Fix due to the added ID property to WebSocketService

This commit is contained in:
sta 2012-08-22 14:12:11 +09:00
parent 0bea2dd623
commit 5f4f7485aa
49 changed files with 178 additions and 122 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -27,6 +27,7 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using WebSocketSharp.Frame; using WebSocketSharp.Frame;
namespace WebSocketSharp.Server namespace WebSocketSharp.Server
@ -35,13 +36,14 @@ namespace WebSocketSharp.Server
{ {
WsServerState State { get; } WsServerState State { get; }
void AddService(WebSocketService service); void AddService(string id, WebSocketService service);
void CloseServices(CloseStatusCode code, string reason); Dictionary<string, bool> PingAround(string data);
void Ping(string data); void Publish<TData>(TData data);
void Publish(byte[] data); void RemoveService(string id);
void Publish(string data); void SendTo<TData>(string id, TData data);
void RemoveService(WebSocketService service); void SendTo<TData>(IEnumerable<string> group, TData data);
void Start(); void Start();
void Stop(); void Stop();
void StopServices(CloseStatusCode code, string reason);
} }
} }

View File

@ -29,6 +29,7 @@
#endregion #endregion
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
@ -44,10 +45,11 @@ namespace WebSocketSharp.Server
{ {
#region Private Fields #region Private Fields
private SynchronizedCollection<WebSocketService> _services; private object _forServices;
private WsServerState _state; private Dictionary<string, WebSocketService> _services;
private TcpListener _tcpListener; private WsServerState _state;
private Uri _uri; private TcpListener _tcpListener;
private Uri _uri;
#endregion #endregion
@ -91,9 +93,11 @@ namespace WebSocketSharp.Server
public WebSocketServer(string url) public WebSocketServer(string url)
{ {
_uri = new Uri(url); _uri = new Uri(url);
if (!isValidScheme(_uri)) if (!isValidScheme(_uri))
{ {
throw new ArgumentException("Unsupported WebSocket URI scheme: " + _uri.Scheme); var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
throw new ArgumentException(msg);
} }
string scheme = _uri.Scheme; string scheme = _uri.Scheme;
@ -112,7 +116,8 @@ namespace WebSocketSharp.Server
} }
_tcpListener = new TcpListener(IPAddress.Any, port); _tcpListener = new TcpListener(IPAddress.Any, port);
_services = new SynchronizedCollection<WebSocketService>(); _forServices = new object();
_services = new Dictionary<string, WebSocketService>();
_state = WsServerState.READY; _state = WsServerState.READY;
} }
@ -132,10 +137,10 @@ namespace WebSocketSharp.Server
try try
{ {
TcpClient client = listener.EndAcceptTcpClient(ar); TcpClient client = listener.EndAcceptTcpClient(ar);
WebSocket socket = new WebSocket(_uri.ToString(), client); WebSocket socket = new WebSocket(_uri, client);
T service = new T(); T service = new T();
service.Bind(this, socket); service.Bind(this, socket);
service.Open(); service.Start();
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
{ {
@ -175,80 +180,99 @@ namespace WebSocketSharp.Server
#region Public Methods #region Public Methods
public void AddService(WebSocketService service) public void AddService(string id, WebSocketService service)
{ {
_services.Add(service); lock (_forServices)
}
public void CloseServices()
{
CloseServices(CloseStatusCode.NORMAL, String.Empty);
}
public void CloseServices(CloseStatusCode code, string reason)
{
lock (_services.SyncRoot)
{ {
foreach (WebSocketService service in _services) _services.Add(id, service);
}
}
public Dictionary<string, bool> PingAround()
{
return PingAround(String.Empty);
}
public Dictionary<string, bool> PingAround(string data)
{
var result = new Dictionary<string, bool>();
lock (_forServices)
{
foreach (WebSocketService service in _services.Values)
{ {
service.Close(code, reason); result.Add(service.ID, service.Ping(data));
}
}
return result;
}
public void Publish<TData>(TData data)
{
WaitCallback broadcast = (state) =>
{
lock (_forServices)
{
SendTo(_services.Keys, data);
}
};
ThreadPool.QueueUserWorkItem(broadcast);
}
public void RemoveService(string id)
{
lock (_forServices)
{
_services.Remove(id);
}
}
public void SendTo<TData>(string id, TData data)
{
if (typeof(TData) != typeof(string) &&
typeof(TData) != typeof(byte[]))
{
var msg = "Type of data must be string or byte[].";
throw new ArgumentException(msg);
}
lock (_forServices)
{
WebSocketService service;
if (_services.TryGetValue(id, out service))
{
if (typeof(TData) == typeof(string))
{
string data_ = (string)(object)data;
service.Send(data_);
}
else if (typeof(TData) == typeof(byte[]))
{
byte[] data_ = (byte[])(object)data;
service.Send(data_);
}
} }
} }
} }
public void Ping() public void SendTo<TData>(IEnumerable<string> group, TData data)
{ {
Ping(String.Empty); if (typeof(TData) != typeof(string) &&
} typeof(TData) != typeof(byte[]))
public void Ping(string data)
{
WaitCallback broadcast = (state) =>
{ {
lock (_services.SyncRoot) var msg = "Type of data must be string or byte[].";
{ throw new ArgumentException(msg);
foreach (WebSocketService service in _services) }
{
service.Ping(data);
}
}
};
ThreadPool.QueueUserWorkItem(broadcast);
}
public void Publish(byte[] data) lock (_forServices)
{
WaitCallback broadcast = (state) =>
{ {
lock (_services.SyncRoot) foreach (string id in group)
{ {
foreach (WebSocketService service in _services) SendTo(id, data);
{
service.Send(data);
}
} }
}; }
ThreadPool.QueueUserWorkItem(broadcast);
}
public void Publish(string data)
{
WaitCallback broadcast = (state) =>
{
lock (_services.SyncRoot)
{
foreach (WebSocketService service in _services)
{
service.Send(data);
}
}
};
ThreadPool.QueueUserWorkItem(broadcast);
}
public void RemoveService(WebSocketService service)
{
_services.Remove(service);
} }
public void Start() public void Start()
@ -263,11 +287,27 @@ namespace WebSocketSharp.Server
_state = WsServerState.SHUTDOWN; _state = WsServerState.SHUTDOWN;
_tcpListener.Stop(); _tcpListener.Stop();
CloseServices(); StopServices();
_state = WsServerState.STOP; _state = WsServerState.STOP;
} }
public void StopServices()
{
StopServices(CloseStatusCode.NORMAL, String.Empty);
}
public void StopServices(CloseStatusCode code, string reason)
{
lock (_forServices)
{
foreach (WebSocketService service in _services.Values)
{
service.Stop(code, reason);
}
}
}
#endregion #endregion
} }
} }

