diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index baa2a429..6e0116e5 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -1049,7 +1049,7 @@ namespace WebSocketSharp { lock (_forConn) { if (_readyState != WebSocketState.Open) { - _logger.Warn ("Sending has been interrupted."); + _logger.Error ("Closing the WebSocket connection has been done."); 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) { lock (_forSend) { var src = stream; - var sent = false; var compressed = false; + var sent = false; + string msg = null; try { if (_compression != CompressionMethod.None) { stream = stream.Compress (_compression); compressed = true; } - var mask = _client ? Mask.Mask : Mask.Unmask; - sent = sendFragmented (opcode, stream, mask, compressed); + sent = send (opcode, stream, _client ? Mask.Mask : Mask.Unmask, compressed); + if (!sent) + msg = "Sending a data has been interrupted."; } catch (Exception ex) { _logger.Fatal (ex.ToString ()); - error ("An exception has occurred while sending a data."); + msg = "An exception has occurred while sending a data."; } finally { if (compressed) @@ -1106,73 +1085,26 @@ namespace WebSocketSharp src.Dispose (); } + if (msg != null) + error (msg); + return sent; } } - private bool send (Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed) + private bool send (Opcode opcode, Stream stream, Mask mask, bool compressed) { - lock (_forConn) { - if (_readyState != WebSocketState.Open) { - _logger.Warn ("Sending has been interrupted."); - return false; - } + var len = stream.Length; - return _stream.WriteBytes ( - WebSocketFrame.CreateFrame (fin, opcode, mask, data, compressed).ToByteArray ()); - } - } + /* Not fragmented */ - private void sendAsync (Opcode opcode, byte[] data, Action completed) - { - Func 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); - } + if (len == 0) + return send (Fin.Final, opcode, mask, new byte[0], compressed); - private void sendAsync (Opcode opcode, Stream stream, Action completed) - { - Func sender = send; - sender.BeginInvoke ( - opcode, - stream, - 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 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 && @@ -1180,20 +1112,24 @@ namespace WebSocketSharp } buff = new byte[FragmentLength]; + if (quo == 1 && rem == 0) + return stream.Read (buff, 0, FragmentLength) == FragmentLength && + send (Fin.Final, opcode, mask, buff, compressed); - // First + /* Send fragmented */ + + // Begin if (stream.Read (buff, 0, FragmentLength) != FragmentLength || !send (Fin.More, opcode, mask, buff, compressed)) return false; - // Mid - for (long i = 0; i < times; i++) { + 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; - } - // Final + // End var tmpLen = FragmentLength; if (rem != 0) buff = new byte[tmpLen = rem]; @@ -1202,6 +1138,39 @@ namespace WebSocketSharp send (Fin.Final, Opcode.Cont, mask, buff, compressed); } + private bool send (Fin fin, Opcode opcode, Mask mask, byte[] data, bool compressed) + { + lock (_forConn) { + if (_readyState != WebSocketState.Open) { + _logger.Error ("Closing the WebSocket connection has been done."); + return false; + } + + return _stream.WriteBytes ( + WebSocketFrame.CreateFrame (fin, opcode, mask, data, compressed).ToByteArray ()); + } + } + + private void sendAsync (Opcode opcode, Stream stream, Action completed) + { + Func sender = send; + sender.BeginInvoke ( + opcode, + stream, + 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); + } + // As client private HttpResponse sendHandshakeRequest () { @@ -1453,8 +1422,10 @@ namespace WebSocketSharp { lock (_forSend) { lock (_forConn) { - if (_readyState != WebSocketState.Open) + if (_readyState != WebSocketState.Open) { + _logger.Error ("Closing the WebSocket connection has been done."); return; + } try { byte[] cached; @@ -1470,11 +1441,11 @@ namespace WebSocketSharp cache.Add (_compression, cached); } - _stream.WriteBytes (cached); + if (!_stream.WriteBytes (cached)) + _logger.Error ("Sending a data has been interrupted."); } catch (Exception ex) { - _logger.Fatal (ex.ToString ()); - error ("An exception has occurred while sending a data."); + _logger.Fatal ("An exception has occurred while sending a data:\n" + ex.ToString ()); } } } @@ -1494,12 +1465,12 @@ namespace WebSocketSharp cached.Position = 0; } - if (_readyState == WebSocketState.Open) - sendFragmented (opcode, cached, Mask.Unmask, _compression != CompressionMethod.None); + if (_readyState != WebSocketState.Open || + !send (opcode, cached, Mask.Unmask, _compression != CompressionMethod.None)) + _logger.Error ("Sending a data has been interrupted."); } catch (Exception ex) { - _logger.Fatal (ex.ToString ()); - error ("An exception has occurred while sending a data."); + _logger.Fatal ("An exception has occurred while sending a data:\n" + ex.ToString ()); } } } @@ -1853,13 +1824,7 @@ namespace WebSocketSharp return; } - var len = data.LongLength; - if (len <= FragmentLength) - send ( - Opcode.Binary, - len > 0 && _client && _compression == CompressionMethod.None ? data.Copy (len) : data); - else - send (Opcode.Binary, new MemoryStream (data)); + send (Opcode.Binary, new MemoryStream (data)); } /// @@ -1898,11 +1863,7 @@ namespace WebSocketSharp return; } - var rawData = Encoding.UTF8.GetBytes (data); - if (rawData.LongLength <= FragmentLength) - send (Opcode.Text, rawData); - else - send (Opcode.Text, new MemoryStream (rawData)); + send (Opcode.Text, new MemoryStream (Encoding.UTF8.GetBytes (data))); } /// @@ -1929,14 +1890,7 @@ namespace WebSocketSharp return; } - var len = data.LongLength; - 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); + sendAsync (Opcode.Binary, new MemoryStream (data), completed); } /// @@ -1991,11 +1945,7 @@ namespace WebSocketSharp return; } - var rawData = Encoding.UTF8.GetBytes (data); - if (rawData.LongLength <= FragmentLength) - sendAsync (Opcode.Text, rawData, completed); - else - sendAsync (Opcode.Text, new MemoryStream (rawData), completed); + sendAsync (Opcode.Text, new MemoryStream (Encoding.UTF8.GetBytes (data)), completed); } /// @@ -2048,10 +1998,7 @@ namespace WebSocketSharp length, len)); - var sent = len <= FragmentLength - ? send (Opcode.Binary, data) - : send (Opcode.Binary, new MemoryStream (data)); - + var sent = send (Opcode.Binary, new MemoryStream (data)); if (completed != null) completed (sent); },