diff --git a/websocket-sharp/Server/WebSocketService.cs b/websocket-sharp/Server/WebSocketService.cs
index 04c15e77..92633f12 100644
--- a/websocket-sharp/Server/WebSocketService.cs
+++ b/websocket-sharp/Server/WebSocketService.cs
@@ -29,6 +29,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+using System.IO;
using System.Text;
using System.Threading;
using WebSocketSharp.Net;
@@ -225,6 +226,11 @@ namespace WebSocketSharp.Server
IsBound = true;
}
+ internal void Start ()
+ {
+ _websocket.Connect ();
+ }
+
#endregion
#region Protected Methods
@@ -235,7 +241,7 @@ namespace WebSocketSharp.Server
///
/// A that contains an error message.
///
- protected virtual void Error (string message)
+ protected void Error (string message)
{
if (!message.IsNullOrEmpty ())
OnError (new ErrorEventArgs (message));
@@ -282,33 +288,6 @@ namespace WebSocketSharp.Server
{
}
- ///
- /// Validates the cookies used in the WebSocket connection request.
- ///
- ///
- /// This method is called when the inner validates
- /// the WebSocket connection request.
- ///
- ///
- /// true if the cookies is valid; otherwise, false.
- /// The default returns true.
- ///
- ///
- /// A that contains a collection of the HTTP Cookies
- /// to validate.
- ///
- ///
- /// A that receives the HTTP Cookies to send to the client.
- ///
- protected virtual bool ValidateCookies (CookieCollection request, CookieCollection response)
- {
- return true;
- }
-
- #endregion
-
- #region Public Methods
-
///
/// Sends a Ping to the client of the current instance.
///
@@ -316,7 +295,7 @@ namespace WebSocketSharp.Server
/// true if the current instance receives a Pong
/// from the client in a time; otherwise, false.
///
- public bool Ping ()
+ protected bool Ping ()
{
return IsBound
? _websocket.Ping ()
@@ -334,7 +313,7 @@ namespace WebSocketSharp.Server
///
/// A that contains a message to send.
///
- public bool Ping (string message)
+ protected bool Ping (string message)
{
return IsBound
? _websocket.Ping (message)
@@ -345,75 +324,172 @@ namespace WebSocketSharp.Server
/// Sends a binary to the client of the current
/// instance.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// An array of that contains a binary data to send.
///
- public virtual void Send (byte [] data)
+ protected void Send (byte [] data)
{
if (IsBound)
- _websocket.Send (data);
+ _websocket.Send (data, null);
}
///
/// Sends a text to the client of the current
/// instance.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// A that contains a text data to send.
///
- public virtual void Send (string data)
+ protected void Send (string data)
{
if (IsBound)
- _websocket.Send (data);
+ _websocket.Send (data, null);
+ }
+
+ ///
+ /// Sends a binary data from the specified to
+ /// the client of the current instance.
+ ///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
+ ///
+ /// A from which contains a binary data to send.
+ ///
+ protected void Send (FileInfo file)
+ {
+ if (IsBound)
+ _websocket.Send (file, null);
}
///
/// Sends a binary to the client of the current
- /// instance asynchronously.
+ /// instance.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// An array of that contains a binary data to send.
///
///
- /// An delegate that references the method(s) called when
- /// the asynchronous operation completes.
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is
+ /// complete successfully; otherwise, false.
///
- public virtual void SendAsync (byte [] data, Action completed)
+ protected void Send (byte [] data, Action completed)
{
if (IsBound)
- _websocket.SendAsync (data, completed);
+ _websocket.Send (data, completed);
}
///
/// Sends a text to the client of the current
- /// instance asynchronously.
+ /// instance.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// A that contains a text data to send.
///
///
- /// An delegate that references the method(s) called when
- /// the asynchronous operation completes.
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is
+ /// complete successfully; otherwise, false.
+ ///
+ protected void Send (string data, Action completed)
+ {
+ if (IsBound)
+ _websocket.Send (data, completed);
+ }
+
+ ///
+ /// Sends a binary data from the specified to
+ /// the client of the current instance.
+ ///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
+ ///
+ /// A from which contains a binary data to send.
+ ///
+ ///
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is
+ /// complete successfully; otherwise, false.
///
- public virtual void SendAsync (string data, Action completed)
+ protected void Send (FileInfo file, Action completed)
{
if (IsBound)
- _websocket.SendAsync (data, completed);
+ _websocket.Send (file, completed);
}
///
- /// Starts the current instance.
+ /// Sends a binary data from the specified to
+ /// the client of the current instance.
///
- public void Start ()
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
+ ///
+ /// A object from which contains a binary data to send.
+ ///
+ ///
+ /// An that contains the number of bytes to send.
+ ///
+ ///
+ /// true if is disposed after a binary data read;
+ /// otherwise, false.
+ ///
+ protected void Send (Stream stream, int length, bool dispose)
+ {
+ if (IsBound)
+ _websocket.Send (stream, length, dispose, null);
+ }
+
+ ///
+ /// Sends a binary data from the specified to
+ /// the client of the current instance.
+ ///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
+ ///
+ /// A object from which contains a binary data to send.
+ ///
+ ///
+ /// An that contains the number of bytes to send.
+ ///
+ ///
+ /// true if is disposed after a binary data read;
+ /// otherwise, false.
+ ///
+ ///
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is
+ /// complete successfully; otherwise, false.
+ ///
+ protected void Send (Stream stream, int length, bool dispose, Action completed)
{
if (IsBound)
- _websocket.Connect ();
+ _websocket.Send (stream, length, dispose, completed);
}
///
/// Stops the current instance.
///
- public void Stop ()
+ protected void Stop ()
{
if (IsBound)
_websocket.Close ();
@@ -429,7 +505,7 @@ namespace WebSocketSharp.Server
///
/// A that contains the reason for stop.
///
- public void Stop (ushort code, string reason)
+ protected void Stop (ushort code, string reason)
{
if (IsBound)
_websocket.Close (code, reason);
@@ -446,12 +522,35 @@ namespace WebSocketSharp.Server
///
/// A that contains the reason for stop.
///
- public void Stop (CloseStatusCode code, string reason)
+ protected void Stop (CloseStatusCode code, string reason)
{
if (IsBound)
_websocket.Close (code, reason);
}
+ ///
+ /// Validates the cookies used in the WebSocket connection request.
+ ///
+ ///
+ /// This method is called when the inner validates
+ /// the WebSocket connection request.
+ ///
+ ///
+ /// true if the cookies is valid; otherwise, false.
+ /// The default returns true.
+ ///
+ ///
+ /// A that contains a collection of the HTTP Cookies
+ /// to validate.
+ ///
+ ///
+ /// A that receives the HTTP Cookies to send to the client.
+ ///
+ protected virtual bool ValidateCookies (CookieCollection request, CookieCollection response)
+ {
+ return true;
+ }
+
#endregion
}
}
diff --git a/websocket-sharp/Server/WebSocketSessionManager.cs b/websocket-sharp/Server/WebSocketSessionManager.cs
index ac4f5afb..d8273d80 100644
--- a/websocket-sharp/Server/WebSocketSessionManager.cs
+++ b/websocket-sharp/Server/WebSocketSessionManager.cs
@@ -649,14 +649,14 @@ namespace WebSocketSharp.Server
return;
}
- WebSocketService service;
- if (!TryGetServiceInstance (id, out service))
+ WebSocketService session;
+ if (!TryGetServiceInstance (id, out session))
{
_logger.Error ("The WebSocket session with the specified ID not found.\nID: " + id);
return;
}
- service.Send (data);
+ session.Context.WebSocket.Send (data, null);
}
///
@@ -678,14 +678,14 @@ namespace WebSocketSharp.Server
return;
}
- WebSocketService service;
- if (!TryGetServiceInstance (id, out service))
+ WebSocketService session;
+ if (!TryGetServiceInstance (id, out session))
{
_logger.Error ("The WebSocket session with the specified ID not found.\nID: " + id);
return;
}
- service.Send (data);
+ session.Context.WebSocket.Send (data, null);
}
///
diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs
index a8c075d9..d0765bd4 100644
--- a/websocket-sharp/WebSocket.cs
+++ b/websocket-sharp/WebSocket.cs
@@ -1028,65 +1028,72 @@ namespace WebSocketSharp
return _stream.Write (frame.ToByteArray ());
}
- private void send (Opcode opcode, byte [] data)
+ private bool send (Opcode opcode, byte [] data)
{
lock (_forSend)
{
+ var sent = false;
try {
- var comped = false;
+ var compressed = false;
if (_compression != CompressionMethod.NONE)
{
data = data.Compress (_compression);
- comped = true;
+ compressed = true;
}
-
- send (WsFrame.CreateFrame (
- Fin.FINAL, opcode, _client ? Mask.MASK : Mask.UNMASK, data, comped));
+
+ sent = send (WsFrame.CreateFrame (
+ Fin.FINAL, opcode, _client ? Mask.MASK : Mask.UNMASK, data, compressed));
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
error ("An exception has occured.");
}
+
+ return sent;
}
}
- private void send (Opcode opcode, Stream stream)
+ private bool send (Opcode opcode, Stream stream)
{
lock (_forSend)
{
- var comp = stream;
- var comped = false;
+ var sent = false;
+
+ var src = stream;
+ var compressed = false;
try {
if (_compression != CompressionMethod.NONE)
{
- comp = stream.Compress (_compression);
- comped = true;
+ stream = stream.Compress (_compression);
+ compressed = true;
}
- sendFragmented (opcode, comp, _client ? Mask.MASK : Mask.UNMASK, comped);
+ sent = sendFragmented (opcode, stream, _client ? Mask.MASK : Mask.UNMASK, compressed);
}
catch (Exception ex) {
_logger.Fatal (ex.ToString ());
error ("An exception has occured.");
}
finally {
- if (comped)
- comp.Dispose ();
+ if (compressed)
+ stream.Dispose ();
- stream.Dispose ();
+ src.Dispose ();
}
+
+ return sent;
}
}
- private void sendAsync (Opcode opcode, byte [] data, Action completed)
+ private void send (Opcode opcode, byte [] data, Action completed)
{
- Action sender = send;
+ Func sender = send;
AsyncCallback callback = ar =>
{
try {
- sender.EndInvoke (ar);
+ var sent = sender.EndInvoke (ar);
if (completed != null)
- completed ();
+ completed (sent);
}
catch (Exception ex)
{
@@ -1098,15 +1105,15 @@ namespace WebSocketSharp
sender.BeginInvoke (opcode, data, callback, null);
}
- private void sendAsync (Opcode opcode, Stream stream, Action completed)
+ private void send (Opcode opcode, Stream stream, Action completed)
{
- Action sender = send;
+ Func sender = send;
AsyncCallback callback = ar =>
{
try {
- sender.EndInvoke (ar);
+ var sent = sender.EndInvoke (ar);
if (completed != null)
- completed ();
+ completed (sent);
}
catch (Exception ex)
{
@@ -1585,127 +1592,62 @@ namespace WebSocketSharp
///
/// Sends a binary using the WebSocket connection.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// An array of that contains a binary data to send.
///
public void Send (byte[] data)
{
- var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
- if (msg != null)
- {
- _logger.Error (msg);
- error (msg);
-
- return;
- }
-
- if (data.LongLength <= FragmentLength)
- send (Opcode.BINARY, data);
- else
- send (Opcode.BINARY, new MemoryStream (data));
+ Send (data, null);
}
///
/// Sends a text using the WebSocket connection.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// A that contains a text data to send.
///
public void Send (string data)
{
- var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
- if (msg != null)
- {
- _logger.Error (msg);
- error (msg);
-
- return;
- }
-
- var rawData = Encoding.UTF8.GetBytes (data);
- if (rawData.LongLength <= FragmentLength)
- send (Opcode.TEXT, rawData);
- else
- send (Opcode.TEXT, new MemoryStream (rawData));
+ Send (data, null);
}
///
- /// Sends a binary data using the WebSocket connection.
+ /// Sends a binary data from the specified
+ /// using the WebSocket connection.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
- /// A that contains a binary data to send.
+ /// A from which contains a binary data to send.
///
public void Send (FileInfo file)
{
- var msg = _readyState.CheckIfOpen () ??
- (file == null ? "'file' must not be null." : null);
-
- if (msg != null)
- {
- _logger.Error (msg);
- error (msg);
-
- return;
- }
-
- send (Opcode.BINARY, file.OpenRead ());
- }
-
- ///
- /// Sends a binary data from the specified using the WebSocket connection.
- ///
- ///
- /// A object from which contains a binary data to send.
- ///
- ///
- /// An that contains the number of bytes to send.
- ///
- ///
- /// true if is disposed after a binary data read;
- /// otherwise, false.
- ///
- public void Send (Stream stream, int length, bool dispose)
- {
- byte [] data = null;
- int readLen = 0;
- var msg = _readyState.CheckIfOpen () ??
- stream.CheckIfCanRead () ??
- (length < 1 ? "'length' must be greater than 0." : null) ??
- ((readLen = (data = stream.ReadBytes (length)).Length) == 0
- ? "A data cannot be read from 'stream'." : null);
-
- if (msg != null)
- {
- _logger.Error (msg);
- error (msg);
-
- return;
- }
-
- if (readLen != length)
- _logger.Warn (String.Format (
- "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}", length, readLen));
-
- if (dispose)
- stream.Dispose ();
-
- if (readLen <= FragmentLength)
- send (Opcode.BINARY, data);
- else
- send (Opcode.BINARY, new MemoryStream (data));
+ Send (file, null);
}
///
- /// Sends a binary asynchronously using the WebSocket connection.
+ /// Sends a binary using the WebSocket connection.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// An array of that contains a binary data to send.
///
///
- /// An delegate that references the method(s) called when
- /// the asynchronous operation completes.
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is complete
+ /// successfully; otherwise, false.
///
- public void SendAsync (byte [] data, Action completed)
+ public void Send (byte [] data, Action completed)
{
var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
if (msg != null)
@@ -1717,22 +1659,27 @@ namespace WebSocketSharp
}
if (data.LongLength <= FragmentLength)
- sendAsync (Opcode.BINARY, data, completed);
+ send (Opcode.BINARY, data, completed);
else
- sendAsync (Opcode.BINARY, new MemoryStream (data), completed);
+ send (Opcode.BINARY, new MemoryStream (data), completed);
}
///
- /// Sends a text asynchronously using the WebSocket connection.
+ /// Sends a text using the WebSocket connection.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// A that contains a text data to send.
///
///
- /// An delegate that references the method(s) called when
- /// the asynchronous operation completes.
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is complete
+ /// successfully; otherwise, false.
///
- public void SendAsync (string data, Action completed)
+ public void Send (string data, Action completed)
{
var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
if (msg != null)
@@ -1745,22 +1692,28 @@ namespace WebSocketSharp
var rawData = Encoding.UTF8.GetBytes (data);
if (rawData.LongLength <= FragmentLength)
- sendAsync (Opcode.TEXT, rawData, completed);
+ send (Opcode.TEXT, rawData, completed);
else
- sendAsync (Opcode.TEXT, new MemoryStream (rawData), completed);
+ send (Opcode.TEXT, new MemoryStream (rawData), completed);
}
///
- /// Sends a binary data asynchronously using the WebSocket connection.
+ /// Sends a binary data from the specified
+ /// using the WebSocket connection.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
- /// A that contains a binary data to send.
+ /// A from which contains a binary data to send.
///
///
- /// An delegate that references the method(s) called when
- /// the asynchronous operation completes.
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is complete
+ /// successfully; otherwise, false.
///
- public void SendAsync (FileInfo file, Action completed)
+ public void Send (FileInfo file, Action completed)
{
var msg = _readyState.CheckIfOpen () ??
(file == null ? "'file' must not be null." : null);
@@ -1773,13 +1726,38 @@ namespace WebSocketSharp
return;
}
- sendAsync (Opcode.BINARY, file.OpenRead (), completed);
+ send (Opcode.BINARY, file.OpenRead (), completed);
}
///
- /// Sends a binary data asynchronously from the specified
+ /// Sends a binary data from the specified
/// using the WebSocket connection.
///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
+ ///
+ /// A object from which contains a binary data to send.
+ ///
+ ///
+ /// An that contains the number of bytes to send.
+ ///
+ ///
+ /// true if is disposed after a binary data read;
+ /// otherwise, false.
+ ///
+ public void Send (Stream stream, int length, bool dispose)
+ {
+ Send (stream, length, dispose, null);
+ }
+
+ ///
+ /// Sends a binary data from the specified
+ /// using the WebSocket connection.
+ ///
+ ///
+ /// This method does not wait for the send to be complete.
+ ///
///
/// A object from which contains a binary data to send.
///
@@ -1791,10 +1769,12 @@ namespace WebSocketSharp
/// otherwise, false.
///
///
- /// An delegate that references the method(s) called when
- /// the asynchronous operation completes.
+ /// An Action<bool> delegate that references the method(s) called when
+ /// the send is complete.
+ /// A passed to this delegate is true if the send is complete
+ /// successfully; otherwise, false.
///
- public void SendAsync (Stream stream, int length, bool dispose, Action completed)
+ public void Send (Stream stream, int length, bool dispose, Action completed)
{
var msg = _readyState.CheckIfOpen () ??
stream.CheckIfCanRead () ??
@@ -1829,10 +1809,12 @@ namespace WebSocketSharp
if (dispose)
stream.Dispose ();
- if (readLen <= FragmentLength)
- sendAsync (Opcode.BINARY, data, completed);
- else
- sendAsync (Opcode.BINARY, new MemoryStream (data), completed);
+ var sent = readLen <= FragmentLength
+ ? send (Opcode.BINARY, data)
+ : send (Opcode.BINARY, new MemoryStream (data));
+
+ if (completed != null)
+ completed (sent);
};
Action exception = ex =>