Modified some Send and Broadcast methods (e.g. Send (stream, length, dispose) -> Send (stream, length))

This commit is contained in:
sta 2013-10-16 00:18:05 +09:00
parent cbf73e9865
commit f6610352e2
6 changed files with 222 additions and 282 deletions

View File

@ -147,7 +147,13 @@ ws.Send (data);
The `Send` method is overloaded. The `Send` method is overloaded.
The types of `data` are `string`, `byte []` and `FileInfo` class. The types of `data` are `string`, `byte []` and `System.IO.FileInfo` class.
In addition, the `Send (stream, length)` method exists, too.
These methods don't wait for the send to be complete. This means that these methods behave asynchronously.
If you want to do something when the send is complete, you use any of some `Send (data, completed)` methods.
#### Step 6 #### #### Step 6 ####
@ -159,9 +165,11 @@ ws.Close (code, reason);
If you want to close the WebSocket connection explicitly, you use the `Close` method. If you want to close the WebSocket connection explicitly, you use the `Close` method.
The `Close` method is overloaded. The types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, the type of `reason` is `string`. The `Close` method is overloaded.
In addition, the `Close ()` and `Close (code)` methods exist. The types of `code` are `WebSocketSharp.CloseStatusCode` and `ushort`, and the type of `reason` is `string`.
In addition, the `Close ()` and `Close (code)` methods exist, too.
### WebSocket Server ### ### WebSocket Server ###

View File

