Renamed SessionManager.cs to WebSocketServiceManager.cs
This commit is contained in:
@@ -38,23 +38,23 @@ namespace WebSocketSharp.Server {
|
||||
public interface IServiceHost {
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the WebSocket service host cleans up the inactive service client.
|
||||
/// Gets or sets a value indicating whether the WebSocket service host cleans up the inactive service clients periodically.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the WebSocket service host cleans up the inactive service client; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the WebSocket service host cleans up the inactive service clients periodically; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool Sweeped { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Binds the specified <see cref="WebSocket"/> instance to the WebSocket service.
|
||||
/// Binds the specified <see cref="WebSocket"/> to the WebSocket service instance.
|
||||
/// </summary>
|
||||
/// <param name="socket">
|
||||
/// An <see cref="WebSocketSharp.WebSocket"/> to bind.
|
||||
/// A <see cref="WebSocketSharp.WebSocket"/> to bind.
|
||||
/// </param>
|
||||
void BindWebSocket(WebSocket socket);
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts the specified <see cref="string"/>.
|
||||
/// Broadcasts the specified <see cref="string"/> to all service clients.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="string"/> to broadcast.
|
||||
|
@@ -1,312 +0,0 @@
|
||||
#region MIT License
|
||||
/*
|
||||
* SessionManager.cs
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012-2013 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 System.Linq;
|
||||
using System.Timers;
|
||||
|
||||
namespace WebSocketSharp.Server {
|
||||
|
||||
public class SessionManager {
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private object _forSweep;
|
||||
private volatile bool _isStopped;
|
||||
private volatile bool _isSweeping;
|
||||
private Dictionary<string, WebSocketService> _sessions;
|
||||
private Timer _sweepTimer;
|
||||
private object _syncRoot;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Constructor
|
||||
|
||||
public SessionManager()
|
||||
{
|
||||
_forSweep = new object();
|
||||
_isStopped = false;
|
||||
_isSweeping = false;
|
||||
_sessions = new Dictionary<string, WebSocketService>();
|
||||
_sweepTimer = new Timer(60 * 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)
|
||||
{
|
||||
return _sessions.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void broadcast(byte[] data)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
foreach (var service in _sessions.Values)
|
||||
service.Send(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(string data)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
foreach (var service in _sessions.Values)
|
||||
service.Send(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastAsync(byte[] data)
|
||||
{
|
||||
var sessions = copySessions();
|
||||
var services = sessions.Values.GetEnumerator();
|
||||
|
||||
Action completed = null;
|
||||
completed = () =>
|
||||
{
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
};
|
||||
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
}
|
||||
|
||||
private void broadcastAsync(string data)
|
||||
{
|
||||
var sessions = copySessions();
|
||||
var services = sessions.Values.GetEnumerator();
|
||||
|
||||
Action completed = null;
|
||||
completed = () =>
|
||||
{
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
};
|
||||
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
}
|
||||
|
||||
private Dictionary<string, WebSocketService> copySessions()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return new Dictionary<string, WebSocketService>(_sessions);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
public string Add(WebSocketService service)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_isStopped)
|
||||
return null;
|
||||
|
||||
var id = createID();
|
||||
_sessions.Add(id, service);
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public void Broadcast(byte[] data)
|
||||
{
|
||||
if (_isStopped)
|
||||
broadcast(data);
|
||||
else
|
||||
broadcastAsync(data);
|
||||
}
|
||||
|
||||
public void Broadcast(string data)
|
||||
{
|
||||
if (_isStopped)
|
||||
broadcast(data);
|
||||
else
|
||||
broadcastAsync(data);
|
||||
}
|
||||
|
||||
public Dictionary<string, bool> Broadping(string message)
|
||||
{
|
||||
var result = new Dictionary<string, bool>();
|
||||
foreach (var session in copySessions())
|
||||
result.Add(session.Key, session.Value.Ping(message));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool Remove(string id)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
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)
|
||||
{
|
||||
stopSweepTimer();
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_isStopped)
|
||||
return;
|
||||
|
||||
_isStopped = true;
|
||||
foreach (var service in copySessions().Values)
|
||||
service.Stop(code, reason);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -111,7 +111,7 @@ namespace WebSocketSharp.Server {
|
||||
/// on the specified <paramref name="address"/> and <paramref name="port"/>.
|
||||
/// </summary>
|
||||
/// <param name="address">
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains an IP address.
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains a local IP address.
|
||||
/// </param>
|
||||
/// <param name="port">
|
||||
/// An <see cref="int"/> that contains a port number.
|
||||
@@ -126,7 +126,7 @@ namespace WebSocketSharp.Server {
|
||||
/// on the specified <paramref name="address"/>, <paramref name="port"/> and <paramref name="secure"/>.
|
||||
/// </summary>
|
||||
/// <param name="address">
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains an IP address.
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains a local IP address.
|
||||
/// </param>
|
||||
/// <param name="port">
|
||||
/// An <see cref="int"/> that contains a port number.
|
||||
@@ -145,10 +145,10 @@ namespace WebSocketSharp.Server {
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the paths associated with the each WebSocket services.
|
||||
/// Gets the collection of paths associated with the every WebSocket services that the server provides.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// An IEnumerable<string> that contains the paths.
|
||||
/// An IEnumerable<string> that contains the collection of paths.
|
||||
/// </value>
|
||||
public IEnumerable<string> ServicePaths {
|
||||
get {
|
||||
@@ -161,10 +161,10 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the server cleans up the inactive client.
|
||||
/// Gets or sets a value indicating whether the server cleans up the inactive clients periodically.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the server cleans up the inactive client; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the server cleans up the inactive clients every 60 seconds; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool Sweeped {
|
||||
get {
|
||||
@@ -193,7 +193,7 @@ namespace WebSocketSharp.Server {
|
||||
/// Accepts a WebSocket connection.
|
||||
/// </summary>
|
||||
/// <param name="context">
|
||||
/// A <see cref="TcpListenerWebSocketContext"/> that contains a WebSocket connection.
|
||||
/// A <see cref="TcpListenerWebSocketContext"/> that contains the WebSocket connection request objects.
|
||||
/// </param>
|
||||
protected override void AcceptWebSocket(TcpListenerWebSocketContext context)
|
||||
{
|
||||
@@ -221,10 +221,10 @@ namespace WebSocketSharp.Server {
|
||||
/// Adds a WebSocket service.
|
||||
/// </summary>
|
||||
/// <param name="absPath">
|
||||
/// A <see cref="string"/> that contains an absolute path associated with a WebSocket service.
|
||||
/// A <see cref="string"/> that contains an absolute path associated with the WebSocket service.
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
/// The type of a WebSocket service. The T must inherit the <see cref="WebSocketService"/> class.
|
||||
/// The type of the WebSocket service. The T must inherit the <see cref="WebSocketService"/> class.
|
||||
/// </typeparam>
|
||||
public void AddService<T>(string absPath)
|
||||
where T : WebSocketService, new()
|
||||
|
@@ -96,7 +96,7 @@ namespace WebSocketSharp.Server {
|
||||
/// on the specified <paramref name="address"/>, <paramref name="port"/>, <paramref name="absPath"/> and <paramref name="secure"/>.
|
||||
/// </summary>
|
||||
/// <param name="address">
|
||||
/// A <see cref="IPAddress"/> that contains an IP address.
|
||||
/// A <see cref="IPAddress"/> that contains a local IP address.
|
||||
/// </param>
|
||||
/// <param name="port">
|
||||
/// An <see cref="int"/> that contains a port number.
|
||||
@@ -177,10 +177,10 @@ namespace WebSocketSharp.Server {
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the IP address on which to listen for incoming connection attempts.
|
||||
/// Gets the local IP address on which to listen for incoming connection attempts.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="IPAddress"/> that contains an IP address.
|
||||
/// A <see cref="IPAddress"/> that contains a local IP address.
|
||||
/// </value>
|
||||
public IPAddress Address {
|
||||
get {
|
||||
@@ -189,10 +189,10 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this server provides secure connection.
|
||||
/// Gets a value indicating whether the server provides secure connection.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this server provides secure connection; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the server provides secure connection; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsSecure {
|
||||
get {
|
||||
@@ -201,10 +201,10 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this server is self host.
|
||||
/// Gets a value indicating whether the server is self host.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this server is self host; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the server is self host; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsSelfHost {
|
||||
get {
|
||||
@@ -339,7 +339,7 @@ namespace WebSocketSharp.Server {
|
||||
/// Accepts a WebSocket connection.
|
||||
/// </summary>
|
||||
/// <param name="context">
|
||||
/// A <see cref="TcpListenerWebSocketContext"/> that contains a WebSocket connection.
|
||||
/// A <see cref="TcpListenerWebSocketContext"/> that contains the WebSocket connection request objects.
|
||||
/// </param>
|
||||
protected abstract void AcceptWebSocket(TcpListenerWebSocketContext context);
|
||||
|
||||
|
@@ -43,8 +43,8 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private SessionManager _sessions;
|
||||
private WebSocket _socket;
|
||||
private WebSocketServiceManager _sessions;
|
||||
private WebSocket _socket;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -79,9 +79,9 @@ namespace WebSocketSharp.Server {
|
||||
/// Gets the sessions to the WebSocket service.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="SessionManager"/> that contains the sessions to the WebSocket service.
|
||||
/// A <see cref="WebSocketServiceManager"/> that contains the sessions to the WebSocket service.
|
||||
/// </value>
|
||||
protected SessionManager Sessions {
|
||||
protected WebSocketServiceManager Sessions {
|
||||
get {
|
||||
return IsBound ? _sessions : null;
|
||||
}
|
||||
@@ -92,18 +92,18 @@ namespace WebSocketSharp.Server {
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of a <see cref="WebSocketService"/> instance.
|
||||
/// Gets the ID of the <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string"/> that contains a ID.
|
||||
/// A <see cref="string"/> that contains an ID.
|
||||
/// </value>
|
||||
public string ID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether a <see cref="WebSocketService"/> instance is bound to a <see cref="WebSocket"/>.
|
||||
/// Gets a value indicating whether the <see cref="WebSocketService"/> instance is bound to a <see cref="WebSocket"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the WebSocketService is bound to a WebSocket; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the <see cref="WebSocketService"/> instance is bound to a <see cref="WebSocket"/>; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsBound { get; private set; }
|
||||
|
||||
@@ -137,6 +137,22 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
internal void Bind(WebSocket socket, WebSocketServiceManager sessions)
|
||||
{
|
||||
if (IsBound)
|
||||
return;
|
||||
|
||||
_socket = socket;
|
||||
_sessions = sessions;
|
||||
|
||||
_socket.OnOpen += onOpen;
|
||||
_socket.OnMessage += onMessage;
|
||||
_socket.OnError += onError;
|
||||
_socket.OnClose += onClose;
|
||||
|
||||
IsBound = true;
|
||||
}
|
||||
|
||||
internal void SendAsync(byte[] data, Action completed)
|
||||
{
|
||||
_socket.SendAsync(data, completed);
|
||||
@@ -152,7 +168,7 @@ namespace WebSocketSharp.Server {
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a inner <see cref="WebSocket"/> receives a Close frame or the Stop method is called.
|
||||
/// Occurs when the inner <see cref="WebSocket"/> receives a Close frame or the Stop method is called.
|
||||
/// </summary>
|
||||
/// <param name="e">
|
||||
/// A <see cref="CloseEventArgs"/> that contains the event data associated with a <see cref="WebSocket.OnClose"/> event.
|
||||
@@ -162,7 +178,7 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a inner <see cref="WebSocket"/> gets an error.
|
||||
/// Occurs when the inner <see cref="WebSocket"/> gets an error.
|
||||
/// </summary>
|
||||
/// <param name="e">
|
||||
/// An <see cref="ErrorEventArgs"/> that contains the event data associated with a <see cref="WebSocket.OnError"/> event.
|
||||
@@ -172,7 +188,7 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a inner <see cref="WebSocket"/> receives a data frame.
|
||||
/// Occurs when the inner <see cref="WebSocket"/> receives a data frame.
|
||||
/// </summary>
|
||||
/// <param name="e">
|
||||
/// A <see cref="MessageEventArgs"/> that contains the event data associated with a <see cref="WebSocket.OnMessage"/> event.
|
||||
@@ -193,33 +209,8 @@ namespace WebSocketSharp.Server {
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Binds the specified <see cref="WebSocket"/> and <see cref="SessionManager"/>
|
||||
/// to a <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="socket">
|
||||
/// A <see cref="WebSocket"/> to bind to the WebSocketService.
|
||||
/// </param>
|
||||
/// <param name="sessions">
|
||||
/// A <see cref="SessionManager"/> to bind to the WebSocketService.
|
||||
/// </param>
|
||||
public void Bind(WebSocket socket, SessionManager sessions)
|
||||
{
|
||||
if (IsBound)
|
||||
return;
|
||||
|
||||
_socket = socket;
|
||||
_sessions = sessions;
|
||||
|
||||
_socket.OnOpen += onOpen;
|
||||
_socket.OnMessage += onMessage;
|
||||
_socket.OnError += onError;
|
||||
_socket.OnClose += onClose;
|
||||
|
||||
IsBound = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts the specified array of <see cref="byte"/> to all clients of the WebSocket service.
|
||||
/// Broadcasts the specified array of <see cref="byte"/> to the clients of every <see cref="WebSocketService"/> instances
|
||||
/// in the <see cref="WebSocketService.Sessions"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// An array of <see cref="byte"/> to broadcast.
|
||||
@@ -231,7 +222,8 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts the specified <see cref="string"/> to all clients of the WebSocket service.
|
||||
/// Broadcasts the specified <see cref="string"/> to the clients of every <see cref="WebSocketService"/> instances
|
||||
/// in the <see cref="WebSocketService.Sessions"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="string"/> to broadcast.
|
||||
@@ -243,11 +235,12 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings to all clients of the WebSocket service.
|
||||
/// Pings to the clients of every <see cref="WebSocketService"/> instances
|
||||
/// in the <see cref="WebSocketService.Sessions"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A Dictionary<string, bool> that contains the collection of the ID and value
|
||||
/// indicating whether the WebSocket service received a Pong in a time.
|
||||
/// A Dictionary<string, bool> that contains the collection of IDs and values
|
||||
/// indicating whether each <see cref="WebSocketService"/> instances received a Pong in a time.
|
||||
/// </returns>
|
||||
public Dictionary<string, bool> Broadping()
|
||||
{
|
||||
@@ -255,11 +248,12 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings with the specified <see cref="string"/> to all clients of the WebSocket service.
|
||||
/// Pings with the specified <see cref="string"/> to the clients of every <see cref="WebSocketService"/> instances
|
||||
/// in the <see cref="WebSocketService.Sessions"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A Dictionary<string, bool> that contains the collection of the ID and value
|
||||
/// indicating whether the WebSocket service received a Pong in a time.
|
||||
/// A Dictionary<string, bool> that contains the collection of IDs and values
|
||||
/// indicating whether each <see cref="WebSocketService"/> instances received a Pong in a time.
|
||||
/// </returns>
|
||||
/// <param name="message">
|
||||
/// A <see cref="string"/> that contains a message.
|
||||
@@ -272,10 +266,10 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings to the client of a <see cref="WebSocketService"/> instance.
|
||||
/// Pings to the client of the <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the WebSocketService receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the <see cref="WebSocketService"/> instance receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Ping()
|
||||
{
|
||||
@@ -283,10 +277,10 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings with the specified <see cref="string"/> to the client of a <see cref="WebSocketService"/> instance.
|
||||
/// Pings with the specified <see cref="string"/> to the client of the <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the WebSocketService receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the <see cref="WebSocketService"/> instance receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <param name="message">
|
||||
/// A <see cref="string"/> that contains a message.
|
||||
@@ -299,13 +293,14 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings to the client of a <see cref="WebSocketService"/> instance associated with the specified ID.
|
||||
/// Pings to the client of the <see cref="WebSocketService"/> instance
|
||||
/// associated with the specified <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the WebSocket service receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the <see cref="WebSocketService"/> instance receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <param name="id">
|
||||
/// A <see cref="string"/> that contains a ID that represents the destination for the Ping.
|
||||
/// A <see cref="string"/> that contains an ID that represents the destination for the Ping.
|
||||
/// </param>
|
||||
public bool PingTo(string id)
|
||||
{
|
||||
@@ -313,14 +308,14 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings with the specified <see cref="string"/> to the client of a <see cref="WebSocketService"/> instance
|
||||
/// associated with the specified ID.
|
||||
/// Pings with the specified <see cref="string"/> to the client of the <see cref="WebSocketService"/> instance
|
||||
/// associated with the specified <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the WebSocketService receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the <see cref="WebSocketService"/> instance receives a Pong in a time; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <param name="id">
|
||||
/// A <see cref="string"/> that contains a ID that represents the destination for the Ping.
|
||||
/// A <see cref="string"/> that contains an ID that represents the destination for the Ping.
|
||||
/// </param>
|
||||
/// <param name="message">
|
||||
/// A <see cref="string"/> that contains a message.
|
||||
@@ -331,13 +326,13 @@ namespace WebSocketSharp.Server {
|
||||
return false;
|
||||
|
||||
WebSocketService service;
|
||||
return _sessions.TryGetByID(id, out service)
|
||||
return _sessions.TryGetWebSocketService(id, out service)
|
||||
? service.Ping(message)
|
||||
: false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a binary data to the client of a <see cref="WebSocketService"/> instance.
|
||||
/// Sends a binary data to the client of the <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// An array of <see cref="byte"/> that contains a binary data to send.
|
||||
@@ -349,7 +344,7 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a text data to the client of a <see cref="WebSocketService"/> instance.
|
||||
/// Sends a text data to the client of the <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="string"/> that contains a text data to send.
|
||||
@@ -361,10 +356,11 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a binary data to the client of a <see cref="WebSocketService"/> instance associated with the specified ID.
|
||||
/// Sends a binary data to the client of the <see cref="WebSocketService"/> instance
|
||||
/// associated with the specified <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="string"/> that contains a ID that represents the destination for the data.
|
||||
/// A <see cref="string"/> that contains an ID that represents the destination for the data.
|
||||
/// </param>
|
||||
/// <param name="data">
|
||||
/// An array of <see cref="byte"/> that contains a binary data to send.
|
||||
@@ -375,15 +371,16 @@ namespace WebSocketSharp.Server {
|
||||
return;
|
||||
|
||||
WebSocketService service;
|
||||
if (_sessions.TryGetByID(id, out service))
|
||||
if (_sessions.TryGetWebSocketService(id, out service))
|
||||
service.Send(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a text data to the client of a <see cref="WebSocketService"/> instance associated with the specified ID.
|
||||
/// Sends a text data to the client of the <see cref="WebSocketService"/> instance
|
||||
/// associated with the specified <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <param name="id">
|
||||
/// A <see cref="string"/> that contains a ID that represents the destination for the data.
|
||||
/// A <see cref="string"/> that contains an ID that represents the destination for the data.
|
||||
/// </param>
|
||||
/// <param name="data">
|
||||
/// A <see cref="string"/> that contains a text data to send.
|
||||
@@ -394,12 +391,12 @@ namespace WebSocketSharp.Server {
|
||||
return;
|
||||
|
||||
WebSocketService service;
|
||||
if (_sessions.TryGetByID(id, out service))
|
||||
if (_sessions.TryGetWebSocketService(id, out service))
|
||||
service.Send(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a <see cref="WebSocketService"/> instance.
|
||||
/// Starts the <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
@@ -408,7 +405,7 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a <see cref="WebSocketService"/> instance.
|
||||
/// Stops the <see cref="WebSocketService"/> instance.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
@@ -419,21 +416,7 @@ namespace WebSocketSharp.Server {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a <see cref="WebSocketService"/> instance with the specified <see cref="CloseStatusCode"/> and <see cref="string"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">
|
||||
/// One of the <see cref="CloseStatusCode"/> values that contains a status code indicating the reason for stop.
|
||||
/// </param>
|
||||
/// <param name="reason">
|
||||
/// A <see cref="string"/> that contains a reason for stop.
|
||||
/// </param>
|
||||
public void Stop(CloseStatusCode code, string reason)
|
||||
{
|
||||
Stop((ushort)code, reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a <see cref="WebSocketService"/> instance with the specified <see cref="ushort"/> and <see cref="string"/>.
|
||||
/// Stops the <see cref="WebSocketService"/> instance with the specified <see cref="ushort"/> and <see cref="string"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">
|
||||
/// A <see cref="ushort"/> that contains a status code indicating the reason for stop.
|
||||
@@ -449,6 +432,20 @@ namespace WebSocketSharp.Server {
|
||||
_socket.Close(code, reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the <see cref="WebSocketService"/> instance with the specified <see cref="CloseStatusCode"/> and <see cref="string"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">
|
||||
/// One of the <see cref="CloseStatusCode"/> values that contains a status code indicating the reason for stop.
|
||||
/// </param>
|
||||
/// <param name="reason">
|
||||
/// A <see cref="string"/> that contains a reason for stop.
|
||||
/// </param>
|
||||
public void Stop(CloseStatusCode code, string reason)
|
||||
{
|
||||
Stop((ushort)code, reason);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -50,7 +50,7 @@ namespace WebSocketSharp.Server {
|
||||
{
|
||||
#region Field
|
||||
|
||||
private SessionManager _sessions;
|
||||
private WebSocketServiceManager _sessions;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace WebSocketSharp.Server {
|
||||
/// on the specified <paramref name="address"/>, <paramref name="port"/> and <paramref name="absPath"/>.
|
||||
/// </summary>
|
||||
/// <param name="address">
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains an IP address.
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains a local IP address.
|
||||
/// </param>
|
||||
/// <param name="port">
|
||||
/// An <see cref="int"/> that contains a port number.
|
||||
@@ -161,7 +161,7 @@ namespace WebSocketSharp.Server {
|
||||
/// on the specified <paramref name="address"/>, <paramref name="port"/>, <paramref name="absPath"/> and <paramref name="secure"/>.
|
||||
/// </summary>
|
||||
/// <param name="address">
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains an IP address.
|
||||
/// A <see cref="System.Net.IPAddress"/> that contains a local IP address.
|
||||
/// </param>
|
||||
/// <param name="port">
|
||||
/// An <see cref="int"/> that contains a port number.
|
||||
@@ -183,10 +183,10 @@ namespace WebSocketSharp.Server {
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the server cleans up the inactive client.
|
||||
/// Gets or sets a value indicating whether the server cleans up the inactive clients periodically.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the server cleans up the inactive client; otherwise, <c>false</c>.
|
||||
/// <c>true</c> if the server cleans up the inactive clients every 60 seconds; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool Sweeped {
|
||||
get {
|
||||
@@ -220,7 +220,7 @@ namespace WebSocketSharp.Server {
|
||||
|
||||
private void init()
|
||||
{
|
||||
_sessions = new SessionManager();
|
||||
_sessions = new WebSocketServiceManager();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -228,7 +228,7 @@ namespace WebSocketSharp.Server {
|
||||
#region Explicit Interface Implementation
|
||||
|
||||
/// <summary>
|
||||
/// Binds the specified <see cref="WebSocket"/> instance to the WebSocket service.
|
||||
/// Binds the specified <see cref="WebSocket"/> to the WebSocket service instance.
|
||||
/// </summary>
|
||||
/// <param name="socket">
|
||||
/// A <see cref="WebSocket"/> to bind.
|
||||
@@ -248,7 +248,7 @@ namespace WebSocketSharp.Server {
|
||||
/// Accepts a WebSocket connection.
|
||||
/// </summary>
|
||||
/// <param name="context">
|
||||
/// A <see cref="TcpListenerWebSocketContext"/> that contains a WebSocket connection.
|
||||
/// A <see cref="TcpListenerWebSocketContext"/> that contains the WebSocket connection request objects.
|
||||
/// </param>
|
||||
protected override void AcceptWebSocket(TcpListenerWebSocketContext context)
|
||||
{
|
||||
@@ -285,8 +285,8 @@ namespace WebSocketSharp.Server {
|
||||
/// Pings with the specified <see cref="string"/> to all clients.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A Dictionary<string, bool> that contains the collection of the session ID and value
|
||||
/// indicating whether the server received a Pong in a time.
|
||||
/// A Dictionary<string, bool> that contains the collection of session IDs and values
|
||||
/// indicating whether the server received the Pongs from each clients in a time.
|
||||
/// </returns>
|
||||
/// <param name="message">
|
||||
/// A <see cref="string"/> that contains a message.
|
||||
|
408
websocket-sharp/Server/WebSocketServiceManager.cs
Normal file
408
websocket-sharp/Server/WebSocketServiceManager.cs
Normal file
@@ -0,0 +1,408 @@
|
||||
#region MIT License
|
||||
/*
|
||||
* WebSocketServiceManager.cs
|
||||
*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2012-2013 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 System.Linq;
|
||||
using System.Timers;
|
||||
|
||||
namespace WebSocketSharp.Server {
|
||||
|
||||
/// <summary>
|
||||
/// Manages the collection of <see cref="WebSocketService"/> objects.
|
||||
/// </summary>
|
||||
public class WebSocketServiceManager {
|
||||
|
||||
#region Fields
|
||||
|
||||
private object _forSweep;
|
||||
private volatile bool _isStopped;
|
||||
private volatile bool _isSweeping;
|
||||
private Dictionary<string, WebSocketService> _services;
|
||||
private Timer _sweepTimer;
|
||||
private object _syncRoot;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
internal WebSocketServiceManager()
|
||||
{
|
||||
_forSweep = new object();
|
||||
_isStopped = false;
|
||||
_isSweeping = false;
|
||||
_services = new Dictionary<string, WebSocketService>();
|
||||
_syncRoot = new object();
|
||||
|
||||
setSweepTimer();
|
||||
startSweepTimer();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of IDs of active <see cref="WebSocketService"/> objects
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// An IEnumerable<string> that contains the collection of IDs of active <see cref="WebSocketService"/> objects.
|
||||
/// </value>
|
||||
public IEnumerable<string> ActiveIDs {
|
||||
get {
|
||||
return from result in Broadping(String.Empty)
|
||||
where result.Value
|
||||
select result.Key;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of <see cref="WebSocketService"/> objects
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// An <see cref="int"/> that contains the number of <see cref="WebSocketService"/> objects
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </value>
|
||||
public int Count {
|
||||
get {
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _services.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of IDs of inactive <see cref="WebSocketService"/> objects
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// An IEnumerable<string> that contains the collection of IDs of inactive <see cref="WebSocketService"/> objects.
|
||||
/// </value>
|
||||
public IEnumerable<string> InactiveIDs {
|
||||
get {
|
||||
return from result in Broadping(String.Empty)
|
||||
where !result.Value
|
||||
select result.Key;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of IDs of <see cref="WebSocketService"/> objects
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// An IEnumerable<string> that contains the collection of IDs of <see cref="WebSocketService"/> objects.
|
||||
/// </value>
|
||||
public IEnumerable<string> IDs {
|
||||
get {
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _services.Keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="WebSocketServiceManager"/> cleans up
|
||||
/// the inactive <see cref="WebSocketService"/> objects periodically.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the <see cref="WebSocketServiceManager"/> cleans up the inactive <see cref="WebSocketService"/> objects
|
||||
/// every 60 seconds; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool Sweeped {
|
||||
get {
|
||||
return _sweepTimer.Enabled;
|
||||
}
|
||||
|
||||
internal set {
|
||||
if (value && !_isStopped)
|
||||
startSweepTimer();
|
||||
|
||||
if (!value)
|
||||
stopSweepTimer();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void broadcast(byte[] data)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
foreach (var service in _services.Values)
|
||||
service.Send(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(string data)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
foreach (var service in _services.Values)
|
||||
service.Send(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastAsync(byte[] data)
|
||||
{
|
||||
var copied = copy();
|
||||
var services = copied.Values.GetEnumerator();
|
||||
|
||||
Action completed = null;
|
||||
completed = () =>
|
||||
{
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
};
|
||||
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
}
|
||||
|
||||
private void broadcastAsync(string data)
|
||||
{
|
||||
var copied = copy();
|
||||
var services = copied.Values.GetEnumerator();
|
||||
|
||||
Action completed = null;
|
||||
completed = () =>
|
||||
{
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
};
|
||||
|
||||
if (services.MoveNext())
|
||||
services.Current.SendAsync(data, completed);
|
||||
}
|
||||
|
||||
private Dictionary<string, WebSocketService> copy()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return new Dictionary<string, WebSocketService>(_services);
|
||||
}
|
||||
}
|
||||
|
||||
private string createID()
|
||||
{
|
||||
return Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
private void setSweepTimer()
|
||||
{
|
||||
_sweepTimer = new Timer(60 * 1000);
|
||||
_sweepTimer.Elapsed += (sender, e) =>
|
||||
{
|
||||
Sweep();
|
||||
};
|
||||
}
|
||||
|
||||
private void startSweepTimer()
|
||||
{
|
||||
if (!Sweeped)
|
||||
_sweepTimer.Start();
|
||||
}
|
||||
|
||||
private void stop(ushort code, string reason, bool ignoreArgs)
|
||||
{
|
||||
stopSweepTimer();
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_isStopped)
|
||||
return;
|
||||
|
||||
_isStopped = true;
|
||||
foreach (var service in copy().Values)
|
||||
if (ignoreArgs)
|
||||
service.Stop();
|
||||
else
|
||||
service.Stop(code, reason);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopSweepTimer()
|
||||
{
|
||||
if (Sweeped)
|
||||
_sweepTimer.Stop();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
internal string Add(WebSocketService service)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_isStopped)
|
||||
return null;
|
||||
|
||||
var id = createID();
|
||||
_services.Add(id, service);
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool Remove(string id)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _services.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Stop()
|
||||
{
|
||||
stop(0, null, true);
|
||||
}
|
||||
|
||||
internal void Stop(ushort code, string reason)
|
||||
{
|
||||
stop(code, reason, false);
|
||||
}
|
||||
|
||||
internal void Stop(CloseStatusCode code, string reason)
|
||||
{
|
||||
Stop((ushort)code, reason);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts the specified array of <see cref="byte"/> to the clients of every <see cref="WebSocketService"/>
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// An array of <see cref="byte"/> to broadcast.
|
||||
/// </param>
|
||||
public void Broadcast(byte[] data)
|
||||
{
|
||||
if (_isStopped)
|
||||
broadcast(data);
|
||||
else
|
||||
broadcastAsync(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts the specified <see cref="string"/> to the clients of every <see cref="WebSocketService"/>
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="string"/> to broadcast.
|
||||
/// </param>
|
||||
public void Broadcast(string data)
|
||||
{
|
||||
if (_isStopped)
|
||||
broadcast(data);
|
||||
else
|
||||
broadcastAsync(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings with the specified <see cref="string"/> to the clients of every <see cref="WebSocketService"/>
|
||||
/// managed by the <see cref="WebSocketServiceManager"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A Dictionary<string, bool> that contains the collection of IDs and values
|
||||
/// indicating whether each <see cref="WebSocketService"/> received a Pong in a time.
|
||||
/// </returns>
|
||||
/// <param name="message">
|
||||
/// A <see cref="string"/> that contains a message.
|
||||
/// </param>
|
||||
public Dictionary<string, bool> Broadping(string message)
|
||||
{
|
||||
var result = new Dictionary<string, bool>();
|
||||
foreach (var session in copy())
|
||||
result.Add(session.Key, session.Value.Ping(message));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up the inactive <see cref="WebSocketService"/> objects.
|
||||
/// </summary>
|
||||
public void Sweep()
|
||||
{
|
||||
if (_isStopped || _isSweeping || Count == 0)
|
||||
return;
|
||||
|
||||
lock (_forSweep)
|
||||
{
|
||||
_isSweeping = true;
|
||||
foreach (var id in InactiveIDs)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_isStopped)
|
||||
{
|
||||
_isSweeping = false;
|
||||
return;
|
||||
}
|
||||
|
||||
WebSocketService service;
|
||||
if (TryGetWebSocketService(id, out service))
|
||||
service.Stop(CloseStatusCode.ABNORMAL, String.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
_isSweeping = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the <see cref="WebSocketService"/> associated with the specified <paramref name="id"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the <see cref="WebSocketServiceManager"/> manages the <see cref="WebSocketService"/> with the specified <paramref name="id"/>; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <param name="id">
|
||||
/// A <see cref="string"/> that contains the ID to find.
|
||||
/// </param>
|
||||
/// <param name="service">
|
||||
/// When this method returns, contains the <see cref="WebSocketService"/> with the specified <paramref name="id"/>, if the <paramref name="id"/> is found; otherwise, <see langword="null"/>.
|
||||
/// </param>
|
||||
public bool TryGetWebSocketService(string id, out WebSocketService service)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
return _services.TryGetValue(id, out service);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user