Refactored WebSocket.cs
This commit is contained in:
parent
7cb6499c3a
commit
cff0253b9d
@ -1049,7 +1049,7 @@ namespace WebSocketSharp
|
|||||||
{
|
{
|
||||||
lock (_forConn) {
|
lock (_forConn) {
|
||||||
if (_readyState != WebSocketState.Open) {
|
if (_readyState != WebSocketState.Open) {
|
||||||
_logger.Warn ("Sending has been interrupted.");
|
_logger.Error ("Closing the WebSocket connection has been done.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,47 +1057,26 @@ namespace WebSocketSharp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool send (Opcode opcode, byte[] data)
|
|
||||||
{
|
|
||||||
lock (_forSend) {
|
|
||||||
var sent = false;
|
|
||||||
try {
|
|
||||||
var compressed = false;
|
|
||||||
if (_compression != CompressionMethod.None) {
|
|
||||||
data = data.Compress (_compression);
|
|
||||||
compressed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var mask = _client ? Mask.Mask : Mask.Unmask;
|
|
||||||
sent = send (Fin.Final, opcode, mask, data, compressed);
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
_logger.Fatal (ex.ToString ());
|
|
||||||
error ("An exception has occurred while sending a data.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool send (Opcode opcode, Stream stream)
|
private bool send (Opcode opcode, Stream stream)
|
||||||
{
|
{
|
||||||
lock (_forSend) {
|
lock (_forSend) {
|
||||||
var src = stream;
|
var src = stream;
|
||||||
var sent = false;
|
|
||||||
var compressed = false;
|
var compressed = false;
|
||||||
|
var sent = false;
|
||||||
|
string msg = null;
|
||||||
try {
|
try {
|
||||||
if (_compression != CompressionMethod.None) {
|
if (_compression != CompressionMethod.None) {
|
||||||
stream = stream.Compress (_compression);
|
stream = stream.Compress (_compression);
|
||||||
compressed = true;
|
compressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mask = _client ? Mask.Mask : Mask.Unmask;
|
sent = send (opcode, stream, _client ? Mask.Mask : Mask.Unmask, compressed);
|
||||||
sent = sendFragmented (opcode, stream, mask, compressed);
|
if (!sent)
|
||||||
|
msg = "Sending a data has been interrupted.";
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
_logger.Fatal (ex.ToString ());
|
_logger.Fatal (ex.ToString ());
|
||||||
error ("An exception has occurred while sending a data.");
|
msg = "An exception has occurred while sending a data.";
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (compressed)
|
if (compressed)
|
||||||
@ -1106,15 +1085,64 @@ namespace WebSocketSharp
|
|||||||
src.Dispose ();
|
src.Dispose ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg != null)
|
||||||
|
error (msg);
|
||||||
|
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool send (Opcode opcode, Stream stream, Mask mask, bool compressed)
|
||||||
|
{
|
||||||
|
var len = stream.Length;
|
||||||
|
|
||||||
|
/* Not fragmented */
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return send (Fin.Final, opcode, mask, new byte[0], compressed);
|
||||||
|
|
||||||
|
var quo = len / FragmentLength;
|
||||||
|
var rem = (int) (len % FragmentLength);
|
||||||
|
|
||||||
|
byte[] buff = null;
|
||||||
|
if (quo == 0) {
|
||||||
|
buff = new byte[rem];
|
||||||
|
return stream.Read (buff, 0, rem) == rem &&
|
||||||
|
send (Fin.Final, opcode, mask, buff, compressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
buff = new byte[FragmentLength];
|
||||||
|
if (quo == 1 && rem == 0)
|
||||||
|
return stream.Read (buff, 0, FragmentLength) == FragmentLength &&
|
||||||
|
send (Fin.Final, opcode, mask, buff, compressed);
|
||||||
|
|
||||||
|
/* Send fragmented */
|
||||||
|
|
||||||
|
// Begin
|
||||||
|
if (stream.Read (buff, 0, FragmentLength) != FragmentLength ||
|
||||||
|
!send (Fin.More, opcode, mask, buff, compressed))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var times = rem == 0 ? quo - 2 : quo - 1;
|
||||||
|
for (long i = 0; i < times; i++)
|
||||||
|
if (stream.Read (buff, 0, FragmentLength) != FragmentLength ||
|
||||||
|
!send (Fin.More, Opcode.Cont, mask, buff, compressed))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// End
|
||||||
|
var tmpLen = FragmentLength;
|
||||||
|
if (rem != 0)
|
||||||
|
buff = new byte[tmpLen = rem];
|
||||||
|
|
||||||
|
return stream.Read (buff, 0, tmpLen) == tmpLen &&
|
||||||
|
send (Fin.Final, Opcode.Cont, mask, buff, compressed);
|
||||||
|
}
|
||||||
|
|
||||||
private bool send (Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed)
|
private bool send (Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed)
|
||||||
{
|
{
|
||||||
lock (_forConn) {
|
lock (_forConn) {
|
||||||
if (_readyState != WebSocketState.Open) {
|
if (_readyState != WebSocketState.Open) {
|
||||||
_logger.Warn ("Sending has been interrupted.");
|
_logger.Error ("Closing the WebSocket connection has been done.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1123,26 +1151,6 @@ namespace WebSocketSharp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendAsync (Opcode opcode, byte[] data, Action<bool> completed)
|
|
||||||
{
|
|
||||||
Func<Opcode, byte[], bool> sender = send;
|
|
||||||
sender.BeginInvoke (
|
|
||||||
opcode,
|
|
||||||
data,
|
|
||||||
ar => {
|
|
||||||
try {
|
|
||||||
var sent = sender.EndInvoke (ar);
|
|
||||||
if (completed != null)
|
|
||||||
completed (sent);
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
_logger.Fatal (ex.ToString ());
|
|
||||||
error ("An exception has occurred while callback.");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendAsync (Opcode opcode, Stream stream, Action<bool> completed)
|
private void sendAsync (Opcode opcode, Stream stream, Action<bool> completed)
|
||||||
{
|
{
|
||||||
Func<Opcode, Stream, bool> sender = send;
|
Func<Opcode, Stream, bool> sender = send;
|
||||||
@ -1163,45 +1171,6 @@ namespace WebSocketSharp
|
|||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool sendFragmented (Opcode opcode, Stream stream, Mask mask, bool compressed)
|
|
||||||
{
|
|
||||||
var len = stream.Length;
|
|
||||||
var quo = len / FragmentLength;
|
|
||||||
var rem = (int) (len % FragmentLength);
|
|
||||||
var times = rem == 0 ? quo - 2 : quo - 1;
|
|
||||||
|
|
||||||
byte[] buff = null;
|
|
||||||
|
|
||||||
// Not fragmented
|
|
||||||
if (quo == 0) {
|
|
||||||
buff = new byte[rem];
|
|
||||||
return stream.Read (buff, 0, rem) == rem &&
|
|
||||||
send (Fin.Final, opcode, mask, buff, compressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
buff = new byte[FragmentLength];
|
|
||||||
|
|
||||||
// First
|
|
||||||
if (stream.Read (buff, 0, FragmentLength) != FragmentLength ||
|
|
||||||
!send (Fin.More, opcode, mask, buff, compressed))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Mid
|
|
||||||
for (long i = 0; i < times; i++) {
|
|
||||||
if (stream.Read (buff, 0, FragmentLength) != FragmentLength ||
|
|
||||||
!send (Fin.More, Opcode.Cont, mask, buff, compressed))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final
|
|
||||||
var tmpLen = FragmentLength;
|
|
||||||
if (rem != 0)
|
|
||||||
buff = new byte[tmpLen = rem];
|
|
||||||
|
|
||||||
return stream.Read (buff, 0, tmpLen) == tmpLen &&
|
|
||||||
send (Fin.Final, Opcode.Cont, mask, buff, compressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
private HttpResponse sendHandshakeRequest ()
|
private HttpResponse sendHandshakeRequest ()
|
||||||
{
|
{
|
||||||
@ -1453,8 +1422,10 @@ namespace WebSocketSharp
|
|||||||
{
|
{
|
||||||
lock (_forSend) {
|
lock (_forSend) {
|
||||||
lock (_forConn) {
|
lock (_forConn) {
|
||||||
if (_readyState != WebSocketState.Open)
|
if (_readyState != WebSocketState.Open) {
|
||||||
|
_logger.Error ("Closing the WebSocket connection has been done.");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] cached;
|
byte[] cached;
|
||||||
@ -1470,11 +1441,11 @@ namespace WebSocketSharp
|
|||||||
cache.Add (_compression, cached);
|
cache.Add (_compression, cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
_stream.WriteBytes (cached);
|
if (!_stream.WriteBytes (cached))
|
||||||
|
_logger.Error ("Sending a data has been interrupted.");
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
_logger.Fatal (ex.ToString ());
|
_logger.Fatal ("An exception has occurred while sending a data:\n" + ex.ToString ());
|
||||||
error ("An exception has occurred while sending a data.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1494,12 +1465,12 @@ namespace WebSocketSharp
|
|||||||
cached.Position = 0;
|
cached.Position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_readyState == WebSocketState.Open)
|
if (_readyState != WebSocketState.Open ||
|
||||||
sendFragmented (opcode, cached, Mask.Unmask, _compression != CompressionMethod.None);
|
!send (opcode, cached, Mask.Unmask, _compression != CompressionMethod.None))
|
||||||
|
_logger.Error ("Sending a data has been interrupted.");
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
_logger.Fatal (ex.ToString ());
|
_logger.Fatal ("An exception has occurred while sending a data:\n" + ex.ToString ());
|
||||||
error ("An exception has occurred while sending a data.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1853,13 +1824,7 @@ namespace WebSocketSharp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var len = data.LongLength;
|
send (Opcode.Binary, new MemoryStream (data));
|
||||||
if (len <= FragmentLength)
|
|
||||||
send (
|
|
||||||
Opcode.Binary,
|
|
||||||
len > 0 && _client && _compression == CompressionMethod.None ? data.Copy (len) : data);
|
|
||||||
else
|
|
||||||
send (Opcode.Binary, new MemoryStream (data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1898,11 +1863,7 @@ namespace WebSocketSharp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawData = Encoding.UTF8.GetBytes (data);
|
send (Opcode.Text, new MemoryStream (Encoding.UTF8.GetBytes (data)));
|
||||||
if (rawData.LongLength <= FragmentLength)
|
|
||||||
send (Opcode.Text, rawData);
|
|
||||||
else
|
|
||||||
send (Opcode.Text, new MemoryStream (rawData));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1929,14 +1890,7 @@ namespace WebSocketSharp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var len = data.LongLength;
|
sendAsync (Opcode.Binary, new MemoryStream (data), completed);
|
||||||
if (len <= FragmentLength)
|
|
||||||
sendAsync (
|
|
||||||
Opcode.Binary,
|
|
||||||
len > 0 && _client && _compression == CompressionMethod.None ? data.Copy (len) : data,
|
|
||||||
completed);
|
|
||||||
else
|
|
||||||
sendAsync (Opcode.Binary, new MemoryStream (data), completed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1991,11 +1945,7 @@ namespace WebSocketSharp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawData = Encoding.UTF8.GetBytes (data);
|
sendAsync (Opcode.Text, new MemoryStream (Encoding.UTF8.GetBytes (data)), completed);
|
||||||
if (rawData.LongLength <= FragmentLength)
|
|
||||||
sendAsync (Opcode.Text, rawData, completed);
|
|
||||||
else
|
|
||||||
sendAsync (Opcode.Text, new MemoryStream (rawData), completed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -2048,10 +1998,7 @@ namespace WebSocketSharp
|
|||||||
length,
|
length,
|
||||||
len));
|
len));
|
||||||
|
|
||||||
var sent = len <= FragmentLength
|
var sent = send (Opcode.Binary, new MemoryStream (data));
|
||||||
? send (Opcode.Binary, data)
|
|
||||||
: send (Opcode.Binary, new MemoryStream (data));
|
|
||||||
|
|
||||||
if (completed != null)
|
if (completed != null)
|
||||||
completed (sent);
|
completed (sent);
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user