@ -140,22 +140,22 @@ namespace WebSocketSharp
private static byte [] readBytes (this Stream stream, byte [] buffer, int offset, int length) private static byte [] readBytes (this Stream stream, byte [] buffer, int offset, int length)
{ {
var readLen = stream.Read (buffer, offset, length); var len = stream.Read (buffer, offset, length);
if (readLen < 1) if (len < 1)
return buffer.SubArray (0, offset); return buffer.SubArray (0, offset);
var tmpLen = 0; var tmp = 0;
while (readLen < length) while (len < length)
{ {
tmpLen = stream.Read (buffer, offset + readLen, length - readLen); tmp = stream.Read (buffer, offset + len, length - len);
if (tmpLen < 1) if (tmp < 1)
break; break;
readLen += tmpLen; len += tmp;
} }
return readLen < length return len < length
? buffer.SubArray (0, offset + readLen) ? buffer.SubArray (0, offset + len)
: buffer; : buffer;
} }
@ -536,15 +536,15 @@ namespace WebSocketSharp
AsyncCallback callback = ar => AsyncCallback callback = ar =>
{ {
try { try {
var readLen = stream.EndRead (ar); var len = stream.EndRead (ar);
var result = readLen < 1 var bytes = len < 1
? new byte []{} ? new byte []{}
: readLen < length : len < length
? stream.readBytes (buffer, readLen, length - readLen) ? stream.readBytes (buffer, len, length - len)
: buffer; : buffer;
if (completed != null) if (completed != null)
completed (result); completed (bytes);
} }
catch (Exception ex) { catch (Exception ex) {
if (error != null) if (error != null)

View File

@ -315,22 +315,6 @@ namespace WebSocketSharp.Server
_websocket.Send (data, null); _websocket.Send (data, null);
} }
/// <summary>
/// Sends a text <paramref name="data"/> to the client of the current
/// <see cref="WebSocketService"/> instance.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="data">
/// A <see cref="string"/> that contains a text data to send.
/// </param>
protected void Send (string data)
{
if (_websocket != null)
_websocket.Send (data, null);
}
/// <summary> /// <summary>
/// Sends a binary data from the specified <see cref="FileInfo"/> to /// Sends a binary data from the specified <see cref="FileInfo"/> to
/// the client of the current <see cref="WebSocketService"/> instance. /// the client of the current <see cref="WebSocketService"/> instance.
@ -347,6 +331,22 @@ namespace WebSocketSharp.Server
_websocket.Send (file, null); _websocket.Send (file, null);
} }
/// <summary>
/// Sends a text <paramref name="data"/> to the client of the current
/// <see cref="WebSocketService"/> instance.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="data">
/// A <see cref="string"/> that contains a text data to send.
/// </param>
protected void Send (string data)
{
if (_websocket != null)
_websocket.Send (data, null);
}
/// <summary> /// <summary>
/// Sends a binary <paramref name="data"/> to the client of the current /// Sends a binary <paramref name="data"/> to the client of the current
/// <see cref="WebSocketService"/> instance. /// <see cref="WebSocketService"/> instance.
@ -369,28 +369,6 @@ namespace WebSocketSharp.Server
_websocket.Send (data, completed); _websocket.Send (data, completed);
} }
/// <summary>
/// Sends a text <paramref name="data"/> to the client of the current
/// <see cref="WebSocketService"/> instance.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="data">
/// A <see cref="string"/> that contains a text data to send.
/// </param>
/// <param name="completed">
/// An Action&lt;bool&gt; delegate that references the method(s) called when
/// the send is complete.
/// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is
/// complete successfully; otherwise, <c>false</c>.
/// </param>
protected void Send (string data, Action<bool> completed)
{
if (_websocket != null)
_websocket.Send (data, completed);
}
/// <summary> /// <summary>
/// Sends a binary data from the specified <see cref="FileInfo"/> to /// Sends a binary data from the specified <see cref="FileInfo"/> to
/// the client of the current <see cref="WebSocketService"/> instance. /// the client of the current <see cref="WebSocketService"/> instance.
@ -414,26 +392,25 @@ namespace WebSocketSharp.Server
} }
/// <summary> /// <summary>
/// Sends a binary data from the specified <see cref="Stream"/> to /// Sends a text <paramref name="data"/> to the client of the current
/// the client of the current <see cref="WebSocketService"/> instance. /// <see cref="WebSocketService"/> instance.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method does not wait for the send to be complete. /// This method does not wait for the send to be complete.
/// </remarks> /// </remarks>
/// <param name="stream"> /// <param name="data">
/// A <see cref="Stream"/> object from which contains a binary data to send. /// A <see cref="string"/> that contains a text data to send.
/// </param> /// </param>
/// <param name="length"> /// <param name="completed">
/// An <see cref="int"/> that contains the number of bytes to send. /// An Action&lt;bool&gt; delegate that references the method(s) called when
/// the send is complete.
/// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is
/// complete successfully; otherwise, <c>false</c>.
/// </param> /// </param>
/// <param name="dispose"> protected void Send (string data, Action<bool> completed)
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read;
/// otherwise, <c>false</c>.
/// </param>
protected void Send (Stream stream, int length, bool dispose)
{ {
if (_websocket != null) if (_websocket != null)
_websocket.Send (stream, length, dispose, null); _websocket.Send (data, completed);
} }
/// <summary> /// <summary>
@ -449,9 +426,24 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send. /// An <see cref="int"/> that contains the number of bytes to send.
/// </param> /// </param>
/// <param name="dispose"> protected void Send (Stream stream, int length)
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read; {
/// otherwise, <c>false</c>. if (_websocket != null)
_websocket.Send (stream, length, null);
}
/// <summary>
/// Sends a binary data from the specified <see cref="Stream"/> to
/// the client of the current <see cref="WebSocketService"/> instance.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="stream">
/// A <see cref="Stream"/> object from which contains a binary data to send.
/// </param>
/// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send.
/// </param> /// </param>
/// <param name="completed"> /// <param name="completed">
/// An Action&lt;bool&gt; delegate that references the method(s) called when /// An Action&lt;bool&gt; delegate that references the method(s) called when
@ -459,10 +451,10 @@ namespace WebSocketSharp.Server
/// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is /// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is
/// complete successfully; otherwise, <c>false</c>. /// complete successfully; otherwise, <c>false</c>.
/// </param> /// </param>
protected void Send (Stream stream, int length, bool dispose, Action<bool> completed) protected void Send (Stream stream, int length, Action<bool> completed)
{ {
if (_websocket != null) if (_websocket != null)
_websocket.Send (stream, length, dispose, completed); _websocket.Send (stream, length, completed);
} }
/// <summary> /// <summary>

View File

