Fix for issue #9 - 2

This commit is contained in:
sta
2012-10-26 14:58:50 +09:00
parent 2ae1d35d03
commit 746c883b82
71 changed files with 230 additions and 84 deletions

View File

@@ -63,12 +63,22 @@ namespace WebSocketSharp.Server {
#endregion
#region Property
#region Properties
public int Port {
get { return _port; }
}
public bool Sweeped {
get {
return _services.Sweeped;
}
set {
_services.Sweeped = value;
}
}
#endregion
#region Events

View File

@@ -32,6 +32,7 @@ namespace WebSocketSharp.Server {
public interface IServiceHost {
bool Sweeped { get; set; }
void BindWebSocket(WebSocket socket);
void Broadcast(string data);
void Start();

View File

@@ -36,6 +36,7 @@ namespace WebSocketSharp.Server {
#region Field
private Dictionary<string, IServiceHost> _services;
private bool _sweeped;
#endregion
@@ -44,11 +45,12 @@ namespace WebSocketSharp.Server {
public ServiceManager()
{
_services = new Dictionary<string, IServiceHost>();
_sweeped = true;
}
#endregion
#region Property
#region Properties
public int Count {
get {
@@ -56,6 +58,21 @@ namespace WebSocketSharp.Server {
}
}
public bool Sweeped {
get {
return _sweeped;
}
set {
if (value ^ _sweeped)
{
_sweeped = value;
foreach (var svcHost in _services.Values)
svcHost.Sweeped = value;
}
}
}
#endregion
#region Public Methods

View File

@@ -28,6 +28,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
using WebSocketSharp.Frame;
namespace WebSocketSharp.Server {
@@ -36,8 +38,11 @@ namespace WebSocketSharp.Server {
#region Private Fields
private bool _isStopped;
private object _forSweep;
private volatile bool _isStopped;
private volatile bool _isSweeping;
private Dictionary<string, WebSocketService> _sessions;
private Timer _sweepTimer;
private object _syncRoot;
#endregion
@@ -46,15 +51,32 @@ namespace WebSocketSharp.Server {
public SessionManager()
{
_isStopped = false;
_sessions = new Dictionary<string, WebSocketService>();
_syncRoot = new object();
_forSweep = new object();
_isStopped = false;
_isSweeping = false;
_sessions = new Dictionary<string, WebSocketService>();
_sweepTimer = new Timer(30 * 1000);
_sweepTimer.Elapsed += (sender, e) =>
{
Sweep();
};
_syncRoot = new object();
startSweepTimer();
}
#endregion
#region Properties
public IEnumerable<string> ActiveID {
get {
return from result in Broadping(String.Empty)
where result.Value
select result.Key;
}
}
public int Count {
get {
lock (_syncRoot)
@@ -64,6 +86,37 @@ namespace WebSocketSharp.Server {
}
}
public IEnumerable<string> InactiveID {
get {
return from result in Broadping(String.Empty)
where !result.Value
select result.Key;
}
}
public IEnumerable<string> ID {
get {
lock (_syncRoot)
{
return _sessions.Keys;
}
}
}
public bool Sweeped {
get {
return _sweepTimer.Enabled;
}
set {
if (value && !_isStopped)
startSweepTimer();
if (!value)
stopSweepTimer();
}
}
public object SyncRoot {
get {
return _syncRoot;
@@ -82,11 +135,23 @@ namespace WebSocketSharp.Server {
}
}
private string getNewID()
private string createID()
{
return Guid.NewGuid().ToString("N");
}
private void startSweepTimer()
{
if (!Sweeped)
_sweepTimer.Start();
}
private void stopSweepTimer()
{
if (Sweeped)
_sweepTimer.Stop();
}
#endregion
#region Public Methods
@@ -98,7 +163,7 @@ namespace WebSocketSharp.Server {
if (_isStopped)
return null;
var id = getNewID();
var id = createID();
_sessions.Add(id, service);
return id;
@@ -110,7 +175,10 @@ namespace WebSocketSharp.Server {
lock (_syncRoot)
{
foreach (var service in _sessions.Values)
service.SendAsync(data);
if (_isStopped || _isSweeping)
service.Send(data);
else
service.SendAsync(data);
}
}
@@ -119,7 +187,10 @@ namespace WebSocketSharp.Server {
lock (_syncRoot)
{
foreach (var service in _sessions.Values)
service.SendAsync(data);
if (_isStopped || _isSweeping)
service.Send(data);
else
service.SendAsync(data);
}
}
@@ -132,21 +203,10 @@ namespace WebSocketSharp.Server {
return result;
}
public IEnumerable<string> GetIDs()
{
lock (_syncRoot)
{
return _sessions.Keys;
}
}
public bool Remove(string id)
{
lock (_syncRoot)
{
if (_isStopped)
return false;
return _sessions.Remove(id);
}
}
@@ -166,16 +226,43 @@ namespace WebSocketSharp.Server {
public void Stop(CloseStatusCode code, string reason)
{
stopSweepTimer();
lock (_syncRoot)
{
if (_isStopped)
return;
_isStopped = true;
foreach (var service in _sessions.Values)
foreach (var service in copySessions().Values)
service.Stop(code, reason);
}
}
_sessions.Clear();
public void Sweep()
{
if (_isStopped || _isSweeping || Count == 0)
return;
lock (_forSweep)
{
_isSweeping = true;
foreach (var id in InactiveID)
{
lock (_syncRoot)
{
if (_isStopped)
{
_isSweeping = false;
return;
}
WebSocketService service;
if (TryGetByID(id, out service))
service.Stop(CloseStatusCode.ABNORMAL, String.Empty);
}
}
_isSweeping = false;
}
}

View File

@@ -74,6 +74,20 @@ namespace WebSocketSharp.Server {
#endregion
#region Property
public bool Sweeped {
get {
return _services.Sweeped;
}
set {
_services.Sweeped = value;
}
}
#endregion
#region Private Method
private void init()

View File

@@ -47,9 +47,8 @@ namespace WebSocketSharp.Server {
public WebSocketService()
{
ID = String.Empty;
IsBound = false;
IsStopped = false;
ID = String.Empty;
IsBound = false;
}
#endregion
@@ -72,9 +71,8 @@ namespace WebSocketSharp.Server {
#region Public Properties
public string ID { get; private set; }
public bool IsBound { get; private set; }
public bool IsStopped { get; private set; }
public string ID { get; private set; }
public bool IsBound { get; private set; }
#endregion
@@ -89,8 +87,7 @@ namespace WebSocketSharp.Server {
_socket.OnClose += (sender, e) =>
{
if (!IsStopped)
_sessions.Remove(ID);
_sessions.Remove(ID);
};
}
@@ -202,6 +199,7 @@ namespace WebSocketSharp.Server {
{
Send(data);
};
ThreadPool.QueueUserWorkItem(sendCb);
}
@@ -211,6 +209,7 @@ namespace WebSocketSharp.Server {
{
Send(data);
};
ThreadPool.QueueUserWorkItem(sendCb);
}
@@ -242,15 +241,22 @@ namespace WebSocketSharp.Server {
public void Stop()
{
Stop(CloseStatusCode.NORMAL, String.Empty);
if (!IsBound)
return;
_socket.Close();
}
public void Stop(CloseStatusCode code, string reason)
{
if (!IsBound || IsStopped)
Stop((ushort)code, reason);
}
public void Stop(ushort code, string reason)
{
if (!IsBound)
return;
IsStopped = true;
_socket.Close(code, reason);
}

View File

@@ -79,7 +79,17 @@ namespace WebSocketSharp.Server {
#endregion
#region Property
#region Properties
public bool Sweeped {
get {
return _sessions.Sweeped;
}
set {
_sessions.Sweeped = value;
}
}
public Uri Uri {
get {