Fix due to the added QueryString property in WebSocketService.cs

This commit is contained in:
sta 2012-10-22 14:58:43 +09:00
parent a7eef35c96
commit c55b5d6479
78 changed files with 1346 additions and 830 deletions

Binary file not shown.

View File

@ -77,7 +77,11 @@ namespace Example
//using (WebSocket ws = new WebSocket("wss://echo.websocket.org", "echo"))
//using (WebSocket ws = new WebSocket("ws://localhost:4649"))
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Echo"))
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Echo?name=nobita"))
//using (WebSocket ws = new WebSocket("ws://localhost:4649/エコー?name=のび太"))
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Chat"))
//using (WebSocket ws = new WebSocket("ws://localhost:4649/Chat?name=nobita"))
//using (WebSocket ws = new WebSocket("ws://localhost:4649/チャット?name=のび太"))
{
ws.OnOpen += (sender, e) =>
{

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

@ -6,9 +6,37 @@ namespace Example2
{
public class Chat : WebSocketService
{
protected override void onMessage(object sender, MessageEventArgs e)
private static object _forId = new object();
private static uint _id = 0;
private string _name;
private string getName()
{
Publish(e.Data);
lock (_forId)
{
return QueryString.Exists("name")
? QueryString["name"]
: "anon#" + (++_id);
}
}
protected override void OnOpen(object sender, EventArgs e)
{
_name = getName();
}
protected override void OnMessage(object sender, MessageEventArgs e)
{
var msg = String.Format("{0}: {1}", _name, e.Data);
Publish(msg);
}
protected override void OnClose(object sender, CloseEventArgs e)
{
var msg = String.Format("{0} got logged off...", _name);
Publish(msg);
}
}
}

View File

@ -2,18 +2,16 @@ using System;
using WebSocketSharp;
using WebSocketSharp.Server;
namespace Example2
{
namespace Example2 {
public class Echo : WebSocketService
{
protected override void onMessage(object sender, MessageEventArgs e)
protected override void OnMessage(object sender, MessageEventArgs e)
{
Send(e.Data);
}
protected override void onClose(object sender, CloseEventArgs e)
{
Console.WriteLine("[Echo] Close({0})", e.Code);
var msg = QueryString.Exists("name")
? String.Format("'{0}' returns to {1}", e.Data, QueryString["name"])
: e.Data;
Send(msg);
}
}
}

Binary file not shown.

View File

@ -8,10 +8,18 @@ namespace Example2
public static void Main(string[] args)
{
/* Single service server
var wssv = new WebSocketServer<Echo>("ws://localhost:4649");
//var wssv = new WebSocketServer<Echo>("ws://localhost:4649");
var wssv = new WebSocketServer<Echo>("ws://localhost:4649/Echo");
//var wssv = new WebSocketServer<Echo>("ws://localhost:4649/エコー");
//var wssv = new WebSocketServer<Echo>(4649);
//var wssv = new WebSocketServer<Echo>(4649, "/Echo");
//var wssv = new WebSocketServer<Echo>(4649, "/エコー");
//var wssv = new WebSocketServer<Chat>("ws://localhost:4649");
//var wssv = new WebSocketServer<Chat>("ws://localhost:4649/Chat");
//var wssv = new WebSocketServer<Chat>("ws://localhost:4649/チャット");
//var wssv = new WebSocketServer<Chat>(4649);
//var wssv = new WebSocketServer<Chat>(4649, "/Chat");
//var wssv = new WebSocketServer<Chat>(4649, "/チャット");
wssv.Start();
Console.WriteLine(
@ -22,7 +30,9 @@ namespace Example2
// Multi services server
var wssv = new WebSocketServer(4649);
wssv.AddService<Echo>("/Echo");
wssv.AddService<Echo>("/エコー");
wssv.AddService<Chat>("/Chat");
wssv.AddService<Chat>("/チャット");
wssv.Start();
Console.WriteLine(

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,9 +6,37 @@ namespace Example3
{
public class Chat : WebSocketService
{
protected override void onMessage(object sender, MessageEventArgs e)
private static object _forId = new object();
private static uint _id = 0;
private string _name;
private string getName()
{
Publish(e.Data);
lock (_forId)
{
return QueryString.Exists("name")
? QueryString["name"]
: "anon#" + (++_id);
}
}
protected override void OnOpen(object sender, EventArgs e)
{
_name = getName();
}
protected override void OnMessage(object sender, MessageEventArgs e)
{
var msg = String.Format("{0}: {1}", _name, e.Data);
Publish(msg);
}
protected override void OnClose(object sender, CloseEventArgs e)
{
var msg = String.Format("{0} got logged off...", _name);
Publish(msg);
}
}
}

View File

@ -6,14 +6,12 @@ namespace Example3
{
public class Echo : WebSocketService
{
protected override void onMessage(object sender, MessageEventArgs e)
protected override void OnMessage(object sender, MessageEventArgs e)
{
Send(e.Data);
}
protected override void onClose(object sender, CloseEventArgs e)
{
Console.WriteLine("[Echo] Close({0})", e.Code);
var msg = QueryString.Exists("name")
? String.Format("'{0}' returns to {1}", e.Data, QueryString["name"])
: e.Data;
Send(msg);
}
}
}

Binary file not shown.

View File

@ -12,7 +12,8 @@ namespace Example3
public static void Main(string[] args)
{
_httpsv = new HttpServer(4649);
_httpsv.AddService<Echo>("/");
_httpsv.AddService<Echo>("/Echo");
_httpsv.AddService<Chat>("/Chat");
_httpsv.OnGet += (sender, e) =>
{

View File

@ -6,7 +6,7 @@
*
*/
var wsUri = "ws://localhost:4649/";
var wsUri = "ws://localhost:4649/Echo";
var output;
function init(){

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -164,7 +164,7 @@ using WebSocketSharp.Server;
public class Echo : WebSocketService
{
protected override void onMessage(object sender, MessageEventArgs e)
protected override void OnMessage(object sender, MessageEventArgs e)
{
Send(e.Data);
}
@ -180,16 +180,16 @@ using WebSocketSharp.Server;
public class Chat : WebSocketService
{
protected override void onMessage(object sender, MessageEventArgs e)
protected override void OnMessage(object sender, MessageEventArgs e)
{
Publish(e.Data);
}
}
```
If you override the `onMessage` method, it is bound to the server side `WebSocket.OnMessage` event.
If you override the `OnMessage` method, it is bound to the server side `WebSocket.OnMessage` event.
In addition, if you override the `onOpen`, `onError` and `onClose` methods, each of them is bound to the `WebSocket.OnOpen`, `WebSocket.OnError` and `WebSocket.OnClose` events.
In addition, if you override the `OnOpen`, `OnError` and `OnClose` methods, each of them is bound to the `WebSocket.OnOpen`, `WebSocket.OnError` and `WebSocket.OnClose` events.
#### Step 3 ####

View File

@ -52,23 +52,46 @@ namespace WebSocketSharp {
return new TcpListenerWebSocketContext(client);
}
/// <summary>
/// Emit the specified <see cref="EventHandler"/> delegate if is not <see langword="null"/>.
/// </summary>
/// <param name="eventHandler">
/// An <see cref="EventHandler"/> to be emitted.
/// </param>
/// <param name="sender">
/// An <see cref="object"/> that emits this <paramref name="eventHandler"/>.
/// </param>
/// <param name="e">
/// An <see cref="EventArgs"/> that contains no event data.
/// </param>
public static void Emit(
this EventHandler eventHandler, object sender, EventArgs e)
{
if (eventHandler != null)
{
if (!eventHandler.IsNull())
eventHandler(sender, e);
}
}
/// <summary>
/// Emit the specified <see cref="EventHandler&lt;TEventArgs&gt;"/> delegate if is not <see langword="null"/>.
/// </summary>
/// <param name="eventHandler">
/// An <see cref="EventHandler&lt;TEventArgs&gt;"/> to be emitted.
/// </param>
/// <param name="sender">
/// An <see cref="object"/> that emits this <paramref name="eventHandler"/>.
/// </param>
/// <param name="e">
/// An <see cref="EventArgs"/> that contains the event data.
/// </param>
/// <typeparam name="TEventArgs">
/// The type of the event data generated by the event.
/// </typeparam>
public static void Emit<TEventArgs>(
this EventHandler<TEventArgs> eventHandler, object sender, TEventArgs e)
where TEventArgs : EventArgs
{
if (eventHandler != null)
{
if (!eventHandler.IsNull())
eventHandler(sender, e);
}
}
public static bool EqualsAndSaveTo(this int value, char c, List<byte> dest)
@ -81,17 +104,17 @@ namespace WebSocketSharp {
return b == Convert.ToByte(c);
}
public static bool Exists(this NameValueCollection headers, string name)
public static bool Exists(this NameValueCollection collections, string name)
{
return headers[name] != null
return collections[name] != null
? true
: false;
}
public static bool Exists(this NameValueCollection headers, string name, string value)
public static bool Exists(this NameValueCollection collections, string name, string value)
{
var values = headers[name];
if (values == null)
var values = collections[name];
if (values.IsNull())
return false;
foreach (string v in values.Split(','))
@ -101,6 +124,27 @@ namespace WebSocketSharp {
return false;
}
public static string GetAbsolutePath(this Uri uri)
{
if (uri.IsAbsoluteUri)
return uri.AbsolutePath;
var uriString = uri.OriginalString;
var i = uriString.IndexOf('/');
if (i != 0)
{
var msg = "Not absolute path: " + uriString;
throw new ArgumentException(msg, "uri");
}
var j = uriString.IndexOfAny(new []{'?', '#'});
if (j > 0)
return uriString.Substring(0, j);
return uriString;
}
public static string GetDescription(this HttpStatusCode code)
{
return ((int)code).GetStatusDescription();
@ -162,11 +206,32 @@ namespace WebSocketSharp {
return String.Empty;
}
public static string GetName(this string nameAndValue, string separator)
{
var i = nameAndValue.IndexOf(separator);
if (i <= 0)
return null;
return nameAndValue.Substring(0, i).Trim();
}
public static KeyValuePair<string, string> GetNameAndValue(this string nameAndValue, string separator)
{
var i = nameAndValue.IndexOf(separator);
if (i <= 0 || i == nameAndValue.Length - 1)
return new KeyValuePair<string, string>(null, null);
var name = nameAndValue.Substring(0, i).Trim();
var value = nameAndValue.Substring(i + 1).Trim();
return new KeyValuePair<string, string>(name, value);
}
/// <summary>
/// Gets the value from a <see cref="string"/> that contains a pair of name and value are separated by a separator string.
/// </summary>
/// <returns>
/// A <see cref="string"/> that contains the value if can get; otherwise, <c>null</c>.
/// A <see cref="string"/> that contains the value if any; otherwise, <c>null</c>.
/// </returns>
/// <param name="nameAndValue">
/// A <see cref="string"/> that contains a pair of name and value are separated by a separator string.
@ -177,7 +242,7 @@ namespace WebSocketSharp {
public static string GetValue(this string nameAndValue, string separator)
{
var i = nameAndValue.IndexOf(separator);
if (i <= 0)
if (i == -1 || i == nameAndValue.Length - 1)
return null;
return nameAndValue.Substring(i + 1).Trim();
@ -195,10 +260,42 @@ namespace WebSocketSharp {
}
}
public static bool IsNullDo<T>(this T value, Action act)
/// <summary>
/// Determines whether the specified <see cref="string"/> is <see cref="String.Empty"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the <paramref name="value"/> is <see cref="String.Empty"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="value">
/// A <see cref="string"/> to test.
/// </param>
public static bool IsEmpty(this string value)
{
return value == String.Empty ? true : false;
}
/// <summary>
/// Determines whether the specified object is <see langword="null"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the specified object is <see langword="null"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="obj">
/// An <see cref="class"/> to test.
/// </param>
/// <typeparam name="T">
/// The type of this <paramref name="obj"/>.
/// </typeparam>
public static bool IsNull<T>(this T obj)
where T : class
{
if (value == null)
return obj == null ? true : false;
}
public static bool IsNullDo<T>(this T obj, Action act)
where T : class
{
if (obj.IsNull())
{
act();
return true;
@ -207,10 +304,50 @@ namespace WebSocketSharp {
return false;
}
/// <summary>
/// Determines whether the specified <see cref="string"/> is <see langword="null"/> or <see cref="String.Empty"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the specified <see cref="string"/> is <see langword="null"/> or <see cref="String.Empty"/>; otherwise, <c>false</c>.
/// </returns>
/// <param name="value">
/// A <see cref="string"/> to test.
/// </param>
public static bool IsNullOrEmpty(this string value)
{
return String.IsNullOrEmpty(value);
}
public static bool IsValidAbsolutePath(this string absPath, out string message)
{
if (absPath.IsEmpty())
{
message = "Must not be empty.";
return false;
}
var i = absPath.IndexOf('/');
if (i != 0)
{
message = "Not absolute path: " + absPath;
return false;
}
var j = absPath.IndexOfAny(new []{'?', '#'});
if (j != -1)
{
message = "Must not contain either or both query and fragment components: " + absPath;
return false;
}
message = String.Empty;
return true;
}
// Derived from System.Uri.IsPredefinedScheme method
public static bool IsPredefinedScheme(this string scheme)
{
if (scheme == null && scheme.Length < 2)
if (scheme.IsNull() && scheme.Length < 2)
return false;
char c = scheme[0];
@ -243,56 +380,6 @@ namespace WebSocketSharp {
return false;
}
/// <summary>
/// Determines whether <paramref name="uri"/> is valid WebSocket URI.
/// </summary>
/// <returns>
/// <c>true</c> if <paramref name="uri"/> is valid WebSocket URI; otherwise, <c>false</c>.
/// </returns>
/// <param name="uri">
/// A <see cref="Uri"/> that contains a WebSocket URI.
/// </param>
/// <param name="message">
/// A <see cref="string"/> that contains a error message if <paramref name="uri"/> is invalid WebSocket URI; otherwise, <c>String.Empty</c>.
/// </param>
public static bool IsValidWebSocketUri(this Uri uri, out string message)
{
if (!uri.IsAbsoluteUri)
{
message = "Not absolute URI: " + uri.ToString();
return false;
}
var scheme = uri.Scheme;
if (scheme != "ws" && scheme != "wss")
{
message = "Unsupported WebSocket URI scheme: " + scheme;
return false;
}
var original = uri.OriginalString;
if (original.Contains('#'))
{
message = "WebSocket URI must not contain a fragment component: " + original;
return false;
}
var port = uri.Port;
if (port > 0)
{
if ((scheme == "ws" && port == 443) ||
(scheme == "wss" && port == 80))
{
message = String.Format(
"Invalid pair of WebSocket URI scheme and port: {0}, {1}", scheme, port);
return false;
}
}
message = String.Empty;
return true;
}
// Derived from System.Uri.MaybeUri method
public static bool MaybeUri(this string uriString)
{
@ -372,12 +459,11 @@ namespace WebSocketSharp {
public static T[] SubArray<T>(this T[] array, int startIndex, int length)
{
if (startIndex == 0 && array.Length == length)
{
return array;
}
T[] subArray = new T[length];
Array.Copy(array, startIndex, subArray, 0, length);
Array.Copy(array, startIndex, subArray, 0, length);
return subArray;
}
@ -564,6 +650,85 @@ namespace WebSocketSharp {
return new Uri(uriString);
}
/// <summary>
/// Tries to create a new WebSocket <see cref="Uri"/> using <paramref name="uriString"/>.
/// </summary>
/// <returns>
/// <c>true</c> if the WebSocket <see cref="Uri"/> was successfully created; otherwise, <c>false</c>.
/// </returns>
/// <param name="uriString">
/// A <see cref="string"/> that contains a WebSocket URI.
/// </param>
/// <param name="result">
/// When this method returns, contains a created WebSocket <see cref="Uri"/> if <paramref name="uriString"/> is valid WebSocket URI; otherwise, <see langword="null"/>.
/// </param>
/// <param name="message">
/// When this method returns, contains a error message <see cref="string"/> if <paramref name="uriString"/> is invalid WebSocket URI; otherwise, <c>String.Empty</c>.
/// </param>
/// <exception cref="ArgumentNullException">
/// Is thrown when <paramref name="uriString"/> passed to a method is invalid because it is <see langword="null"/>.
/// </exception>
public static bool TryCreateWebSocketUri(this string uriString, out Uri result, out string message)
{
if (uriString == null)
throw new ArgumentNullException("uriString");
result = null;
if (uriString == String.Empty)
{
message = "Must not be empty.";
return false;
}
var uri = uriString.ToUri();
if (!uri.IsAbsoluteUri)
{
message = "Not absolute URI: " + uriString;
return false;
}
var scheme = uri.Scheme;
if (scheme != "ws" && scheme != "wss")
{
message = "Unsupported scheme: " + scheme;
return false;
}
var fragment = uri.Fragment;
if (!String.IsNullOrEmpty(fragment))
{
message = "Must not contain the fragment component: " + uriString;
return false;
}
var port = uri.Port;
if (port > 0)
{
if ((scheme == "ws" && port == 443) ||
(scheme == "wss" && port == 80))
{
message = String.Format(
"Invalid pair of scheme and port: {0}, {1}", scheme, port);
return false;
}
}
result = uri;
message = String.Empty;
return true;
}
public static string UrlDecode(this string s)
{
return HttpUtility.UrlDecode(s);
}
public static string UrlEncode(this string s)
{
return HttpUtility.UrlEncode(s);
}
public static void WriteContent(this HttpListenerResponse response, byte[] content)
{
var output = response.OutputStream;

View File

@ -169,9 +169,9 @@ namespace WebSocketSharp.Net {
#region Public Method
public HttpListenerWebSocketContext AcceptWebSocket (string path)
public HttpListenerWebSocketContext AcceptWebSocket ()
{
return new HttpListenerWebSocketContext (path, this);
return new HttpListenerWebSocketContext (this);
}
#endregion

View File

@ -39,67 +39,113 @@ namespace WebSocketSharp.Net {
private WebSocket _socket;
private WsStream _stream;
internal HttpListenerWebSocketContext(string path, HttpListenerContext context)
internal HttpListenerWebSocketContext(HttpListenerContext context)
{
_context = context;
_stream = WsStream.CreateServerStream(context);
_socket = new WebSocket(path.ToUri(), this);
_socket = new WebSocket(this);
}
internal HttpListenerContext BaseContext {
get { return _context; }
get {
return _context;
}
}
internal WsStream Stream {
get { return _stream; }
get {
return _stream;
}
}
public override CookieCollection CookieCollection {
get { return _context.Request.Cookies; }
get {
return _context.Request.Cookies;
}
}
public override NameValueCollection Headers {
get { return _context.Request.Headers; }
get {
return _context.Request.Headers;
}
}
public override bool IsAuthenticated {
get { return _context.Request.IsAuthenticated; }
get {
return _context.Request.IsAuthenticated;
}
}
public override bool IsSecureConnection {
get { return _context.Request.IsSecureConnection; }
get {
return _context.Request.IsSecureConnection;
}
}
public override bool IsLocal {
get { return _context.Request.IsLocal; }
get {
return _context.Request.IsLocal;
}
}
public override string Origin {
get { return Headers["Origin"]; }
get {
return Headers["Origin"];
}
}
public virtual string Path {
get {
return RequestUri.GetAbsolutePath();
}
}
public override Uri RequestUri {
get { return _context.Request.RawUrl.ToUri(); }
get {
return _context.Request.RawUrl.ToUri();
}
}
public override string SecWebSocketKey {
get { return Headers["Sec-WebSocket-Key"]; }
get {
return Headers["Sec-WebSocket-Key"];
}
}
public override IEnumerable<string> SecWebSocketProtocols {
get { return Headers.GetValues("Sec-WebSocket-Protocol"); }
get {
return Headers.GetValues("Sec-WebSocket-Protocol");
}
}
public override string SecWebSocketVersion {
get { return Headers["Sec-WebSocket-Version"]; }
get {
return Headers["Sec-WebSocket-Version"];
}
}
public virtual System.Net.IPEndPoint ServerEndPoint {
get {
return _context.Connection.LocalEndPoint;
}
}
public override IPrincipal User {
get { return _context.User; }
get {
return _context.User;
}
}
public virtual System.Net.IPEndPoint UserEndPoint {
get {
return _context.Connection.RemoteEndPoint;
}
}
public override WebSocket WebSocket {
get { return _socket; }
get {
return _socket;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Net.Sockets;
using System.Security.Principal;
@ -44,72 +45,113 @@ namespace WebSocketSharp.Net.Sockets {
internal TcpListenerWebSocketContext(TcpClient client)
{
_client = client;
init();
}
internal TcpClient Client {
get { return _client; }
}
internal WsStream Stream {
get { return _stream; }
}
public override CookieCollection CookieCollection {
get { throw new NotImplementedException(); }
}
public override NameValueCollection Headers {
get { return _request.Headers; }
}
public override bool IsAuthenticated {
get { throw new NotImplementedException(); }
}
public override bool IsSecureConnection {
get { return _isSecure; }
}
public override bool IsLocal {
get { throw new NotImplementedException(); }
}
public override string Origin {
get { return Headers["Origin"]; }
}
public override Uri RequestUri {
get { return _request.RequestUri; }
}
public override string SecWebSocketKey {
get { return Headers["Sec-WebSocket-Key"]; }
}
public override IEnumerable<string> SecWebSocketProtocols {
get { return Headers.GetValues("Sec-WebSocket-Protocol"); }
}
public override string SecWebSocketVersion {
get { return Headers["Sec-WebSocket-Version"]; }
}
public override IPrincipal User {
get { throw new NotImplementedException(); }
}
public override WebSocket WebSocket {
get { return _socket; }
}
private void init()
{
_stream = WsStream.CreateServerStream(_client);
_client = client;
_stream = WsStream.CreateServerStream(client);
_isSecure = _stream.IsSecure;
_request = RequestHandshake.Parse(_stream.ReadHandshake());
_socket = new WebSocket(this);
}
internal TcpClient Client {
get {
return _client;
}
}
internal WsStream Stream {
get {
return _stream;
}
}
public override CookieCollection CookieCollection {
get {
throw new NotImplementedException();
}
}
public override NameValueCollection Headers {
get {
return _request.Headers;
}
}
public override bool IsAuthenticated {
get {
throw new NotImplementedException();
}
}
public override bool IsSecureConnection {
get {
return _isSecure;
}
}
public override bool IsLocal {
get {
throw new NotImplementedException();
}
}
public override string Origin {
get {
return Headers["Origin"];
}
}
public virtual string Path {
get {
return _request.RequestUri.GetAbsolutePath();
}
}
public override Uri RequestUri {
get {
return _request.RequestUri;
}
}
public override string SecWebSocketKey {
get {
return Headers["Sec-WebSocket-Key"];
}
}
public override IEnumerable<string> SecWebSocketProtocols {
get {
return Headers.GetValues("Sec-WebSocket-Protocol");
}
}
public override string SecWebSocketVersion {
get {
return Headers["Sec-WebSocket-Version"];
}
}
public virtual IPEndPoint ServerEndPoint {
get {
return (IPEndPoint)_client.Client.LocalEndPoint;
}
}
public override IPrincipal User {
get {
throw new NotImplementedException();
}
}
public virtual IPEndPoint UserEndPoint {
get {
return (IPEndPoint)_client.Client.RemoteEndPoint;
}
}
public override WebSocket WebSocket {
get {
return _socket;
}
}
}
}

View File

@ -35,6 +35,12 @@ namespace WebSocketSharp {
public class RequestHandshake : Handshake
{
#region Private Field
private NameValueCollection _queryString;
#endregion
#region Private Constructor
private RequestHandshake()
@ -43,7 +49,6 @@ namespace WebSocketSharp {
#endregion
#region Public Constructor
public RequestHandshake(string uriString)
@ -59,7 +64,7 @@ namespace WebSocketSharp {
#region Properties
public string HttpMethod { get; internal set; }
public string HttpMethod { get; private set; }
public bool IsWebSocketRequest {
@ -89,7 +94,44 @@ namespace WebSocketSharp {
}
}
public Uri RequestUri { get; internal set; }
public NameValueCollection QueryString {
get {
if (_queryString == null)
{
_queryString = new NameValueCollection();
var i = RawUrl.IndexOf('?');
if (i > 0)
{
var query = RawUrl.Substring(i + 1);
var components = query.Split('&');
foreach (var c in components)
{
var nv = c.GetNameAndValue("=");
if (nv.Key != null)
{
var name = nv.Key.UrlDecode();
var val = nv.Value.UrlDecode();
_queryString.Add(name, val);
}
}
}
}
return _queryString;
}
}
public string RawUrl {
get {
if (RequestUri.IsAbsoluteUri)
return RequestUri.PathAndQuery;
return RequestUri.OriginalString;
}
}
public Uri RequestUri { get; private set; }
#endregion
@ -109,7 +151,10 @@ namespace WebSocketSharp {
{
var requestLine = request[0].Split(' ');
if (requestLine.Length != 3)
throw new ArgumentException("Invalid request line.");
{
var msg = "Invalid HTTP Request-Line: " + request[0];
throw new ArgumentException(msg, "request");
}
var headers = new WebHeaderCollection();
for (int i = 1; i < request.Length; i++)
@ -130,14 +175,11 @@ namespace WebSocketSharp {
public override string ToString()
{
var buffer = new StringBuilder();
buffer.AppendFormat("{0} {1} HTTP/{2}{3}", HttpMethod, RequestUri, ProtocolVersion, _crlf);
buffer.AppendFormat("{0} {1} HTTP/{2}{3}", HttpMethod, RawUrl, ProtocolVersion, _crlf);
foreach (string key in Headers.AllKeys)
buffer.AppendFormat("{0}: {1}{2}", key, Headers[key], _crlf);
buffer.Append(_crlf);
return buffer.ToString();
}

View File

@ -29,6 +29,7 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Threading;
using WebSocketSharp.Net;
@ -95,7 +96,7 @@ namespace WebSocketSharp.Server {
try
{
var context = _listener.GetContext();
respond(context);
respondAsync(context);
}
catch (HttpListenerException)
{
@ -104,7 +105,7 @@ namespace WebSocketSharp.Server {
}
catch (Exception ex)
{
OnError.Emit(this, new ErrorEventArgs(ex.Message));
onError(ex.Message);
break;
}
}
@ -143,36 +144,17 @@ namespace WebSocketSharp.Server {
return true;
}
private void respond(HttpListenerContext context)
private void onError(string message)
{
WaitCallback respondCb = (state) =>
{
var req = context.Request;
var res = context.Response;
try
{
if (isUpgrade(req, "websocket"))
{
if (upgradeToWebSocket(context))
return;
}
else
{
respondToClient(context);
}
res.Close();
}
catch (Exception ex)
{
OnError.Emit(this, new ErrorEventArgs(ex.Message));
}
};
ThreadPool.QueueUserWorkItem(respondCb);
#if DEBUG
var callerFrame = new StackFrame(1);
var caller = callerFrame.GetMethod();
Console.WriteLine("HTTPSV: Error@{0}: {1}", caller.Name, message);
#endif
OnError.Emit(this, new ErrorEventArgs(message));
}
private void respondToClient(HttpListenerContext context)
private void respond(HttpListenerContext context)
{
var req = context.Request;
var res = context.Response;
@ -235,6 +217,36 @@ namespace WebSocketSharp.Server {
res.StatusCode = (int)HttpStatusCode.NotImplemented;
}
private void respondAsync(HttpListenerContext context)
{
WaitCallback respondCb = (state) =>
{
var req = context.Request;
var res = context.Response;
try
{
if (isUpgrade(req, "websocket"))
{
if (upgradeToWebSocket(context))
return;
}
else
{
respond(context);
}
res.Close();
}
catch (Exception ex)
{
onError(ex.Message);
}
};
ThreadPool.QueueUserWorkItem(respondCb);
}
private void startAcceptRequestThread()
{
_acceptRequestThread = new Thread(new ThreadStart(acceptRequest));
@ -244,19 +256,17 @@ namespace WebSocketSharp.Server {
private bool upgradeToWebSocket(HttpListenerContext context)
{
var req = context.Request;
var res = context.Response;
var path = req.RawUrl;
var res = context.Response;
var wsContext = context.AcceptWebSocket();
var path = wsContext.Path.UrlDecode();
if (!_services.ContainsKey(path))
{
res.StatusCode = (int)HttpStatusCode.NotImplemented;
return false;
}
var wsContext = context.AcceptWebSocket(path);
var socket = wsContext.WebSocket;
var service = _services[path];
var socket = wsContext.WebSocket;
var service = _services[path];
service.BindWebSocket(socket);
return true;
@ -266,11 +276,18 @@ namespace WebSocketSharp.Server {
#region Public Methods
public void AddService<T>(string path)
public void AddService<T>(string absPath)
where T : WebSocketService, new()
{
string msg;
if (!absPath.IsValidAbsolutePath(out msg))
{
onError(msg);
return;
}
var service = new WebSocketServer<T>();
_services.Add(path, service);
_services.Add(absPath, service);
}
public byte[] GetFile(string path)

View File

@ -52,7 +52,33 @@ namespace WebSocketSharp.Server {
}
public WebSocketServer(int port)
: base(System.Net.IPAddress.Any, port)
: this(System.Net.IPAddress.Any, port)
{
}
public WebSocketServer(string url)
: base(url)
{
if (BaseUri.AbsolutePath != "/")
{
var msg = "Must not contain the path component: " + url;
throw new ArgumentException(msg, "url");
}
init();
}
public WebSocketServer(System.Net.IPAddress address, int port)
: base(address, port)
{
init();
}
#endregion
#region Private Method
private void init()
{
_services = new Dictionary<string, IServiceHost>();
}
@ -61,17 +87,20 @@ namespace WebSocketSharp.Server {
#region Protected Method
protected override void bindSocket(TcpClient client)
protected override void AcceptWebSocket(TcpClient client)
{
var context = client.AcceptWebSocket();
var socket = context.WebSocket;
var path = context.RequestUri.ToString();
var path = context.Path.UrlDecode();
if (!_services.ContainsKey(path))
{
socket.Close(HttpStatusCode.NotImplemented);
return;
}
if (BaseUri.IsAbsoluteUri)
socket.Url = new Uri(BaseUri, path);
var service = _services[path];
service.BindWebSocket(socket);
}
@ -80,11 +109,18 @@ namespace WebSocketSharp.Server {
#region Public Methods
public void AddService<T>(string path)
public void AddService<T>(string absPath)
where T : WebSocketService, new()
{
string msg;
if (!absPath.IsValidAbsolutePath(out msg))
{
Error(msg);
return;
}
var service = new WebSocketServer<T>();
_services.Add(path, service);
_services.Add(absPath, service);
}
public override void Stop()
@ -104,7 +140,6 @@ namespace WebSocketSharp.Server {
#region Fields
private SessionManager _sessions;
private Uri _uri;
#endregion
@ -119,29 +154,25 @@ namespace WebSocketSharp.Server {
#region Public Constructors
public WebSocketServer(string url)
: base(url)
{
_uri = url.ToUri();
init();
}
public WebSocketServer(int port)
: this(port, "/")
{
}
public WebSocketServer(int port, string path)
: base(System.Net.IPAddress.Any, port)
public WebSocketServer(string url)
: base(url)
{
var uri = path.ToUri();
if (uri.IsAbsoluteUri)
{
var msg = "Not absolute path: " + path;
throw new ArgumentException(msg, "path");
}
init();
}
_uri = uri;
public WebSocketServer(int port, string absPath)
: this(System.Net.IPAddress.Any, port, absPath)
{
}
public WebSocketServer(System.Net.IPAddress address, int port, string absPath)
: base(address, port, absPath)
{
init();
}
@ -149,9 +180,10 @@ namespace WebSocketSharp.Server {
#region Property
public Uri Uri
{
get { return _uri; }
public Uri Uri {
get {
return BaseUri;
}
}
#endregion
@ -167,9 +199,20 @@ namespace WebSocketSharp.Server {
#region Protected Method
protected override void bindSocket(TcpClient client)
protected override void AcceptWebSocket(TcpClient client)
{
var socket = new WebSocket(_uri, client);
var context = client.AcceptWebSocket();
var socket = context.WebSocket;
var path = context.Path.UrlDecode();
if (path != Uri.GetAbsolutePath().UrlDecode())
{
socket.Close(HttpStatusCode.NotImplemented);
return;
}
if (Uri.IsAbsoluteUri)
socket.Url = new Uri(Uri, path);
BindWebSocket(socket);
}

View File

@ -34,8 +34,8 @@ using System.Threading;
namespace WebSocketSharp.Server {
public abstract class WebSocketServerBase
{
public abstract class WebSocketServerBase {
#region Fields
private Thread _acceptClientThread;
@ -43,6 +43,7 @@ namespace WebSocketSharp.Server {
private bool _isSelfHost;
private int _port;
private TcpListener _tcpListener;
private Uri _uri;
#endregion
@ -55,31 +56,72 @@ namespace WebSocketSharp.Server {
protected WebSocketServerBase(string url)
{
init(url);
if (url.IsNull())
throw new ArgumentNullException("url");
Uri uri;
string msg;
if (!tryCreateUri(url, out uri, out msg))
throw new ArgumentException(msg, "url");
init(uri);
}
protected WebSocketServerBase(IPAddress address, int port)
: this(address, port, "/")
{
}
protected WebSocketServerBase(IPAddress address, int port, string absPath)
{
if (address.IsNull())
throw new ArgumentNullException("address");
if (absPath.IsNull())
throw new ArgumentNullException("absPath");
string msg;
if (!absPath.IsValidAbsolutePath(out msg))
throw new ArgumentException(msg, "absPath");
_address = address;
_port = port <= 0 ? 80 : port;
_uri = absPath.ToUri();
init();
}
#endregion
#region Property
#region Protected Property
protected Uri BaseUri
{
get {
return _uri;
}
}
#endregion
#region Public Properties
public IPAddress Address {
get { return _address; }
get {
return _address;
}
}
public bool IsSelfHost {
get { return _isSelfHost; }
get {
return _isSelfHost;
}
}
public int Port {
get { return _port; }
get {
return _port;
}
}
#endregion
@ -99,7 +141,7 @@ namespace WebSocketSharp.Server {
try
{
var client = _tcpListener.AcceptTcpClient();
acceptSocket(client);
acceptSocketAsync(client);
}
catch (SocketException)
{
@ -108,36 +150,27 @@ namespace WebSocketSharp.Server {
}
catch (Exception ex)
{
error(ex.Message);
onError(ex.Message);
break;
}
}
}
private void acceptSocket(TcpClient client)
private void acceptSocketAsync(TcpClient client)
{
WaitCallback acceptSocketCb = (state) =>
{
try
{
bindSocket(client);
AcceptWebSocket(client);
}
catch (Exception ex)
{
error(ex.Message);
onError(ex.Message);
}
};
ThreadPool.QueueUserWorkItem(acceptSocketCb);
}
private void error(string message)
{
#if DEBUG
var callerFrame = new StackFrame(1);
var caller = callerFrame.GetMethod();
Console.WriteLine("WSSV: Error@{0}: {1}", caller.Name, message);
#endif
OnError.Emit(this, new ErrorEventArgs(message));
ThreadPool.QueueUserWorkItem(acceptSocketCb);
}
private void init()
@ -146,14 +179,9 @@ namespace WebSocketSharp.Server {
_isSelfHost = true;
}
private void init(string url)
private void init(Uri uri)
{
var uri = url.ToUri();
string msg;
if (!uri.IsValidWebSocketUri(out msg))
throw new ArgumentException(msg, "url");
_uri = uri;
var scheme = uri.Scheme;
var port = uri.Port;
var host = uri.DnsSafeHost;
@ -168,6 +196,16 @@ namespace WebSocketSharp.Server {
init();
}
private void onError(string message)
{
#if DEBUG
var callerFrame = new StackFrame(1);
var caller = callerFrame.GetMethod();
Console.WriteLine("WSSV: Error@{0}: {1}", caller.Name, message);
#endif
OnError.Emit(this, new ErrorEventArgs(message));
}
private void startAcceptClientThread()
{
_acceptClientThread = new Thread(new ThreadStart(acceptClient));
@ -175,11 +213,31 @@ namespace WebSocketSharp.Server {
_acceptClientThread.Start();
}
private bool tryCreateUri(string uriString, out Uri result, out string message)
{
if (!uriString.TryCreateWebSocketUri(out result, out message))
return false;
if (!result.Query.IsNullOrEmpty())
{
result = null;
message = "Must not contain the query component: " + uriString;
return false;
}
return true;
}
#endregion
#region Protected Method
protected abstract void bindSocket(TcpClient client);
protected abstract void AcceptWebSocket(TcpClient client);
protected virtual void Error(string message)
{
onError(message);
}
#endregion

View File

@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading;
using WebSocketSharp.Frame;
@ -53,9 +54,15 @@ namespace WebSocketSharp.Server
#endregion
#region Protected Property
#region Protected Properties
protected SessionManager sessions {
protected NameValueCollection QueryString {
get {
return _socket.QueryString;
}
}
protected SessionManager Sessions {
get {
return _sessions;
}
@ -91,19 +98,19 @@ namespace WebSocketSharp.Server
#region Protected Methods
protected virtual void onOpen(object sender, EventArgs e)
protected virtual void OnClose(object sender, CloseEventArgs e)
{
}
protected virtual void onMessage(object sender, MessageEventArgs e)
protected virtual void OnError(object sender, ErrorEventArgs e)
{
}
protected virtual void onError(object sender, ErrorEventArgs e)
protected virtual void OnMessage(object sender, MessageEventArgs e)
{
}
protected virtual void onClose(object sender, CloseEventArgs e)
protected virtual void OnOpen(object sender, EventArgs e)
{
}
@ -117,10 +124,10 @@ namespace WebSocketSharp.Server
_sessions = sessions;
defaultBind();
_socket.OnOpen += onOpen;
_socket.OnMessage += onMessage;
_socket.OnError += onError;
_socket.OnClose += onClose;
_socket.OnOpen += OnOpen;
_socket.OnMessage += OnMessage;
_socket.OnError += OnError;
_socket.OnClose += OnClose;
IsBound = true;
}

View File

@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
@ -75,6 +76,7 @@ namespace WebSocketSharp {
private bool _isSecure;
private string _protocol;
private string _protocols;
private NameValueCollection _queryString;
private volatile WsState _readyState;
private AutoResetEvent _receivePong;
private TcpClient _tcpClient;
@ -100,39 +102,28 @@ namespace WebSocketSharp {
#region Internal Constructor
internal WebSocket(TcpListenerWebSocketContext context)
internal WebSocket(HttpListenerWebSocketContext context)
: this()
{
_uri = context.RequestUri;
_context = context;
_tcpClient = context.Client;
_wsStream = context.Stream;
_endPoint = (System.Net.IPEndPoint)_tcpClient.Client.LocalEndPoint;
_isClient = false;
_isSecure = context.IsSecureConnection;
}
internal WebSocket(Uri uri, HttpListenerWebSocketContext context)
: this()
{
_uri = uri;
_uri = context.Path.ToUri();
_context = context;
_baseContext = context.BaseContext;
_wsStream = context.Stream;
_endPoint = _baseContext.Connection.LocalEndPoint;
_endPoint = context.ServerEndPoint;
_isClient = false;
_isSecure = context.IsSecureConnection;
}
internal WebSocket(Uri uri, TcpClient tcpClient)
internal WebSocket(TcpListenerWebSocketContext context)
: this()
{
_uri = uri;
_tcpClient = tcpClient;
_wsStream = WsStream.CreateServerStream(tcpClient);
_endPoint = (System.Net.IPEndPoint)tcpClient.Client.LocalEndPoint;
_uri = context.Path.ToUri();
_context = context;
_tcpClient = context.Client;
_wsStream = context.Stream;
_endPoint = context.ServerEndPoint;
_isClient = false;
_isSecure = _wsStream.IsSecure;
_isSecure = context.IsSecureConnection;
}
#endregion
@ -157,16 +148,18 @@ namespace WebSocketSharp {
public WebSocket(string url, params string[] protocols)
: this()
{
if (url == null)
if (url.IsNull())
throw new ArgumentNullException("url");
Uri uri;
string msg;
if (!isValidUrl(url, out msg))
if (!tryCreateUri(url, out uri, out msg))
throw new ArgumentException(msg, "url");
_uri = uri;
_protocols = protocols.ToString(", ");
_isClient = true;
_isSecure = _uri.Scheme == "wss" ? true : false;
_isSecure = uri.Scheme == "wss" ? true : false;
}
/// <summary>
@ -215,7 +208,17 @@ namespace WebSocketSharp {
#endregion
#region Properties
#region Internal Property
internal NameValueCollection QueryString {
get {
return _queryString;
}
}
#endregion
#region Public Properties
/// <summary>
/// Gets the amount of untransmitted data.
@ -320,10 +323,8 @@ namespace WebSocketSharp {
public Uri Url {
get { return _uri; }
set {
if (_readyState != WsState.CONNECTING || _isClient)
return;
_uri = value;
if (_readyState == WsState.CONNECTING && !_isClient)
_uri = value;
}
}
@ -355,6 +356,7 @@ namespace WebSocketSharp {
#region Private Methods
// As Server
private void acceptHandshake()
{
var req = receiveOpeningHandshake();
@ -439,7 +441,7 @@ namespace WebSocketSharp {
private void close(ushort code, string reason)
{
var data = new List<byte>(code.ToBytes(ByteOrder.BIG));
if (!String.IsNullOrEmpty(reason))
if (!reason.IsNullOrEmpty())
{
var buffer = Encoding.UTF8.GetBytes(reason);
data.AddRange(buffer);
@ -462,20 +464,20 @@ namespace WebSocketSharp {
try
{
if (_baseContext != null)
if (!_baseContext.IsNull())
{
_baseContext.Response.Close();
_wsStream = null;
_baseContext = null;
}
if (_wsStream != null)
if (!_wsStream.IsNull())
{
_wsStream.Dispose();
_wsStream = null;
}
if (_tcpClient != null)
if (!_tcpClient.IsNull())
{
_tcpClient.Close();
_tcpClient = null;
@ -495,12 +497,13 @@ namespace WebSocketSharp {
var args = new CloseEventArgs(data);
var frame = createFrame(Fin.FINAL, Opcode.CLOSE, data);
if (send(frame) && !Thread.CurrentThread.IsBackground)
if (_exitMessageLoop != null)
if (!_exitMessageLoop.IsNull())
_exitMessageLoop.WaitOne(5 * 1000);
onClose(args);
}
// As Client
private void createClientStream()
{
var host = _uri.DnsSafeHost;
@ -529,6 +532,7 @@ namespace WebSocketSharp {
: new WsFrame(fin, opcode, Mask.UNMASK, payloadData);
}
// As Client
private RequestHandshake createOpeningHandshake()
{
var path = _uri.PathAndQuery;
@ -545,13 +549,14 @@ namespace WebSocketSharp {
var req = new RequestHandshake(path);
req.AddHeader("Host", host);
req.AddHeader("Sec-WebSocket-Key", _base64key);
if (!String.IsNullOrEmpty(_protocols))
if (!_protocols.IsNullOrEmpty())
req.AddHeader("Sec-WebSocket-Protocol", _protocols);
req.AddHeader("Sec-WebSocket-Version", _version);
return req;
}
// As Server
private ResponseHandshake createResponseHandshake()
{
var res = new ResponseHandshake();
@ -560,6 +565,7 @@ namespace WebSocketSharp {
return res;
}
// As Server
private ResponseHandshake createResponseHandshake(HttpStatusCode code)
{
var res = ResponseHandshake.CreateCloseResponse(code);
@ -568,6 +574,7 @@ namespace WebSocketSharp {
return res;
}
// As Client
private void doHandshake()
{
var res = sendOpeningHandshake();
@ -601,6 +608,7 @@ namespace WebSocketSharp {
return true;
}
// As Server
private bool isValidRequest(RequestHandshake request, out string message)
{
Func<string, Func<string, string, string>> func = s =>
@ -617,9 +625,6 @@ namespace WebSocketSharp {
return false;
}
if (!isValidRequestUri(request.RequestUri, func("Request URI"), out message))
return false;
if (_uri.IsAbsoluteUri)
if (!isValidRequestHost(request.GetHeaderValues("Host")[0], func("Host"), out message))
return false;
@ -638,10 +643,13 @@ namespace WebSocketSharp {
if (request.HeaderExists("Sec-WebSocket-Extensions"))
_extensions = request.Headers["Sec-WebSocket-Extensions"];
_queryString = request.QueryString;
message = String.Empty;
return true;
}
// As Server
private bool isValidRequestHost(string value, Func<string, string, string> func, out string message)
{
var host = _uri.DnsSafeHost;
@ -669,28 +677,7 @@ namespace WebSocketSharp {
return true;
}
private bool isValidRequestUri(Uri requestUri, Func<string, string, string> func, out string message)
{
if (_uri.IsAbsoluteUri && requestUri.IsAbsoluteUri)
if (_uri.ToString().NotEqualsDo(requestUri.ToString(), func, out message, false))
return false;
if (_uri.IsAbsoluteUri && !requestUri.IsAbsoluteUri)
if (_uri.PathAndQuery.NotEqualsDo(requestUri.ToString(), func, out message, false))
return false;
if (!_uri.IsAbsoluteUri && requestUri.IsAbsoluteUri)
if (_uri.ToString().NotEqualsDo(requestUri.PathAndQuery, func, out message, false))
return false;
if (!_uri.IsAbsoluteUri && !requestUri.IsAbsoluteUri)
if (_uri.ToString().NotEqualsDo(requestUri.ToString(), func, out message, false))
return false;
message = String.Empty;
return true;
}
// As Client
private bool isValidResponse(ResponseHandshake response, out string message)
{
if (!response.IsWebSocketResponse)
@ -724,24 +711,6 @@ namespace WebSocketSharp {
return true;
}
private bool isValidUrl(string url, out string message)
{
if (url == String.Empty)
{
message = "'url' is empty.";
return false;
}
var uri = url.ToUri();
if (!uri.IsValidWebSocketUri(out message))
return false;
_uri = uri;
message = String.Empty;
return true;
}
private void message()
{
try
@ -791,7 +760,7 @@ namespace WebSocketSharp {
private void onMessage(MessageEventArgs eventArgs)
{
if (eventArgs != null)
if (!eventArgs.IsNull())
OnMessage.Emit(this, eventArgs);
}
@ -802,9 +771,9 @@ namespace WebSocketSharp {
OnOpen.Emit(this, EventArgs.Empty);
}
private bool ping(string data, int millisecondsTimeout)
private bool ping(string message, int millisecondsTimeout)
{
var buffer = Encoding.UTF8.GetBytes(data);
var buffer = Encoding.UTF8.GetBytes(message);
if (buffer.Length > 125)
{
var msg = "Ping frame must have a payload length of 125 bytes or less.";
@ -833,7 +802,7 @@ namespace WebSocketSharp {
private WsFrame readFrame()
{
var frame = _wsStream.ReadFrame();
if (frame == null)
if (frame.IsNull())
{
var msg = "WebSocket data frame can not be read from network stream.";
close(CloseStatusCode.ABNORMAL, msg);
@ -862,7 +831,7 @@ namespace WebSocketSharp {
private MessageEventArgs receive()
{
var frame = _isClient ? readFrame() : readFrameWithTimeout(1 * 100);
if (frame == null)
if (frame.IsNull())
return null;
if ((frame.Fin == Fin.FINAL && frame.Opcode == Opcode.CONT) ||
@ -872,7 +841,7 @@ namespace WebSocketSharp {
if (frame.Fin == Fin.MORE)
{// MORE
var merged = receiveFragmented(frame);
if (merged == null)
if (merged.IsNull())
return null;
return new MessageEventArgs(frame.Opcode, new PayloadData(merged));
@ -912,7 +881,7 @@ namespace WebSocketSharp {
while (true)
{
var frame = readFrame();
if (frame == null)
if (frame.IsNull())
return null;
if (frame.Fin == Fin.MORE)
@ -972,11 +941,10 @@ namespace WebSocketSharp {
return buffer.ToArray();
}
// As Server
private RequestHandshake receiveOpeningHandshake()
{
var req = _context != null
? RequestHandshake.Parse(_context)
: RequestHandshake.Parse(readHandshake());
var req = RequestHandshake.Parse(_context);
#if DEBUG
Console.WriteLine("WS: Info@receiveOpeningHandshake: Opening handshake from client:\n");
Console.WriteLine(req.ToString());
@ -984,6 +952,7 @@ namespace WebSocketSharp {
return req;
}
// As Client
private ResponseHandshake receiveResponseHandshake()
{
var res = ResponseHandshake.Parse(readHandshake());
@ -1008,7 +977,7 @@ namespace WebSocketSharp {
{
if (_unTransmittedBuffer.Count == 0)
{
if (_wsStream != null)
if (!_wsStream.IsNull())
{
_wsStream.WriteFrame(frame);
return true;
@ -1097,13 +1066,16 @@ namespace WebSocketSharp {
return readLen;
}
// As Client
private ResponseHandshake sendOpeningHandshake()
{
var req = createOpeningHandshake();
sendOpeningHandshake(req);
return receiveResponseHandshake();
}
// As Client
private void sendOpeningHandshake(RequestHandshake request)
{
#if DEBUG
@ -1113,18 +1085,21 @@ namespace WebSocketSharp {
writeHandshake(request);
}
// As Server
private void sendResponseHandshake()
{
var res = createResponseHandshake();
sendResponseHandshake(res);
}
// As Server
private void sendResponseHandshake(HttpStatusCode code)
{
var res = createResponseHandshake(code);
sendResponseHandshake(res);
}
// As Server
private void sendResponseHandshake(ResponseHandshake response)
{
#if DEBUG
@ -1147,6 +1122,11 @@ namespace WebSocketSharp {
messageInvoker.BeginInvoke(messageLoopCallback, messageInvoker);
}
private bool tryCreateUri(string uriString, out Uri result, out string message)
{
return uriString.TryCreateWebSocketUri(out result, out message);
}
private void writeHandshake(Handshake handshake)
{
_wsStream.WriteHandshake(handshake);
@ -1156,6 +1136,7 @@ namespace WebSocketSharp {
#region Internal Method
// As Server
internal void Close(HttpStatusCode code)
{
close(code);
@ -1290,15 +1271,18 @@ namespace WebSocketSharp {
/// <summary>
/// Sends a Ping frame with a message using the connection.
/// </summary>
/// <param name="data">
/// A <see cref="string"/> that contains the message data to be sent.
/// <param name="message">
/// A <see cref="string"/> that contains the message to be sent.
/// </param>
/// <returns>
/// <c>true</c> if the WebSocket receives a Pong frame in a time; otherwise, <c>false</c>.
/// </returns>
public bool Ping(string data)
public bool Ping(string message)
{
return ping(data, 5 * 1000);
if (message.IsNull())
message = String.Empty;
return ping(message, 5 * 1000);
}
/// <summary>
@ -1309,6 +1293,12 @@ namespace WebSocketSharp {
/// </param>
public void Send(string data)
{
if (data.IsNull())
{
onError("'data' must not be null.");
return;
}
var buffer = Encoding.UTF8.GetBytes(data);
send(Opcode.TEXT, buffer);
}
@ -1321,6 +1311,12 @@ namespace WebSocketSharp {
/// </param>
public void Send(byte[] data)
{
if (data.IsNull())
{
onError("'data' must not be null.");
return;
}
send(Opcode.BINARY, data);
}
@ -1332,6 +1328,12 @@ namespace WebSocketSharp {
/// </param>
public void Send(FileInfo file)
{
if (file.IsNull())
{
onError("'file' must not be null.");
return;
}
using (FileStream fs = file.OpenRead())
{
send(Opcode.BINARY, fs);

Binary file not shown.