@ -470,13 +470,9 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to broadcast. /// An <see cref="int"/> that contains the number of bytes to broadcast.
/// </param> /// </param>
/// <param name="dispose"> public void Broadcast (Stream stream, int length)
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data broadcasted;
/// otherwise, <c>false</c>.
/// </param>
public void Broadcast (Stream stream, int length, bool dispose)
{ {
Broadcast (stream, length, dispose, null); Broadcast (stream, length, null);
} }
/// <summary> /// <summary>
@ -492,15 +488,11 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to broadcast. /// An <see cref="int"/> that contains the number of bytes to broadcast.
/// </param> /// </param>
/// <param name="dispose">
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data broadcasted;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="completed"> /// <param name="completed">
/// A <see cref="Action"/> delegate that references the method(s) called when /// A <see cref="Action"/> delegate that references the method(s) called when
/// the broadcast is complete. /// the broadcast is complete.
/// </param> /// </param>
public void Broadcast (Stream stream, int length, bool dispose, Action completed) public void Broadcast (Stream stream, int length, Action completed)
{ {
var msg = _state.CheckIfStarted () ?? var msg = _state.CheckIfStarted () ??
stream.CheckIfCanRead () ?? stream.CheckIfCanRead () ??
@ -512,36 +504,32 @@ namespace WebSocketSharp.Server
return; return;
} }
Action<byte []> result = data => stream.ReadBytesAsync (
{ length,
var readLen = data.Length; data =>
if (readLen == 0)
{ {
_logger.Error ("A data cannot be read from 'stream'."); var len = data.Length;
return; if (len == 0)
} {
_logger.Error ("A data cannot be read from 'stream'.");
return;
}
if (readLen != length) if (len < length)
_logger.Warn (String.Format ( _logger.Warn (String.Format (
"A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}", "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}",
length, length,
readLen)); len));
if (dispose) if (len <= WebSocket.FragmentLength)
stream.Dispose (); broadcast (Opcode.BINARY, data, completed);
else
if (readLen <= WebSocket.FragmentLength) broadcast (Opcode.BINARY, new MemoryStream (data), completed);
broadcast (Opcode.BINARY, data, completed); },
else ex =>
broadcast (Opcode.BINARY, new MemoryStream (data), completed); {
}; _logger.Fatal (ex.ToString ());
});
Action<Exception> exception = ex =>
{
_logger.Fatal (ex.ToString ());
};
stream.ReadBytesAsync (length, result, exception);
} }
/// <summary> /// <summary>
@ -644,13 +632,9 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to broadcast. /// An <see cref="int"/> that contains the number of bytes to broadcast.
/// </param> /// </param>
/// <param name="dispose"> public void BroadcastTo (string servicePath, Stream stream, int length)
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data broadcasted;
/// otherwise, <c>false</c>.
/// </param>
public void BroadcastTo (string servicePath, Stream stream, int length, bool dispose)
{ {
BroadcastTo (servicePath, stream, length, dispose, null); BroadcastTo (servicePath, stream, length, null);
} }
/// <summary> /// <summary>
@ -669,20 +653,16 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to broadcast. /// An <see cref="int"/> that contains the number of bytes to broadcast.
/// </param> /// </param>
/// <param name="dispose">
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data broadcasted;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="completed"> /// <param name="completed">
/// A <see cref="Action"/> delegate that references the method(s) called when /// A <see cref="Action"/> delegate that references the method(s) called when
/// the broadcast is complete. /// the broadcast is complete.
/// </param> /// </param>
public void BroadcastTo ( public void BroadcastTo (
string servicePath, Stream stream, int length, bool dispose, Action completed) string servicePath, Stream stream, int length, Action completed)
{ {
WebSocketServiceHost host; WebSocketServiceHost host;
if (TryGetServiceHost (servicePath, out host)) if (TryGetServiceHost (servicePath, out host))
host.Sessions.Broadcast (stream, length, dispose, completed); host.Sessions.Broadcast (stream, length, completed);
} }
/// <summary> /// <summary>
@ -1011,13 +991,9 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send. /// An <see cref="int"/> that contains the number of bytes to send.
/// </param> /// </param>
/// <param name="dispose"> public void SendTo (string servicePath, string id, Stream stream, int length)
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read;
/// otherwise, <c>false</c>.
/// </param>
public void SendTo (string servicePath, string id, Stream stream, int length, bool dispose)
{ {
SendTo (servicePath, id, stream, length, dispose, null); SendTo (servicePath, id, stream, length, null);
} }
/// <summary> /// <summary>
@ -1040,10 +1016,6 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send. /// An <see cref="int"/> that contains the number of bytes to send.
/// </param> /// </param>
/// <param name="dispose">
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="completed"> /// <param name="completed">
/// An Action&lt;bool&gt; delegate that references the method(s) called when /// An Action&lt;bool&gt; delegate that references the method(s) called when
/// the send is complete. /// the send is complete.
@ -1051,11 +1023,11 @@ namespace WebSocketSharp.Server
/// successfully; otherwise, <c>false</c>. /// successfully; otherwise, <c>false</c>.
/// </param> /// </param>
public void SendTo ( public void SendTo (
string servicePath, string id, Stream stream, int length, bool dispose, Action<bool> completed) string servicePath, string id, Stream stream, int length, Action<bool> completed)
{ {
WebSocketServiceHost host; WebSocketServiceHost host;
if (TryGetServiceHost (servicePath, out host)) if (TryGetServiceHost (servicePath, out host))
host.Sessions.SendTo (id, stream, length, dispose, completed); host.Sessions.SendTo (id, stream, length, completed);
} }
/// <summary> /// <summary>