View File

@ -27,6 +27,7 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using WebSocketSharp.Frame; using WebSocketSharp.Frame;
namespace WebSocketSharp.Server namespace WebSocketSharp.Server
@ -40,9 +41,10 @@ namespace WebSocketSharp.Server
#endregion #endregion
#region Property #region Properties
public bool IsBound { get; private set; } public string ID { get; private set; }
public bool IsBound { get; private set; }
#endregion #endregion
@ -50,6 +52,7 @@ namespace WebSocketSharp.Server
public WebSocketService() public WebSocketService()
{ {
ID = String.Empty;
IsBound = false; IsBound = false;
} }
@ -57,18 +60,24 @@ namespace WebSocketSharp.Server
#region Private Method #region Private Method
private string getNewID()
{
return Guid.NewGuid().ToString("N");
}
private void defaultBind() private void defaultBind()
{ {
_socket.OnOpen += (sender, e) => _socket.OnOpen += (sender, e) =>
{ {
_server.AddService(this); ID = getNewID();
_server.AddService(ID, this);
}; };
_socket.OnClose += (sender, e) => _socket.OnClose += (sender, e) =>
{ {
if (_server.State == WsServerState.START) if (_server.State == WsServerState.START)
{ {
_server.RemoveService(this); _server.RemoveService(ID);
} }
}; };
} }
@ -111,47 +120,30 @@ namespace WebSocketSharp.Server
IsBound = true; IsBound = true;
} }
public void BPing() public Dictionary<string, bool> PingAround()
{ {
BPing(String.Empty); return PingAround(String.Empty);
} }
public void BPing(string data) public Dictionary<string, bool> PingAround(string data)
{ {
if (IsBound) _server.Ping(data); if (IsBound) return _server.PingAround(data);
return null;
} }
public void Close() public bool Ping()
{ {
if (IsBound) _socket.Close(); if (IsBound) return _socket.Ping();
return false;
} }
public void Close(CloseStatusCode code, string reason) public bool Ping(string data)
{ {
if (IsBound) _socket.Close(code, reason); if (IsBound) return _socket.Ping(data);
return false;
} }
public void Open() public void Publish<TData>(TData data)
{
if (IsBound) _socket.Connect();
}
public void Ping()
{
if (IsBound) _socket.Ping();
}
public void Ping(string data)
{
if (IsBound) _socket.Ping(data);
}
public void Publish(byte[] data)
{
if (IsBound) _server.Publish(data);
}
public void Publish(string data)
{ {
if (IsBound) _server.Publish(data); if (IsBound) _server.Publish(data);
} }
@ -166,6 +158,31 @@ namespace WebSocketSharp.Server
if (IsBound) _socket.Send(data); if (IsBound) _socket.Send(data);
} }
public void SendTo<TData>(string id, TData data)
{
if (IsBound) _server.SendTo(id, data);
}
public void SendTo<TData>(IEnumerable<string> group, TData data)
{
if (IsBound) _server.SendTo(group, data);
}
public void Start()
{
if (IsBound) _socket.Connect();
}
public void Stop()
{
if (IsBound) _socket.Close();
}
public void Stop(CloseStatusCode code, string reason)
{
if (IsBound) _socket.Close(code, reason);
}
#endregion #endregion
} }
} }

