Fix for issue #6 - 1
This commit is contained in:
parent
75417fba70
commit
3ef6d58f31
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.
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.
Binary file not shown.
Binary file not shown.
@ -7,13 +7,14 @@ namespace Example2
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var wssv = new WebSocketServer<Echo>("ws://localhost:4649");
|
//var wssv = new WebSocketServer<Echo>("ws://localhost:4649");
|
||||||
//var wssv = new WebSocketServer<Chat>("ws://localhost:4649");
|
//var wssv = new WebSocketServer<Chat>("ws://localhost:4649");
|
||||||
|
var wssv = new WebSocketServer<Echo>("/", 4649);
|
||||||
|
|
||||||
wssv.Start();
|
wssv.Start();
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
"WebSocket Server (url: {0}) listening on port: {1}\n",
|
"WebSocket Server (url: {0})\n listening on address: {1} port: {2}\n",
|
||||||
wssv.Url, wssv.Port);
|
wssv.Url, wssv.Address, wssv.Port);
|
||||||
|
|
||||||
Console.WriteLine("Press any key to stop server...");
|
Console.WriteLine("Press any key to stop server...");
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
|
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.
@ -57,6 +57,8 @@ namespace WebSocketSharp
|
|||||||
|
|
||||||
public static bool EqualsAndSaveTo(this int value, char c, List<byte> dest)
|
public static bool EqualsAndSaveTo(this int value, char c, List<byte> dest)
|
||||||
{
|
{
|
||||||
|
if (value < 0)
|
||||||
|
throw new ArgumentOutOfRangeException("value");
|
||||||
byte b = (byte)value;
|
byte b = (byte)value;
|
||||||
dest.Add(b);
|
dest.Add(b);
|
||||||
return b == Convert.ToByte(c);
|
return b == Convert.ToByte(c);
|
||||||
|
@ -37,19 +37,65 @@ using System.Net.Sockets;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using WebSocketSharp.Frame;
|
using WebSocketSharp.Frame;
|
||||||
|
|
||||||
namespace WebSocketSharp.Server
|
namespace WebSocketSharp.Server {
|
||||||
{
|
|
||||||
public class WebSocketServer<T>
|
public class WebSocketServer<T>
|
||||||
where T : WebSocketService, new()
|
where T : WebSocketService, new()
|
||||||
{
|
{
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
|
private Thread _acceptClientThread;
|
||||||
private Dictionary<string, WebSocketService> _services;
|
private Dictionary<string, WebSocketService> _services;
|
||||||
private TcpListener _tcpListener;
|
private TcpListener _tcpListener;
|
||||||
private Uri _uri;
|
private Uri _uri;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public WebSocketServer(string url)
|
||||||
|
{
|
||||||
|
_uri = new Uri(url);
|
||||||
|
if (!isValidScheme(_uri))
|
||||||
|
{
|
||||||
|
var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
|
||||||
|
throw new ArgumentException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var host = _uri.DnsSafeHost;
|
||||||
|
var ips = Dns.GetHostAddresses(host);
|
||||||
|
if (ips.Length == 0)
|
||||||
|
{
|
||||||
|
var msg = "Invalid WebSocket URI host: " + host;
|
||||||
|
throw new ArgumentException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var scheme = _uri.Scheme;
|
||||||
|
var port = _uri.Port;
|
||||||
|
if (port <= 0)
|
||||||
|
{
|
||||||
|
port = 80;
|
||||||
|
if (scheme == "wss")
|
||||||
|
port = 443;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tcpListener = new TcpListener(ips[0], port);
|
||||||
|
_services = new Dictionary<string, WebSocketService>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WebSocketServer(string absPath, int port)
|
||||||
|
{
|
||||||
|
_uri = new Uri(absPath, UriKind.Relative);
|
||||||
|
|
||||||
|
if (port <= 0)
|
||||||
|
port = 80;
|
||||||
|
|
||||||
|
_tcpListener = new TcpListener(IPAddress.Any, port);
|
||||||
|
_services = new Dictionary<string, WebSocketService>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
public IPAddress Address
|
public IPAddress Address
|
||||||
@ -80,69 +126,27 @@ namespace WebSocketSharp.Server
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Constructor
|
|
||||||
|
|
||||||
public WebSocketServer(string url)
|
|
||||||
{
|
|
||||||
_uri = new Uri(url);
|
|
||||||
|
|
||||||
if (!isValidScheme(_uri))
|
|
||||||
{
|
|
||||||
var msg = "Unsupported WebSocket URI scheme: " + _uri.Scheme;
|
|
||||||
throw new ArgumentException(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
string scheme = _uri.Scheme;
|
|
||||||
int port = _uri.Port;
|
|
||||||
|
|
||||||
if (port <= 0)
|
|
||||||
{
|
|
||||||
if (scheme == "wss")
|
|
||||||
{
|
|
||||||
port = 443;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
port = 80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_tcpListener = new TcpListener(IPAddress.Any, port);
|
|
||||||
_services = new Dictionary<string, WebSocketService>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
private void acceptClient(IAsyncResult ar)
|
private void acceptClient()
|
||||||
{
|
{
|
||||||
TcpListener listener = (TcpListener)ar.AsyncState;
|
while (true)
|
||||||
|
|
||||||
if (listener.Server == null || !listener.Server.IsBound)
|
|
||||||
{
|
{
|
||||||
return;
|
try {
|
||||||
|
var client = _tcpListener.AcceptTcpClient();
|
||||||
|
startService(client);
|
||||||
|
}
|
||||||
|
catch (SocketException)
|
||||||
|
{
|
||||||
|
// TcpListener has been stopped.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error(ex.Message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TcpClient client = listener.EndAcceptTcpClient(ar);
|
|
||||||
WebSocket socket = new WebSocket(_uri, client);
|
|
||||||
T service = new T();
|
|
||||||
service.Bind(socket, _services);
|
|
||||||
service.Start();
|
|
||||||
}
|
|
||||||
catch (ObjectDisposedException)
|
|
||||||
{
|
|
||||||
// TcpListener has been stopped.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
error(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
listener.BeginAcceptTcpClient(acceptClient, listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void error(string message)
|
private void error(string message)
|
||||||
@ -157,28 +161,57 @@ namespace WebSocketSharp.Server
|
|||||||
|
|
||||||
private bool isValidScheme(Uri uri)
|
private bool isValidScheme(Uri uri)
|
||||||
{
|
{
|
||||||
string scheme = uri.Scheme;
|
var scheme = uri.Scheme;
|
||||||
if (scheme == "ws" || scheme == "wss")
|
if (scheme == "ws" || scheme == "wss")
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startAcceptClientThread()
|
||||||
|
{
|
||||||
|
_acceptClientThread = new Thread(new ThreadStart(acceptClient));
|
||||||
|
_acceptClientThread.IsBackground = true;
|
||||||
|
_acceptClientThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startService(TcpClient client)
|
||||||
|
{
|
||||||
|
WaitCallback startCb = (state) =>
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
var socket = new WebSocket(_uri, client);
|
||||||
|
BindWebSocket(socket);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
error(ex.Message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ThreadPool.QueueUserWorkItem(startCb);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
|
|
||||||
|
public void BindWebSocket(WebSocket socket)
|
||||||
|
{
|
||||||
|
T service = new T();
|
||||||
|
service.Bind(socket, _services);
|
||||||
|
service.Start();
|
||||||
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
_tcpListener.Start();
|
_tcpListener.Start();
|
||||||
_tcpListener.BeginAcceptTcpClient(acceptClient, _tcpListener);
|
startAcceptClientThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
_tcpListener.Stop();
|
_tcpListener.Stop();
|
||||||
|
_acceptClientThread.Join(5 * 1000);
|
||||||
StopServices();
|
StopServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,9 +225,7 @@ namespace WebSocketSharp.Server
|
|||||||
lock (((ICollection)_services).SyncRoot)
|
lock (((ICollection)_services).SyncRoot)
|
||||||
{
|
{
|
||||||
foreach (WebSocketService service in _services.Values)
|
foreach (WebSocketService service in _services.Values)
|
||||||
{
|
|
||||||
service.Stop(code, reason);
|
service.Stop(code, reason);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ namespace WebSocketSharp
|
|||||||
|
|
||||||
private string _base64key;
|
private string _base64key;
|
||||||
private string _binaryType;
|
private string _binaryType;
|
||||||
|
private IPEndPoint _endPoint;
|
||||||
private AutoResetEvent _exitedMessageLoop;
|
private AutoResetEvent _exitedMessageLoop;
|
||||||
private string _extensions;
|
private string _extensions;
|
||||||
private Object _forClose;
|
private Object _forClose;
|
||||||
@ -106,6 +107,7 @@ namespace WebSocketSharp
|
|||||||
{
|
{
|
||||||
_uri = uri;
|
_uri = uri;
|
||||||
_tcpClient = tcpClient;
|
_tcpClient = tcpClient;
|
||||||
|
_endPoint = (IPEndPoint)_tcpClient.Client.LocalEndPoint;
|
||||||
_isClient = false;
|
_isClient = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,15 +179,24 @@ namespace WebSocketSharp
|
|||||||
get { return _extensions; }
|
get { return _extensions; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsConnected
|
public bool IsConnected {
|
||||||
{
|
get {
|
||||||
get
|
if (_readyState != WsState.OPEN)
|
||||||
{
|
return false;
|
||||||
if (_readyState != WsState.OPEN) return false;
|
|
||||||
return Ping();
|
return Ping();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsSecure {
|
||||||
|
get {
|
||||||
|
if (_endPoint.Port == 443)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Protocol
|
public string Protocol
|
||||||
{
|
{
|
||||||
get { return _protocol; }
|
get { return _protocol; }
|
||||||
@ -447,7 +458,7 @@ namespace WebSocketSharp
|
|||||||
{
|
{
|
||||||
_netStream = _tcpClient.GetStream();
|
_netStream = _tcpClient.GetStream();
|
||||||
|
|
||||||
if (_uri.Scheme == "wss")
|
if (IsSecure)
|
||||||
{
|
{
|
||||||
_sslStream = new SslStream(_netStream);
|
_sslStream = new SslStream(_netStream);
|
||||||
|
|
||||||
@ -507,16 +518,18 @@ namespace WebSocketSharp
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
string expectedHost = _uri.DnsSafeHost;
|
if (_uri.IsAbsoluteUri)
|
||||||
int port = ((IPEndPoint)_tcpClient.Client.LocalEndPoint).Port;
|
{
|
||||||
if (port != 80)
|
if (_uri.PathAndQuery.NotEqualsDo(request.Uri, func("Request URI"), out message, false))
|
||||||
expectedHost += ":" + port;
|
return false;
|
||||||
|
|
||||||
if (_uri.PathAndQuery.NotEqualsDo(request.Uri, func("Request URI"), out message, false))
|
if (!isValidRequestHost(request.GetHeaderValues("Host")[0], func("Host"), out message))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (expectedHost.NotEqualsDo(request.GetHeaderValues("Host")[0], func("Host"), out message, false))
|
if (!_uri.IsAbsoluteUri)
|
||||||
return false;
|
if (_uri.ToString().NotEqualsDo(request.Uri, func("Request URI"), out message, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!request.HeaderExists("Sec-WebSocket-Version", _version))
|
if (!request.HeaderExists("Sec-WebSocket-Version", _version))
|
||||||
{
|
{
|
||||||
@ -536,6 +549,27 @@ namespace WebSocketSharp
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool isValidRequestHost(string value, Func<string, string, string> func, out string message)
|
||||||
|
{
|
||||||
|
var address = _endPoint.Address;
|
||||||
|
var port = _endPoint.Port;
|
||||||
|
|
||||||
|
var expectedHost1 = _uri.DnsSafeHost;
|
||||||
|
var expectedHost2 = address.ToString();
|
||||||
|
if (port != 80)
|
||||||
|
{
|
||||||
|
expectedHost1 += ":" + port;
|
||||||
|
expectedHost2 += ":" + port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedHost1.NotEqualsDo(value, func, out message, false))
|
||||||
|
if (expectedHost2.NotEqualsDo(value, func, out message, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
message = String.Empty;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private bool isValidResponse(ResponseHandshake response, out string message)
|
private bool isValidResponse(ResponseHandshake response, out string message)
|
||||||
{
|
{
|
||||||
if (!response.IsWebSocketResponse)
|
if (!response.IsWebSocketResponse)
|
||||||
|
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.
Loading…
Reference in New Issue
Block a user