View File

@ -504,13 +504,9 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to broadcast. /// An <see cref="int"/> that contains the number of bytes to broadcast.
/// </param> /// </param>
/// <param name="dispose"> public void Broadcast (Stream stream, int length)
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data broadcasted;
/// otherwise, <c>false</c>.
/// </param>
public void Broadcast (Stream stream, int length, bool dispose)
{ {
Broadcast (stream, length, dispose, null); Broadcast (stream, length, null);
} }
/// <summary> /// <summary>
@ -526,15 +522,11 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to broadcast. /// An <see cref="int"/> that contains the number of bytes to broadcast.
/// </param> /// </param>
/// <param name="dispose">
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data broadcasted;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="completed"> /// <param name="completed">
/// A <see cref="Action"/> delegate that references the method(s) called when /// A <see cref="Action"/> delegate that references the method(s) called when
/// the broadcast is complete. /// the broadcast is complete.
/// </param> /// </param>
public void Broadcast (Stream stream, int length, bool dispose, Action completed) public void Broadcast (Stream stream, int length, Action completed)
{ {
var msg = _state.CheckIfStarted () ?? var msg = _state.CheckIfStarted () ??
stream.CheckIfCanRead () ?? stream.CheckIfCanRead () ??
@ -546,36 +538,32 @@ namespace WebSocketSharp.Server
return; return;
} }
Action<byte []> result = data => stream.ReadBytesAsync (
{ length,
var readLen = data.Length; data =>
if (readLen == 0)
{ {
_logger.Error ("A data cannot be read from 'stream'."); var len = data.Length;
return; if (len == 0)
} {
_logger.Error ("A data cannot be read from 'stream'.");
return;
}
if (readLen != length) if (len < length)
_logger.Warn (String.Format ( _logger.Warn (String.Format (
"A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}", "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}",
length, length,
readLen)); len));
if (dispose) if (len <= WebSocket.FragmentLength)
stream.Dispose (); Broadcast (Opcode.BINARY, data, completed);
else
if (readLen <= WebSocket.FragmentLength) Broadcast (Opcode.BINARY, new MemoryStream (data), completed);
Broadcast (Opcode.BINARY, data, completed); },
else ex =>
Broadcast (Opcode.BINARY, new MemoryStream (data), completed); {
}; _logger.Fatal (ex.ToString ());
});
Action<Exception> exception = ex =>
{
_logger.Fatal (ex.ToString ());
};
stream.ReadBytesAsync (length, result, exception);
} }
/// <summary> /// <summary>
@ -826,13 +814,9 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send. /// An <see cref="int"/> that contains the number of bytes to send.
/// </param> /// </param>
/// <param name="dispose"> public void SendTo (string id, Stream stream, int length)
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read;
/// otherwise, <c>false</c>.
/// </param>
public void SendTo (string id, Stream stream, int length, bool dispose)
{ {
SendTo (id, stream, length, dispose, null); SendTo (id, stream, length, null);
} }
/// <summary> /// <summary>
@ -852,10 +836,6 @@ namespace WebSocketSharp.Server
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send. /// An <see cref="int"/> that contains the number of bytes to send.
/// </param> /// </param>
/// <param name="dispose">
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="completed"> /// <param name="completed">
/// An Action&lt;bool&gt; delegate that references the method(s) called when /// An Action&lt;bool&gt; delegate that references the method(s) called when
/// the send is complete. /// the send is complete.
@ -863,11 +843,11 @@ namespace WebSocketSharp.Server
/// successfully; otherwise, <c>false</c>. /// successfully; otherwise, <c>false</c>.
/// </param> /// </param>
public void SendTo ( public void SendTo (
string id, Stream stream, int length, bool dispose, Action<bool> completed) string id, Stream stream, int length, Action<bool> completed)
{ {
IWebSocketSession session; IWebSocketSession session;
if (TryGetSession (id, out session)) if (TryGetSession (id, out session))
session.Context.WebSocket.Send (stream, length, dispose, completed); session.Context.WebSocket.Send (stream, length, completed);
} }
/// <summary> /// <summary>