View File

@ -61,9 +61,9 @@ namespace WebSocketSharp
#region Private Fields #region Private Fields
private AutoResetEvent _autoEvent;
private string _base64key; private string _base64key;
private string _binaryType; private string _binaryType;
private AutoResetEvent _exitedMessageLoop;
private string _extensions; private string _extensions;
private Object _forClose; private Object _forClose;
private Object _forSend; private Object _forSend;
@ -190,15 +190,10 @@ namespace WebSocketSharp
#region Internal Constructors #region Internal Constructors
internal WebSocket(string url, TcpClient tcpClient) internal WebSocket(Uri uri, TcpClient tcpClient)
: this() : this()
{ {
_uri = new Uri(url); _uri = uri;
if (!isValidScheme(_uri))
{
throw new ArgumentException("Unsupported WebSocket URI scheme: " + _uri.Scheme);
}
_tcpClient = tcpClient; _tcpClient = tcpClient;
_isClient = false; _isClient = false;
} }
@ -211,9 +206,11 @@ namespace WebSocketSharp
: this() : this()
{ {
_uri = new Uri(url); _uri = new Uri(url);
if (!isValidScheme(_uri)) if (!isValidScheme(_uri))
{ {
throw new ArgumentException("Unsupported WebSocket URI scheme: " + _uri.Scheme); var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
throw new ArgumentException(msg);
} }
_protocols = protocols.ToString(", "); _protocols = protocols.ToString(", ");
@ -346,11 +343,11 @@ namespace WebSocketSharp
{ {
if (_isClient) if (_isClient)
{ {
_msgThread.Join(5000); _msgThread.Join(5 * 1000);
} }
else else
{ {
_autoEvent.WaitOne(); _exitedMessageLoop.WaitOne(5 * 1000);
} }
} }
@ -788,7 +785,7 @@ namespace WebSocketSharp
} }
else else
{ {
_autoEvent.Set(); _exitedMessageLoop.Set();
} }
} }
@ -1118,7 +1115,7 @@ namespace WebSocketSharp
} }
else else
{ {
_autoEvent = new AutoResetEvent(false); _exitedMessageLoop = new AutoResetEvent(false);
Action messageInvoker = () => Action messageInvoker = () =>
{ {
if (_readyState == WsState.OPEN) if (_readyState == WsState.OPEN)

Binary file not shown.