Fix due to the added SessionManager.cs
This commit is contained in:
@@ -32,8 +32,8 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace WebSocketSharp.Frame
|
||||
{
|
||||
namespace WebSocketSharp.Frame {
|
||||
|
||||
public class WsFrame : IEnumerable<byte>
|
||||
{
|
||||
#region Field
|
||||
@@ -42,37 +42,6 @@ namespace WebSocketSharp.Frame
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public Fin Fin { get; private set; }
|
||||
public Rsv Rsv1 { get; private set; }
|
||||
public Rsv Rsv2 { get; private set; }
|
||||
public Rsv Rsv3 { get; private set; }
|
||||
public Opcode Opcode { get; private set; }
|
||||
public Mask Masked { get; private set; }
|
||||
public byte PayloadLen { get; private set; }
|
||||
public byte[] ExtPayloadLen { get; private set; }
|
||||
public byte[] MaskingKey { get; private set; }
|
||||
public PayloadData PayloadData { get; private set; }
|
||||
|
||||
public ulong Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2 + (ulong)(ExtPayloadLen.Length + MaskingKey.Length) + PayloadLength;
|
||||
}
|
||||
}
|
||||
|
||||
public ulong PayloadLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return PayloadData.Length;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Constructor
|
||||
|
||||
static WsFrame()
|
||||
@@ -120,6 +89,37 @@ namespace WebSocketSharp.Frame
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public Fin Fin { get; private set; }
|
||||
public Rsv Rsv1 { get; private set; }
|
||||
public Rsv Rsv2 { get; private set; }
|
||||
public Rsv Rsv3 { get; private set; }
|
||||
public Opcode Opcode { get; private set; }
|
||||
public Mask Masked { get; private set; }
|
||||
public byte PayloadLen { get; private set; }
|
||||
public byte[] ExtPayloadLen { get; private set; }
|
||||
public byte[] MaskingKey { get; private set; }
|
||||
public PayloadData PayloadData { get; private set; }
|
||||
|
||||
public ulong Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2 + (ulong)(ExtPayloadLen.Length + MaskingKey.Length) + PayloadLength;
|
||||
}
|
||||
}
|
||||
|
||||
public ulong PayloadLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return PayloadData.Length;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// EndPointManager.cs
|
||||
// Copied from System.Net.EndPointManager
|
||||
// Copied from System.Net.EndPointManager.cs
|
||||
//
|
||||
// Author:
|
||||
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
|
||||
|
@@ -39,12 +39,12 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
#region Fields
|
||||
|
||||
private Thread _acceptRequestThread;
|
||||
private bool _isWindows;
|
||||
private HttpListener _listener;
|
||||
private int _port;
|
||||
private string _rootPath;
|
||||
private Dictionary<string, IWebSocketServer> _wsServers;
|
||||
private Thread _acceptRequestThread;
|
||||
private bool _isWindows;
|
||||
private HttpListener _listener;
|
||||
private int _port;
|
||||
private string _rootPath;
|
||||
private Dictionary<string, IServiceHost> _services;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace WebSocketSharp.Server {
|
||||
{
|
||||
_isWindows = false;
|
||||
_listener = new HttpListener();
|
||||
_wsServers = new Dictionary<string, IWebSocketServer>();
|
||||
_services = new Dictionary<string, IServiceHost>();
|
||||
|
||||
var os = Environment.OSVersion;
|
||||
if (os.Platform != PlatformID.Unix && os.Platform != PlatformID.MacOSX)
|
||||
@@ -248,7 +248,7 @@ namespace WebSocketSharp.Server {
|
||||
var res = context.Response;
|
||||
|
||||
var path = req.RawUrl;
|
||||
if (!_wsServers.ContainsKey(path))
|
||||
if (!_services.ContainsKey(path))
|
||||
{
|
||||
res.StatusCode = (int)HttpStatusCode.NotImplemented;
|
||||
return false;
|
||||
@@ -256,8 +256,8 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
var wsContext = context.AcceptWebSocket(path);
|
||||
var socket = wsContext.WebSocket;
|
||||
var wsServer = _wsServers[path];
|
||||
wsServer.BindWebSocket(socket);
|
||||
var service = _services[path];
|
||||
service.BindWebSocket(socket);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -269,8 +269,8 @@ namespace WebSocketSharp.Server {
|
||||
public void AddService<T>(string path)
|
||||
where T : WebSocketService, new()
|
||||
{
|
||||
var server = new WebSocketServer<T>();
|
||||
_wsServers.Add(path, server);
|
||||
var service = new WebSocketServer<T>();
|
||||
_services.Add(path, service);
|
||||
}
|
||||
|
||||
public byte[] GetFile(string path)
|
||||
@@ -295,9 +295,9 @@ namespace WebSocketSharp.Server {
|
||||
{
|
||||
_listener.Close();
|
||||
_acceptRequestThread.Join(5 * 1000);
|
||||
foreach (var server in _wsServers.Values)
|
||||
server.Stop();
|
||||
_wsServers.Clear();
|
||||
foreach (var service in _services.Values)
|
||||
service.Stop();
|
||||
_services.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#region MIT License
|
||||
/**
|
||||
* IWebSocketServer.cs
|
||||
* IServiceHost.cs
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
@@ -30,11 +30,10 @@ using System;
|
||||
|
||||
namespace WebSocketSharp.Server {
|
||||
|
||||
public interface IWebSocketServer {
|
||||
public interface IServiceHost {
|
||||
|
||||
void BindWebSocket(WebSocket socket);
|
||||
void Start();
|
||||
void Stop();
|
||||
void StopServices();
|
||||
}
|
||||
}
|
184
websocket-sharp/Server/SessionManager.cs
Normal file
184
websocket-sharp/Server/SessionManager.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
#region MIT License
|
||||
/**
|
||||
* SessionManager.cs
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012 sta.blockhead
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WebSocketSharp.Frame;
|
||||
|
||||
namespace WebSocketSharp.Server {
|
||||
|
||||
public class SessionManager {
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private bool _isStopped;
|
||||
private Dictionary<string, WebSocketService> _sessions;
|
||||
private object _syncRoot;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Constructor
|
||||
|
||||
public SessionManager()
|
||||
{
|
||||
_isStopped = false;
|
||||
_sessions = new Dictionary<string, WebSocketService>();
|
||||
_syncRoot = new object();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _sessions.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public object SyncRoot {
|
||||
get {
|
||||
return _syncRoot;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Method
|
||||
|
||||
private Dictionary<string, WebSocketService> copySessions()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return new Dictionary<string, WebSocketService>(_sessions);
|
||||
}
|
||||
}
|
||||
|
||||
private string getNewID()
|
||||
{
|
||||
return Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public string Add(WebSocketService service)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_isStopped)
|
||||
return null;
|
||||
|
||||
var id = getNewID();
|
||||
_sessions.Add(id, service);
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public void Broadcast(byte[] data)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
foreach (var service in _sessions.Values)
|
||||
service.SendAsync(data);
|
||||
}
|
||||
}
|
||||
|
||||
public void Broadcast(string data)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
foreach (var service in _sessions.Values)
|
||||
service.SendAsync(data);
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, bool> Broadping(string data)
|
||||
{
|
||||
var result = new Dictionary<string, bool>();
|
||||
foreach (var session in copySessions())
|
||||
result.Add(session.Key, session.Value.Ping(data));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetByID(string id, out WebSocketService service)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _sessions.TryGetValue(id, out service);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Stop(CloseStatusCode.NORMAL, String.Empty);
|
||||
}
|
||||
|
||||
public void Stop(CloseStatusCode code, string reason)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_isStopped)
|
||||
return;
|
||||
|
||||
_isStopped = true;
|
||||
foreach (var service in _sessions.Values)
|
||||
service.Stop(code, reason);
|
||||
|
||||
_sessions.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -29,10 +29,8 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using WebSocketSharp.Frame;
|
||||
using WebSocketSharp.Net;
|
||||
using WebSocketSharp.Net.Sockets;
|
||||
|
||||
@@ -42,7 +40,7 @@ namespace WebSocketSharp.Server {
|
||||
{
|
||||
#region Field
|
||||
|
||||
private Dictionary<string, IWebSocketServer> _servers;
|
||||
private Dictionary<string, IServiceHost> _services;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -56,7 +54,7 @@ namespace WebSocketSharp.Server {
|
||||
public WebSocketServer(int port)
|
||||
: base(System.Net.IPAddress.Any, port)
|
||||
{
|
||||
_servers = new Dictionary<string, IWebSocketServer>();
|
||||
_services = new Dictionary<string, IServiceHost>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -68,14 +66,14 @@ namespace WebSocketSharp.Server {
|
||||
var context = client.AcceptWebSocket();
|
||||
var socket = context.WebSocket;
|
||||
var path = context.RequestUri.ToString();
|
||||
if (!_servers.ContainsKey(path))
|
||||
if (!_services.ContainsKey(path))
|
||||
{
|
||||
socket.Close(HttpStatusCode.NotImplemented);
|
||||
return;
|
||||
}
|
||||
|
||||
var server = _servers[path];
|
||||
server.BindWebSocket(socket);
|
||||
var service = _services[path];
|
||||
service.BindWebSocket(socket);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -85,28 +83,28 @@ namespace WebSocketSharp.Server {
|
||||
public void AddService<T>(string path)
|
||||
where T : WebSocketService, new()
|
||||
{
|
||||
var server = new WebSocketServer<T>();
|
||||
_servers.Add(path, server);
|
||||
var service = new WebSocketServer<T>();
|
||||
_services.Add(path, service);
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
foreach (var server in _servers.Values)
|
||||
server.Stop();
|
||||
_servers.Clear();
|
||||
foreach (var service in _services.Values)
|
||||
service.Stop();
|
||||
_services.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class WebSocketServer<T> : WebSocketServerBase, IWebSocketServer
|
||||
public class WebSocketServer<T> : WebSocketServerBase, IServiceHost
|
||||
where T : WebSocketService, new()
|
||||
{
|
||||
#region Fields
|
||||
|
||||
private Dictionary<string, WebSocketService> _services;
|
||||
private Uri _uri;
|
||||
private SessionManager _sessions;
|
||||
private Uri _uri;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -162,7 +160,7 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
private void init()
|
||||
{
|
||||
_services = new Dictionary<string, WebSocketService>();
|
||||
_sessions = new SessionManager();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -182,29 +180,14 @@ namespace WebSocketSharp.Server {
|
||||
public void BindWebSocket(WebSocket socket)
|
||||
{
|
||||
T service = new T();
|
||||
service.Bind(socket, _services);
|
||||
service.Bind(socket, _sessions);
|
||||
service.Start();
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
StopServices();
|
||||
}
|
||||
|
||||
public void StopServices()
|
||||
{
|
||||
StopServices(CloseStatusCode.NORMAL, String.Empty);
|
||||
}
|
||||
|
||||
public void StopServices(CloseStatusCode code, string reason)
|
||||
{
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
foreach (WebSocketService service in _services.Values)
|
||||
service.Stop(code, reason);
|
||||
_services.Clear();
|
||||
}
|
||||
_sessions.Stop();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using WebSocketSharp.Frame;
|
||||
@@ -38,16 +37,8 @@ namespace WebSocketSharp.Server
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
private Dictionary<string, WebSocketService> _services;
|
||||
private WebSocket _socket;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public string ID { get; private set; }
|
||||
public bool IsBound { get; private set; }
|
||||
public bool IsStop { get; private set; }
|
||||
private SessionManager _sessions;
|
||||
private WebSocket _socket;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -55,53 +46,37 @@ namespace WebSocketSharp.Server
|
||||
|
||||
public WebSocketService()
|
||||
{
|
||||
ID = String.Empty;
|
||||
IsBound = false;
|
||||
IsStop = false;
|
||||
ID = String.Empty;
|
||||
IsBound = false;
|
||||
IsStopped = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public string ID { get; private set; }
|
||||
public bool IsBound { get; private set; }
|
||||
public bool IsStopped { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Method
|
||||
|
||||
private void addService(string id, WebSocketService service)
|
||||
{
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
_services.Add(id, service);
|
||||
}
|
||||
}
|
||||
|
||||
private string getNewID()
|
||||
{
|
||||
return Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
private void defaultBind()
|
||||
{
|
||||
_socket.OnOpen += (sender, e) =>
|
||||
{
|
||||
ID = getNewID();
|
||||
addService(ID, this);
|
||||
ID = _sessions.Add(this);
|
||||
};
|
||||
|
||||
_socket.OnClose += (sender, e) =>
|
||||
{
|
||||
if (!IsStop)
|
||||
{
|
||||
removeService(ID);
|
||||
}
|
||||
if (!IsStopped)
|
||||
_sessions.Remove(ID);
|
||||
};
|
||||
}
|
||||
|
||||
private void removeService(string id)
|
||||
{
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
_services.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
@@ -126,10 +101,10 @@ namespace WebSocketSharp.Server
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public void Bind(WebSocket socket, Dictionary<string, WebSocketService> services)
|
||||
public void Bind(WebSocket socket, SessionManager sessions)
|
||||
{
|
||||
_socket = socket;
|
||||
_services = services;
|
||||
_sessions = sessions;
|
||||
|
||||
defaultBind();
|
||||
_socket.OnOpen += onOpen;
|
||||
@@ -159,12 +134,9 @@ namespace WebSocketSharp.Server
|
||||
|
||||
public Dictionary<string, bool> PingAround(string data)
|
||||
{
|
||||
if (!IsBound) return null;
|
||||
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
return PingTo(_services.Keys, data);
|
||||
}
|
||||
return IsBound
|
||||
? _sessions.Broadping(data)
|
||||
: null;
|
||||
}
|
||||
|
||||
public bool PingTo(string id)
|
||||
@@ -172,120 +144,83 @@ namespace WebSocketSharp.Server
|
||||
return PingTo(id, String.Empty);
|
||||
}
|
||||
|
||||
public Dictionary<string, bool> PingTo(IEnumerable<string> group)
|
||||
{
|
||||
return PingTo(group, String.Empty);
|
||||
}
|
||||
|
||||
public bool PingTo(string id, string data)
|
||||
{
|
||||
if (!IsBound) return false;
|
||||
if (!IsBound)
|
||||
return false;
|
||||
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
WebSocketService service;
|
||||
|
||||
return _services.TryGetValue(id, out service)
|
||||
? service.Ping(data)
|
||||
: false;
|
||||
}
|
||||
WebSocketService service;
|
||||
return _sessions.TryGetByID(id, out service)
|
||||
? service.Ping(data)
|
||||
: false;
|
||||
}
|
||||
|
||||
public Dictionary<string, bool> PingTo(IEnumerable<string> group, string data)
|
||||
public void Publish(byte[] data)
|
||||
{
|
||||
if (!IsBound) return null;
|
||||
|
||||
var result = new Dictionary<string, bool>();
|
||||
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
foreach (string id in group)
|
||||
{
|
||||
result.Add(id, PingTo(id, data));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
if (IsBound)
|
||||
_sessions.Broadcast(data);
|
||||
}
|
||||
|
||||
public void Publish<TData>(TData data)
|
||||
public void Publish(string data)
|
||||
{
|
||||
if (!IsBound) return;
|
||||
|
||||
WaitCallback broadcast = (state) =>
|
||||
{
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
SendTo(_services.Keys, data);
|
||||
}
|
||||
};
|
||||
ThreadPool.QueueUserWorkItem(broadcast);
|
||||
if (IsBound)
|
||||
_sessions.Broadcast(data);
|
||||
}
|
||||
|
||||
public void Send(byte[] data)
|
||||
{
|
||||
if (IsBound) _socket.Send(data);
|
||||
if (IsBound)
|
||||
_socket.Send(data);
|
||||
}
|
||||
|
||||
public void Send(string data)
|
||||
{
|
||||
if (IsBound) _socket.Send(data);
|
||||
if (IsBound)
|
||||
_socket.Send(data);
|
||||
}
|
||||
|
||||
public void SendTo<TData>(string id, TData data)
|
||||
public void SendAsync(byte[] data)
|
||||
{
|
||||
if (!IsBound) return;
|
||||
|
||||
if (typeof(TData) != typeof(string) &&
|
||||
typeof(TData) != typeof(byte[]))
|
||||
WaitCallback sendCb = (state) =>
|
||||
{
|
||||
var msg = "Type of data must be string or byte[].";
|
||||
throw new ArgumentException(msg);
|
||||
}
|
||||
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
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_);
|
||||
}
|
||||
}
|
||||
}
|
||||
Send(data);
|
||||
};
|
||||
ThreadPool.QueueUserWorkItem(sendCb);
|
||||
}
|
||||
|
||||
public void SendTo<TData>(IEnumerable<string> group, TData data)
|
||||
public void SendAsync(string data)
|
||||
{
|
||||
if (!IsBound) return;
|
||||
|
||||
if (typeof(TData) != typeof(string) &&
|
||||
typeof(TData) != typeof(byte[]))
|
||||
WaitCallback sendCb = (state) =>
|
||||
{
|
||||
var msg = "Type of data must be string or byte[].";
|
||||
throw new ArgumentException(msg);
|
||||
}
|
||||
Send(data);
|
||||
};
|
||||
ThreadPool.QueueUserWorkItem(sendCb);
|
||||
}
|
||||
|
||||
lock (((ICollection)_services).SyncRoot)
|
||||
{
|
||||
foreach (string id in group)
|
||||
{
|
||||
SendTo(id, data);
|
||||
}
|
||||
}
|
||||
public void SendTo(string id, byte[] data)
|
||||
{
|
||||
if (!IsBound)
|
||||
return;
|
||||
|
||||
WebSocketService service;
|
||||
if (_sessions.TryGetByID(id, out service))
|
||||
service.Send(data);
|
||||
}
|
||||
|
||||
public void SendTo(string id, string data)
|
||||
{
|
||||
if (!IsBound)
|
||||
return;
|
||||
|
||||
WebSocketService service;
|
||||
if (_sessions.TryGetByID(id, out service))
|
||||
service.Send(data);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (IsBound) _socket.Connect();
|
||||
if (IsBound)
|
||||
_socket.Connect();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
@@ -295,9 +230,10 @@ namespace WebSocketSharp.Server
|
||||
|
||||
public void Stop(CloseStatusCode code, string reason)
|
||||
{
|
||||
if (!IsBound || IsStop) return;
|
||||
if (!IsBound || IsStopped)
|
||||
return;
|
||||
|
||||
IsStop = true;
|
||||
IsStopped = true;
|
||||
_socket.Close(code, reason);
|
||||
}
|
||||
|
||||
|
@@ -32,11 +32,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -588,12 +586,9 @@ namespace WebSocketSharp {
|
||||
{
|
||||
try
|
||||
{
|
||||
MessageEventArgs eventArgs = receive();
|
||||
|
||||
var eventArgs = receive();
|
||||
if (eventArgs != null)
|
||||
{
|
||||
OnMessage.Emit(this, eventArgs);
|
||||
}
|
||||
}
|
||||
catch (WsReceivedTooBigMessageException ex)
|
||||
{
|
||||
@@ -609,7 +604,6 @@ namespace WebSocketSharp {
|
||||
{
|
||||
Action messageInvoker = (Action)ar.AsyncState;
|
||||
messageInvoker.EndInvoke(ar);
|
||||
|
||||
if (_readyState == WsState.OPEN)
|
||||
{
|
||||
messageInvoker.BeginInvoke(messageLoopCallback, messageInvoker);
|
||||
@@ -619,6 +613,22 @@ namespace WebSocketSharp {
|
||||
_exitMessageLoop.Set();
|
||||
}
|
||||
|
||||
private bool ping(string data, int millisecondsTimeout)
|
||||
{
|
||||
var buffer = Encoding.UTF8.GetBytes(data);
|
||||
if (buffer.Length > 125)
|
||||
{
|
||||
var msg = "Ping frame must have a payload length of 125 bytes or less.";
|
||||
error(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!send(Fin.FINAL, Opcode.PING, buffer))
|
||||
return false;
|
||||
|
||||
return _receivePong.WaitOne(millisecondsTimeout);
|
||||
}
|
||||
|
||||
private void pong(PayloadData data)
|
||||
{
|
||||
var frame = createFrame(Fin.FINAL, Opcode.PONG, data);
|
||||
@@ -643,12 +653,11 @@ namespace WebSocketSharp {
|
||||
return frame;
|
||||
}
|
||||
|
||||
private WsFrame readFrameWithTimeout()
|
||||
private WsFrame readFrameWithTimeout(int millisecondsTimeout)
|
||||
{
|
||||
if (!_wsStream.DataAvailable)
|
||||
{
|
||||
var timeout = 1 * 100;
|
||||
Thread.Sleep(timeout);
|
||||
Thread.Sleep(millisecondsTimeout);
|
||||
if (!_wsStream.DataAvailable)
|
||||
return null;
|
||||
}
|
||||
@@ -663,7 +672,7 @@ namespace WebSocketSharp {
|
||||
|
||||
private MessageEventArgs receive()
|
||||
{
|
||||
var frame = _isClient ? readFrame() : readFrameWithTimeout();
|
||||
var frame = _isClient ? readFrame() : readFrameWithTimeout(1 * 100);
|
||||
if (frame == null)
|
||||
return null;
|
||||
|
||||
@@ -939,7 +948,6 @@ namespace WebSocketSharp {
|
||||
private void startMessageThread()
|
||||
{
|
||||
_exitMessageLoop = new AutoResetEvent(false);
|
||||
|
||||
Action messageInvoker = () =>
|
||||
{
|
||||
if (_readyState == WsState.OPEN)
|
||||
@@ -1022,18 +1030,7 @@ namespace WebSocketSharp {
|
||||
|
||||
public bool Ping(string data)
|
||||
{
|
||||
var buffer = Encoding.UTF8.GetBytes(data);
|
||||
if (buffer.Length > 125)
|
||||
{
|
||||
var msg = "Ping frame must have a payload length of 125 bytes or less.";
|
||||
error(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!send(Fin.FINAL, Opcode.PING, buffer))
|
||||
return false;
|
||||
|
||||
return _receivePong.WaitOne(5 * 1000);
|
||||
return ping(data, 5 * 1000);
|
||||
}
|
||||
|
||||
public void Send(string data)
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -107,10 +107,11 @@
|
||||
<Compile Include="Server\ResponseEventArgs.cs" />
|
||||
<Compile Include="Net\HttpVersion.cs" />
|
||||
<Compile Include="Net\HttpStatusCode.cs" />
|
||||
<Compile Include="Server\IWebSocketServer.cs" />
|
||||
<Compile Include="Net\Sockets\TcpListenerWebSocketContext.cs" />
|
||||
<Compile Include="Server\WebSocketServerBase.cs" />
|
||||
<Compile Include="Net\Security\SslStream.cs" />
|
||||
<Compile Include="Server\IServiceHost.cs" />
|
||||
<Compile Include="Server\SessionManager.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
Binary file not shown.
Reference in New Issue
Block a user