View File

@ -202,7 +202,7 @@ namespace WebSocketSharp
/// <paramref name="url"/> is <see langword="null"/>. /// <paramref name="url"/> is <see langword="null"/>.
/// </exception> /// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// <paramref name="url"/> is not valid WebSocket URL. /// <paramref name="url"/> is invalid.
/// </exception> /// </exception>
public WebSocket ( public WebSocket (
string url, string url,
@ -1602,20 +1602,6 @@ namespace WebSocketSharp
Send (data, null); Send (data, null);
} }
/// <summary>
/// Sends a text <paramref name="data"/> using the WebSocket connection.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="data">
/// A <see cref="string"/> that contains a text data to send.
/// </param>
public void Send (string data)
{
Send (data, null);
}
/// <summary> /// <summary>
/// Sends a binary data from the specified <see cref="FileInfo"/> /// Sends a binary data from the specified <see cref="FileInfo"/>
/// using the WebSocket connection. /// using the WebSocket connection.
@ -1631,6 +1617,20 @@ namespace WebSocketSharp
Send (file, null); Send (file, null);
} }
/// <summary>
/// Sends a text <paramref name="data"/> using the WebSocket connection.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="data">
/// A <see cref="string"/> that contains a text data to send.
/// </param>
public void Send (string data)
{
Send (data, null);
}
/// <summary> /// <summary>
/// Sends a binary <paramref name="data"/> using the WebSocket connection. /// Sends a binary <paramref name="data"/> using the WebSocket connection.
/// </summary> /// </summary>
@ -1663,6 +1663,38 @@ namespace WebSocketSharp
send (Opcode.BINARY, new MemoryStream (data), completed); send (Opcode.BINARY, new MemoryStream (data), completed);
} }
/// <summary>
/// Sends a binary data from the specified <see cref="FileInfo"/>
/// using the WebSocket connection.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="file">
/// A <see cref="FileInfo"/> from which contains a binary data to send.
/// </param>
/// <param name="completed">
/// An Action&lt;bool&gt; delegate that references the method(s) called when
/// the send is complete.
/// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is complete
/// successfully; otherwise, <c>false</c>.
/// </param>
public void Send (FileInfo file, Action<bool> completed)
{
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 (), completed);
}
/// <summary> /// <summary>
/// Sends a text <paramref name="data"/> using the WebSocket connection. /// Sends a text <paramref name="data"/> using the WebSocket connection.
/// </summary> /// </summary>
@ -1697,35 +1729,21 @@ namespace WebSocketSharp
} }
/// <summary> /// <summary>
/// Sends a binary data from the specified <see cref="FileInfo"/> /// Sends a binary data from the specified <see cref="Stream"/>
/// using the WebSocket connection. /// using the WebSocket connection.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method does not wait for the send to be complete. /// This method does not wait for the send to be complete.
/// </remarks> /// </remarks>
/// <param name="file"> /// <param name="stream">
/// A <see cref="FileInfo"/> from which contains a binary data to send. /// A <see cref="Stream"/> object from which contains a binary data to send.
/// </param> /// </param>
/// <param name="completed"> /// <param name="length">
/// An Action&lt;bool&gt; delegate that references the method(s) called when /// An <see cref="int"/> that contains the number of bytes to send.
/// the send is complete.
/// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is complete
/// successfully; otherwise, <c>false</c>.
/// </param> /// </param>
public void Send (FileInfo file, Action<bool> completed) public void Send (Stream stream, int length)
{ {
var msg = _readyState.CheckIfOpen () ?? Send (stream, length, null);
(file == null ? "'file' must not be null." : null);
if (msg != null)
{
_logger.Error (msg);
error (msg);
return;
}
send (Opcode.BINARY, file.OpenRead (), completed);
} }
/// <summary> /// <summary>
@ -1741,39 +1759,13 @@ namespace WebSocketSharp
/// <param name="length"> /// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send. /// An <see cref="int"/> that contains the number of bytes to send.
/// </param> /// </param>
/// <param name="dispose">
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read;
/// otherwise, <c>false</c>.
/// </param>
public void Send (Stream stream, int length, bool dispose)
{
Send (stream, length, dispose, null);
}
/// <summary>
/// Sends a binary data from the specified <see cref="Stream"/>
/// using the WebSocket connection.
/// </summary>
/// <remarks>
/// This method does not wait for the send to be complete.
/// </remarks>
/// <param name="stream">
/// A <see cref="Stream"/> object from which contains a binary data to send.
/// </param>
/// <param name="length">
/// An <see cref="int"/> that contains the number of bytes to send.
/// </param>
/// <param name="dispose">
/// <c>true</c> if <paramref name="stream"/> is disposed after a binary data read;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="completed"> /// <param name="completed">
/// An Action&lt;bool&gt; delegate that references the method(s) called when /// An Action&lt;bool&gt; delegate that references the method(s) called when
/// the send is complete. /// the send is complete.
/// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is complete /// A <see cref="bool"/> passed to this delegate is <c>true</c> if the send is
/// successfully; otherwise, <c>false</c>. /// complete successfully; otherwise, <c>false</c>.
/// </param> /// </param>
public void Send (Stream stream, int length, bool dispose, Action<bool> completed) public void Send (Stream stream, int length, Action<bool> completed)
{ {
var msg = _readyState.CheckIfOpen () ?? var msg = _readyState.CheckIfOpen () ??
stream.CheckIfCanRead () ?? stream.CheckIfCanRead () ??
@ -1787,42 +1779,38 @@ namespace WebSocketSharp
return; return;
} }
Action<byte []> result = data => stream.ReadBytesAsync (
{ length,
var readLen = data.Length; data =>
if (readLen == 0)
{ {
var err = "A data cannot be read from 'stream'."; var len = data.Length;
_logger.Error (err); if (len == 0)
error (err); {
var err = "A data cannot be read from 'stream'.";
_logger.Error (err);
error (err);
return; return;
} }
if (readLen != length) if (len < length)
_logger.Warn (String.Format ( _logger.Warn (String.Format (
"A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}", "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}",
length, length,
readLen)); len));
if (dispose) var sent = len <= FragmentLength
stream.Dispose (); ? send (Opcode.BINARY, data)
: send (Opcode.BINARY, new MemoryStream (data));
var sent = readLen <= FragmentLength if (completed != null)
? send (Opcode.BINARY, data) completed (sent);
: send (Opcode.BINARY, new MemoryStream (data)); },
ex =>
if (completed != null) {
completed (sent); _logger.Fatal (ex.ToString ());
}; error ("An exception has occured.");
});
Action<Exception> exception = ex =>
{
_logger.Fatal (ex.ToString ());
error ("An exception has occured.");
};
stream.ReadBytesAsync (length, result, exception);
} }
/// <summary> /// <summary>