Fix for issue #9 - 2
This commit is contained in:
@@ -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
|
||||
|
@@ -32,6 +32,7 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
public interface IServiceHost {
|
||||
|
||||
bool Sweeped { get; set; }
|
||||
void BindWebSocket(WebSocket socket);
|
||||
void Broadcast(string data);
|
||||
void Start();
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user