Modified sending and added a new Send method
This commit is contained in:
parent
79abc9aee3
commit
a5e6e6e80e
@ -165,6 +165,22 @@ namespace WebSocketSharp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static string CheckIfCanRead (this Stream stream)
|
||||||
|
{
|
||||||
|
return stream == null
|
||||||
|
? "'stream' must not be null."
|
||||||
|
: !stream.CanRead
|
||||||
|
? "'stream' cannot be read."
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string CheckIfOpen (this WebSocketState state)
|
||||||
|
{
|
||||||
|
return state != WebSocketState.OPEN
|
||||||
|
? "A WebSocket connection isn't established or has been closed."
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
internal static string CheckIfStarted (this ServerState state)
|
internal static string CheckIfStarted (this ServerState state)
|
||||||
{
|
{
|
||||||
return state != ServerState.START
|
return state != ServerState.START
|
||||||
@ -456,7 +472,7 @@ namespace WebSocketSharp
|
|||||||
var buffer = new byte [length];
|
var buffer = new byte [length];
|
||||||
var readLen = stream.Read (buffer, 0, length);
|
var readLen = stream.Read (buffer, 0, length);
|
||||||
if (readLen <= 0)
|
if (readLen <= 0)
|
||||||
return new byte [] {};
|
return new byte []{};
|
||||||
|
|
||||||
var tmpLen = 0;
|
var tmpLen = 0;
|
||||||
while (readLen < length)
|
while (readLen < length)
|
||||||
@ -1148,7 +1164,7 @@ namespace WebSocketSharp
|
|||||||
public static byte [] ReadBytes (this Stream stream, int length)
|
public static byte [] ReadBytes (this Stream stream, int length)
|
||||||
{
|
{
|
||||||
return stream == null || length < 1
|
return stream == null || length < 1
|
||||||
? new byte [] {}
|
? new byte []{}
|
||||||
: stream.ReadBytesInternal (length);
|
: stream.ReadBytesInternal (length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,7 +1184,7 @@ namespace WebSocketSharp
|
|||||||
public static byte [] ReadBytes (this Stream stream, long length)
|
public static byte [] ReadBytes (this Stream stream, long length)
|
||||||
{
|
{
|
||||||
return stream == null || length < 1
|
return stream == null || length < 1
|
||||||
? new byte [] {}
|
? new byte []{}
|
||||||
: length > 1024
|
: length > 1024
|
||||||
? stream.ReadBytesInternal (length, 1024)
|
? stream.ReadBytesInternal (length, 1024)
|
||||||
: stream.ReadBytesInternal ((int) length);
|
: stream.ReadBytesInternal ((int) length);
|
||||||
@ -1439,7 +1455,7 @@ namespace WebSocketSharp
|
|||||||
? BitConverter.GetBytes ((UInt32)(object) value)
|
? BitConverter.GetBytes ((UInt32)(object) value)
|
||||||
: type == typeof (UInt64)
|
: type == typeof (UInt64)
|
||||||
? BitConverter.GetBytes ((UInt64)(object) value)
|
? BitConverter.GetBytes ((UInt64)(object) value)
|
||||||
: new byte [] {};
|
: new byte []{};
|
||||||
|
|
||||||
return buffer.Length <= 1 || order.IsHostOrder ()
|
return buffer.Length <= 1 || order.IsHostOrder ()
|
||||||
? buffer
|
? buffer
|
||||||
|
@ -916,8 +916,7 @@ namespace WebSocketSharp
|
|||||||
|
|
||||||
private bool processPingFrame (WsFrame frame)
|
private bool processPingFrame (WsFrame frame)
|
||||||
{
|
{
|
||||||
if (send (WsFrame.CreatePongFrame (
|
if (send (WsFrame.CreatePongFrame (_client ? Mask.MASK : Mask.UNMASK, frame.PayloadData)))
|
||||||
_client ? Mask.MASK : Mask.UNMASK, frame.PayloadData).ToByteArray ()))
|
|
||||||
_logger.Trace ("Returned Pong.");
|
_logger.Trace ("Returned Pong.");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1026,50 +1025,77 @@ namespace WebSocketSharp
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _stream.WriteFrame (frame);
|
return _stream.Write (frame.ToByteArray ());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void send (Opcode opcode, byte [] data)
|
||||||
|
{
|
||||||
|
lock (_forSend)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
var comped = false;
|
||||||
|
if (_compression != CompressionMethod.NONE)
|
||||||
|
{
|
||||||
|
data = data.Compress (_compression);
|
||||||
|
comped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
send (WsFrame.CreateFrame (
|
||||||
|
Fin.FINAL, opcode, _client ? Mask.MASK : Mask.UNMASK, data, comped));
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
_logger.Fatal (ex.ToString ());
|
||||||
|
error ("An exception has occured.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send (Opcode opcode, Stream stream)
|
private void send (Opcode opcode, Stream stream)
|
||||||
{
|
{
|
||||||
var data = stream;
|
lock (_forSend)
|
||||||
var compressed = false;
|
{
|
||||||
try {
|
var comp = stream;
|
||||||
if (_readyState != WebSocketState.OPEN)
|
var comped = false;
|
||||||
{
|
try {
|
||||||
var msg = "A WebSocket connection isn't established or has been closed.";
|
if (_compression != CompressionMethod.NONE)
|
||||||
_logger.Error (msg);
|
{
|
||||||
error (msg);
|
comp = stream.Compress (_compression);
|
||||||
|
comped = true;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
sendFragmented (opcode, comp, _client ? Mask.MASK : Mask.UNMASK, comped);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
if (_compression != CompressionMethod.NONE)
|
_logger.Fatal (ex.ToString ());
|
||||||
{
|
error ("An exception has occured.");
|
||||||
data = data.Compress (_compression);
|
|
||||||
compressed = true;
|
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
if (comped)
|
||||||
|
comp.Dispose ();
|
||||||
|
|
||||||
lock (_forSend)
|
stream.Dispose ();
|
||||||
{
|
|
||||||
var mask = _client ? Mask.MASK : Mask.UNMASK;
|
|
||||||
var length = data.Length;
|
|
||||||
if (length <= FragmentLength)
|
|
||||||
send (WsFrame.CreateFrame (
|
|
||||||
Fin.FINAL, opcode, mask, data.ReadBytes ((int) length), compressed));
|
|
||||||
else
|
|
||||||
sendFragmented (opcode, data, mask, compressed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
}
|
||||||
_logger.Fatal (ex.ToString ());
|
|
||||||
error ("An exception has occured.");
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (compressed)
|
|
||||||
data.Dispose ();
|
|
||||||
|
|
||||||
stream.Dispose ();
|
private void sendAsync (Opcode opcode, byte [] data, Action completed)
|
||||||
}
|
{
|
||||||
|
Action<Opcode, byte []> sender = send;
|
||||||
|
AsyncCallback callback = ar =>
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
sender.EndInvoke (ar);
|
||||||
|
if (completed != null)
|
||||||
|
completed ();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Fatal (ex.ToString ());
|
||||||
|
error ("An exception has occured.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.BeginInvoke (opcode, data, callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendAsync (Opcode opcode, Stream stream, Action completed)
|
private void sendAsync (Opcode opcode, Stream stream, Action completed)
|
||||||
@ -1092,55 +1118,75 @@ namespace WebSocketSharp
|
|||||||
sender.BeginInvoke (opcode, stream, callback, null);
|
sender.BeginInvoke (opcode, stream, callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long sendFragmented (Opcode opcode, Stream stream, Mask mask, bool compressed)
|
private bool sendFragmented (Opcode opcode, Stream stream, Mask mask, bool compressed)
|
||||||
{
|
{
|
||||||
var length = stream.Length;
|
var len = stream.Length;
|
||||||
var quo = length / FragmentLength;
|
if (sendFragmented (opcode, stream, len, mask, compressed) == len)
|
||||||
var rem = length % FragmentLength;
|
return true;
|
||||||
var count = rem == 0 ? quo - 2 : quo - 1;
|
|
||||||
|
|
||||||
long readLen = 0;
|
var msg = "Sending fragmented data is interrupted.";
|
||||||
int tmpLen = 0;
|
_logger.Error (msg);
|
||||||
|
error (msg);
|
||||||
|
close (CloseStatusCode.ABNORMAL, msg, false);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long sendFragmented (
|
||||||
|
Opcode opcode, Stream stream, long length, Mask mask, bool compressed)
|
||||||
|
{
|
||||||
|
var quo = length / FragmentLength;
|
||||||
|
var rem = (int) (length % FragmentLength);
|
||||||
|
var count = rem == 0 ? quo - 2 : quo - 1;
|
||||||
|
|
||||||
|
long sentLen = 0;
|
||||||
|
int readLen = 0;
|
||||||
byte [] buffer = null;
|
byte [] buffer = null;
|
||||||
|
|
||||||
// Not fragmented
|
// Not fragmented
|
||||||
if (quo == 0)
|
if (quo == 0)
|
||||||
{
|
{
|
||||||
buffer = new byte [rem];
|
buffer = new byte [rem];
|
||||||
tmpLen = stream.Read (buffer, 0, buffer.Length);
|
readLen = stream.Read (buffer, 0, rem);
|
||||||
if (send (WsFrame.CreateFrame (Fin.FINAL, opcode, mask, buffer, compressed)))
|
if (readLen == rem &&
|
||||||
readLen = tmpLen;
|
send (WsFrame.CreateFrame (Fin.FINAL, opcode, mask, buffer, compressed)))
|
||||||
|
sentLen = readLen;
|
||||||
|
|
||||||
return readLen;
|
return sentLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = new byte [FragmentLength];
|
buffer = new byte [FragmentLength];
|
||||||
|
|
||||||
// First
|
// First
|
||||||
tmpLen = stream.Read (buffer, 0, FragmentLength);
|
readLen = stream.Read (buffer, 0, FragmentLength);
|
||||||
if (send (WsFrame.CreateFrame (Fin.MORE, opcode, mask, buffer, compressed)))
|
if (readLen == FragmentLength &&
|
||||||
readLen = tmpLen;
|
send (WsFrame.CreateFrame (Fin.MORE, opcode, mask, buffer, compressed)))
|
||||||
|
sentLen = readLen;
|
||||||
else
|
else
|
||||||
return 0;
|
return sentLen;
|
||||||
|
|
||||||
// Mid
|
// Mid
|
||||||
for (long i = 0; i < count; i++)
|
for (long i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
tmpLen = stream.Read (buffer, 0, FragmentLength);
|
readLen = stream.Read (buffer, 0, FragmentLength);
|
||||||
if (send (WsFrame.CreateFrame (Fin.MORE, Opcode.CONT, mask, buffer, compressed)))
|
if (readLen == FragmentLength &&
|
||||||
readLen += tmpLen;
|
send (WsFrame.CreateFrame (Fin.MORE, Opcode.CONT, mask, buffer, compressed)))
|
||||||
|
sentLen += readLen;
|
||||||
else
|
else
|
||||||
return readLen;
|
return sentLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final
|
// Final
|
||||||
|
var tmpLen = FragmentLength;
|
||||||
if (rem != 0)
|
if (rem != 0)
|
||||||
buffer = new byte [rem];
|
buffer = new byte [tmpLen = rem];
|
||||||
tmpLen = stream.Read (buffer, 0, buffer.Length);
|
|
||||||
if (send (WsFrame.CreateFrame (Fin.FINAL, Opcode.CONT, mask, buffer, compressed)))
|
|
||||||
readLen += tmpLen;
|
|
||||||
|
|
||||||
return readLen;
|
readLen = stream.Read (buffer, 0, tmpLen);
|
||||||
|
if (readLen == tmpLen &&
|
||||||
|
send (WsFrame.CreateFrame (Fin.FINAL, Opcode.CONT, mask, buffer, compressed)))
|
||||||
|
sentLen += readLen;
|
||||||
|
|
||||||
|
return sentLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
@ -1291,51 +1337,51 @@ namespace WebSocketSharp
|
|||||||
// As server, used to broadcast
|
// As server, used to broadcast
|
||||||
internal void Send (Opcode opcode, byte [] data, Dictionary<CompressionMethod, byte []> cache)
|
internal void Send (Opcode opcode, byte [] data, Dictionary<CompressionMethod, byte []> cache)
|
||||||
{
|
{
|
||||||
try {
|
lock (_forSend)
|
||||||
byte [] cached;
|
{
|
||||||
if (!cache.TryGetValue (_compression, out cached))
|
try {
|
||||||
{
|
byte [] cached;
|
||||||
cached = WsFrame.CreateFrame (
|
if (!cache.TryGetValue (_compression, out cached))
|
||||||
Fin.FINAL,
|
{
|
||||||
opcode,
|
cached = WsFrame.CreateFrame (
|
||||||
Mask.UNMASK,
|
Fin.FINAL,
|
||||||
data.Compress (_compression),
|
opcode,
|
||||||
_compression != CompressionMethod.NONE).ToByteArray ();
|
Mask.UNMASK,
|
||||||
|
data.Compress (_compression),
|
||||||
|
_compression != CompressionMethod.NONE).ToByteArray ();
|
||||||
|
|
||||||
cache.Add (_compression, cached);
|
cache.Add (_compression, cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_forSend)
|
|
||||||
{
|
|
||||||
send (cached);
|
send (cached);
|
||||||
}
|
}
|
||||||
}
|
catch (Exception ex) {
|
||||||
catch (Exception ex) {
|
_logger.Fatal (ex.ToString ());
|
||||||
_logger.Fatal (ex.ToString ());
|
error ("An exception has occured.");
|
||||||
error ("An exception has occured.");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As server, used to broadcast
|
// As server, used to broadcast
|
||||||
internal void Send (Opcode opcode, Stream stream, Dictionary <CompressionMethod, Stream> cache)
|
internal void Send (Opcode opcode, Stream stream, Dictionary <CompressionMethod, Stream> cache)
|
||||||
{
|
{
|
||||||
try {
|
lock (_forSend)
|
||||||
Stream cached;
|
{
|
||||||
if (!cache.TryGetValue (_compression, out cached))
|
try {
|
||||||
{
|
Stream cached;
|
||||||
cached = stream.Compress (_compression);
|
if (!cache.TryGetValue (_compression, out cached))
|
||||||
cache.Add (_compression, cached);
|
{
|
||||||
}
|
cached = stream.Compress (_compression);
|
||||||
|
cache.Add (_compression, cached);
|
||||||
|
}
|
||||||
|
|
||||||
lock (_forSend)
|
|
||||||
{
|
|
||||||
cached.Position = 0;
|
cached.Position = 0;
|
||||||
sendFragmented (opcode, cached, Mask.UNMASK, _compression != CompressionMethod.NONE);
|
sendFragmented (opcode, cached, Mask.UNMASK, _compression != CompressionMethod.NONE);
|
||||||
}
|
}
|
||||||
}
|
catch (Exception ex) {
|
||||||
catch (Exception ex) {
|
_logger.Fatal (ex.ToString ());
|
||||||
_logger.Fatal (ex.ToString ());
|
error ("An exception has occured.");
|
||||||
error ("An exception has occured.");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1544,17 +1590,19 @@ namespace WebSocketSharp
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void Send (byte[] data)
|
public void Send (byte[] data)
|
||||||
{
|
{
|
||||||
if (data == null)
|
var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
|
||||||
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "'data' must not be null.";
|
|
||||||
_logger.Error (msg);
|
_logger.Error (msg);
|
||||||
error (msg);
|
error (msg);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stream = new MemoryStream (data);
|
if (data.LongLength <= FragmentLength)
|
||||||
send (Opcode.BINARY, stream);
|
send (Opcode.BINARY, data);
|
||||||
|
else
|
||||||
|
send (Opcode.BINARY, new MemoryStream (data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1565,17 +1613,20 @@ namespace WebSocketSharp
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void Send (string data)
|
public void Send (string data)
|
||||||
{
|
{
|
||||||
if (data == null)
|
var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
|
||||||
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "'data' must not be null.";
|
|
||||||
_logger.Error (msg);
|
_logger.Error (msg);
|
||||||
error (msg);
|
error (msg);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stream = new MemoryStream (Encoding.UTF8.GetBytes (data));
|
var rawData = Encoding.UTF8.GetBytes (data);
|
||||||
send (Opcode.TEXT, stream);
|
if (rawData.LongLength <= FragmentLength)
|
||||||
|
send (Opcode.TEXT, rawData);
|
||||||
|
else
|
||||||
|
send (Opcode.TEXT, new MemoryStream (rawData));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1586,9 +1637,11 @@ namespace WebSocketSharp
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void Send (FileInfo file)
|
public void Send (FileInfo file)
|
||||||
{
|
{
|
||||||
if (file == null)
|
var msg = _readyState.CheckIfOpen () ??
|
||||||
|
(file == null ? "'file' must not be null." : null);
|
||||||
|
|
||||||
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "'file' must not be null.";
|
|
||||||
_logger.Error (msg);
|
_logger.Error (msg);
|
||||||
error (msg);
|
error (msg);
|
||||||
|
|
||||||
@ -1598,6 +1651,50 @@ namespace WebSocketSharp
|
|||||||
send (Opcode.BINARY, file.OpenRead ());
|
send (Opcode.BINARY, file.OpenRead ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a binary data from the specified <see cref="Stream"/> using the WebSocket connection.
|
||||||
|
/// </summary>
|
||||||
|
/// <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>
|
||||||
|
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.ReadBytesInternal (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));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a binary <paramref name="data"/> asynchronously using the WebSocket connection.
|
/// Sends a binary <paramref name="data"/> asynchronously using the WebSocket connection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1610,17 +1707,19 @@ namespace WebSocketSharp
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void SendAsync (byte [] data, Action completed)
|
public void SendAsync (byte [] data, Action completed)
|
||||||
{
|
{
|
||||||
if (data == null)
|
var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
|
||||||
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "'data' must not be null.";
|
|
||||||
_logger.Error (msg);
|
_logger.Error (msg);
|
||||||
error (msg);
|
error (msg);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stream = new MemoryStream (data);
|
if (data.LongLength <= FragmentLength)
|
||||||
sendAsync (Opcode.BINARY, stream, completed);
|
sendAsync (Opcode.BINARY, data, completed);
|
||||||
|
else
|
||||||
|
sendAsync (Opcode.BINARY, new MemoryStream (data), completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1635,17 +1734,20 @@ namespace WebSocketSharp
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void SendAsync (string data, Action completed)
|
public void SendAsync (string data, Action completed)
|
||||||
{
|
{
|
||||||
if (data == null)
|
var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData ();
|
||||||
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "'data' must not be null.";
|
|
||||||
_logger.Error (msg);
|
_logger.Error (msg);
|
||||||
error (msg);
|
error (msg);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stream = new MemoryStream (Encoding.UTF8.GetBytes (data));
|
var rawData = Encoding.UTF8.GetBytes (data);
|
||||||
sendAsync (Opcode.TEXT, stream, completed);
|
if (rawData.LongLength <= FragmentLength)
|
||||||
|
sendAsync (Opcode.TEXT, rawData, completed);
|
||||||
|
else
|
||||||
|
sendAsync (Opcode.TEXT, new MemoryStream (rawData), completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1660,9 +1762,11 @@ namespace WebSocketSharp
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void SendAsync (FileInfo file, Action completed)
|
public void SendAsync (FileInfo file, Action completed)
|
||||||
{
|
{
|
||||||
if (file == null)
|
var msg = _readyState.CheckIfOpen () ??
|
||||||
|
(file == null ? "'file' must not be null." : null);
|
||||||
|
|
||||||
|
if (msg != null)
|
||||||
{
|
{
|
||||||
var msg = "'file' must not be null.";
|
|
||||||
_logger.Error (msg);
|
_logger.Error (msg);
|
||||||
error (msg);
|
error (msg);
|
||||||
|
|
||||||
@ -1672,6 +1776,55 @@ namespace WebSocketSharp
|
|||||||
sendAsync (Opcode.BINARY, file.OpenRead (), completed);
|
sendAsync (Opcode.BINARY, file.OpenRead (), completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a binary data asynchronously from the specified <see cref="Stream"/>
|
||||||
|
/// using the WebSocket connection.
|
||||||
|
/// </summary>
|
||||||
|
/// <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">
|
||||||
|
/// An <see cref="Action"/> delegate that references the method(s) called when
|
||||||
|
/// the asynchronous operation completes.
|
||||||
|
/// </param>
|
||||||
|
public void SendAsync (Stream stream, int length, bool dispose, Action completed)
|
||||||
|
{
|
||||||
|
byte [] data = null;
|
||||||
|
int readLen = 0;
|
||||||
|
var msg = _readyState.CheckIfOpen () ??
|
||||||
|
stream.CheckIfCanRead () ??
|
||||||
|
(length < 1 ? "'length' must be greater than 0." : null) ??
|
||||||
|
((readLen = (data = stream.ReadBytesInternal (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)
|
||||||
|
sendAsync (Opcode.BINARY, data, completed);
|
||||||
|
else
|
||||||
|
sendAsync (Opcode.BINARY, new MemoryStream (data), completed);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets a <see cref="Cookie"/> used in the WebSocket opening handshake.
|
/// Sets a <see cref="Cookie"/> used in the WebSocket opening handshake.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user