From 418ec8bc2fbb4d7339e0815c5274c5bcfd265a41 Mon Sep 17 00:00:00 2001 From: sta Date: Fri, 10 Jan 2014 05:04:46 +0900 Subject: [PATCH] Added SendAsync methods to the WebSocket class. Existing Send methods were changed to behave synchronously --- websocket-sharp/Server/WebSocketService.cs | 98 ++--- .../Server/WebSocketServiceHostManager.cs | 147 +++---- .../Server/WebSocketSessionManager.cs | 192 ++++----- websocket-sharp/WebSocket.cs | 395 +++++++++--------- 4 files changed, 387 insertions(+), 445 deletions(-) diff --git a/websocket-sharp/Server/WebSocketService.cs b/websocket-sharp/Server/WebSocketService.cs index 4110197f..2d9d051d 100644 --- a/websocket-sharp/Server/WebSocketService.cs +++ b/websocket-sharp/Server/WebSocketService.cs @@ -5,7 +5,7 @@ * The MIT License * * Copyright (c) 2012-2014 sta.blockhead - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -15,7 +15,7 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -182,8 +182,7 @@ namespace WebSocketSharp.Server private void onOpen (object sender, EventArgs e) { ID = _sessions.Add (this); - if (ID == null) - { + if (ID == null) { _websocket.Close (CloseStatusCode.AWAY); return; } @@ -303,59 +302,50 @@ 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. + /// An array of that contains the binary data to send. /// protected void Send (byte [] data) { if (_websocket != null) - _websocket.Send (data, null); + _websocket.Send (data); } /// /// 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. + /// A from which contains the binary data to send. /// protected void Send (FileInfo file) { if (_websocket != null) - _websocket.Send (file, null); + _websocket.Send (file); } /// /// 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. + /// A that represents the text data to send. /// protected void Send (string data) { if (_websocket != null) - _websocket.Send (data, null); + _websocket.Send (data); } /// - /// Sends a binary to the client of the current - /// instance. + /// Sends a binary asynchronously to the client of the + /// current instance. /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// An array of that contains a binary data to send. + /// An array of that contains the binary data to send. /// /// /// An Action<bool> delegate that references the method(s) called when @@ -363,21 +353,22 @@ namespace WebSocketSharp.Server /// A passed to this delegate is true if the send is /// complete successfully; otherwise, false. /// - protected void Send (byte [] data, Action completed) + protected void SendAsync (byte [] data, Action completed) { if (_websocket != null) - _websocket.Send (data, completed); + _websocket.SendAsync (data, completed); } /// - /// Sends a binary data from the specified to - /// the client of the current instance. + /// Sends a binary data from the specified + /// asynchronously to the client of the current + /// instance. /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// A from which contains a binary data to send. + /// A from which contains the binary data to send. /// /// /// An Action<bool> delegate that references the method(s) called when @@ -385,21 +376,21 @@ namespace WebSocketSharp.Server /// A passed to this delegate is true if the send is /// complete successfully; otherwise, false. /// - protected void Send (FileInfo file, Action completed) + protected void SendAsync (FileInfo file, Action completed) { if (_websocket != null) - _websocket.Send (file, completed); + _websocket.SendAsync (file, completed); } /// - /// Sends a text to the client of the current - /// instance. + /// Sends a text asynchronously to the client of the + /// current instance. /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// A that contains a text data to send. + /// A that contains the text data to send. /// /// /// An Action<bool> delegate that references the method(s) called when @@ -407,43 +398,24 @@ namespace WebSocketSharp.Server /// A passed to this delegate is true if the send is /// complete successfully; otherwise, false. /// - protected void Send (string data, Action completed) + protected void SendAsync (string data, Action completed) { if (_websocket != null) - _websocket.Send (data, completed); + _websocket.SendAsync (data, completed); } /// - /// Sends a binary data from the specified to - /// the client of the current instance. + /// Sends a binary data from the specified asynchronously + /// to the client of the current instance. /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// A object from which contains a binary data to send. + /// A object from which contains the binary data to send. /// /// - /// An that contains the number of bytes to send. - /// - protected void Send (Stream stream, int length) - { - if (_websocket != null) - _websocket.Send (stream, length, 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. + /// An that represents the number of bytes to send. /// /// /// An Action<bool> delegate that references the method(s) called when @@ -451,10 +423,10 @@ namespace WebSocketSharp.Server /// A passed to this delegate is true if the send is /// complete successfully; otherwise, false. /// - protected void Send (Stream stream, int length, Action completed) + protected void SendAsync (Stream stream, int length, Action completed) { if (_websocket != null) - _websocket.Send (stream, length, completed); + _websocket.SendAsync (stream, length, completed); } /// diff --git a/websocket-sharp/Server/WebSocketServiceHostManager.cs b/websocket-sharp/Server/WebSocketServiceHostManager.cs index 45e4eb8d..ced1a652 100644 --- a/websocket-sharp/Server/WebSocketServiceHostManager.cs +++ b/websocket-sharp/Server/WebSocketServiceHostManager.cs @@ -4,8 +4,8 @@ * * The MIT License * - * Copyright (c) 2012-2013 sta.blockhead - * + * Copyright (c) 2012-2014 sta.blockhead + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -15,7 +15,7 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -868,166 +868,149 @@ namespace WebSocketSharp.Server } /// - /// Sends a binary to the client associated with the specified - /// and . + /// Sends a binary to the client associated with the + /// specified and . /// - /// - /// This method does not wait for the send to be complete. - /// /// - /// A that contains an absolute path to the WebSocket service to find. + /// A that represents the absolute path to the WebSocket + /// service to find. /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// /// - /// An array of that contains a binary data to send. + /// An array of that contains the binary data to send. /// public void SendTo (string servicePath, string id, byte [] data) { - SendTo (servicePath, id, data, null); + WebSocketServiceHost host; + if (TryGetServiceHost (servicePath, out host)) + host.Sessions.SendTo (id, data); } /// - /// Sends a text to the client associated with the specified - /// and . + /// Sends a text to the client associated with the + /// specified and . /// - /// - /// This method does not wait for the send to be complete. - /// /// - /// A that contains an absolute path to the WebSocket service to find. + /// A that represents the absolute path to the WebSocket + /// service to find. /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// /// - /// A that contains a text data to send. + /// A that represents the text data to send. /// public void SendTo (string servicePath, string id, string data) { - SendTo (servicePath, id, data, null); + WebSocketServiceHost host; + if (TryGetServiceHost (servicePath, out host)) + host.Sessions.SendTo (id, data); } /// - /// Sends a binary to the client associated with the specified - /// and . + /// Sends a binary asynchronously to the client + /// associated with the specified and + /// . /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// A that contains an absolute path to the WebSocket service to find. + /// A that represents the absolute path to the WebSocket + /// service to find. /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// /// - /// An array of that contains a binary data to send. + /// An array of that contains the 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. + /// A passed to this delegate is true if the send is + /// complete successfully; otherwise, false. /// - public void SendTo (string servicePath, string id, byte [] data, Action completed) + public void SendToAsync ( + string servicePath, string id, byte [] data, Action completed) { WebSocketServiceHost host; if (TryGetServiceHost (servicePath, out host)) - host.Sessions.SendTo (id, data, completed); + host.Sessions.SendToAsync (id, data, completed); } /// - /// Sends a text to the client associated with the specified - /// and . + /// Sends a text asynchronously to the client + /// associated with the specified and + /// . /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// A that contains an absolute path to the WebSocket service to find. + /// A that represents the absolute path to the WebSocket + /// service to find. /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// /// - /// A that contains a text data to send. + /// A that represents the text 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. + /// A passed to this delegate is true if the send is + /// complete successfully; otherwise, false. /// - public void SendTo (string servicePath, string id, string data, Action completed) + public void SendToAsync ( + string servicePath, string id, string data, Action completed) { WebSocketServiceHost host; if (TryGetServiceHost (servicePath, out host)) - host.Sessions.SendTo (id, data, completed); + host.Sessions.SendToAsync (id, data, completed); } /// - /// Sends a binary data from the specified to the client associated with - /// the specified and . + /// Sends a binary data from the specified asynchronously + /// to the client associated with the specified + /// and . /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// A that contains an absolute path to the WebSocket service to find. + /// A that represents the absolute path to the WebSocket + /// service to find. /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// /// - /// A object from which contains a binary data to send. + /// A object from which contains the binary data to send. /// /// - /// An that contains the number of bytes to send. - /// - public void SendTo (string servicePath, string id, Stream stream, int length) - { - SendTo (servicePath, id, stream, length, null); - } - - /// - /// Sends a binary data from the specified to the client associated with - /// the specified and . - /// - /// - /// This method does not wait for the send to be complete. - /// - /// - /// A that contains an absolute path to the WebSocket service to find. - /// - /// - /// A that contains a session ID that represents the destination - /// for the data. - /// - /// - /// A object from which contains a binary data to send. - /// - /// - /// An that contains the number of bytes to send. + /// An that represents the number of bytes 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. + /// A passed to this delegate is true if the send is + /// complete successfully; otherwise, false. /// - public void SendTo ( + public void SendToAsync ( string servicePath, string id, Stream stream, int length, Action completed) { WebSocketServiceHost host; if (TryGetServiceHost (servicePath, out host)) - host.Sessions.SendTo (id, stream, length, completed); + host.Sessions.SendToAsync (id, stream, length, completed); } /// diff --git a/websocket-sharp/Server/WebSocketSessionManager.cs b/websocket-sharp/Server/WebSocketSessionManager.cs index 00ce5f8e..d4dcbb95 100644 --- a/websocket-sharp/Server/WebSocketSessionManager.cs +++ b/websocket-sharp/Server/WebSocketSessionManager.cs @@ -4,8 +4,8 @@ * * The MIT License * - * Copyright (c) 2012-2013 sta.blockhead - * + * Copyright (c) 2012-2014 sta.blockhead + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -15,7 +15,7 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -706,148 +706,124 @@ namespace WebSocketSharp.Server } /// - /// Sends a binary to the client associated with the specified - /// . + /// Sends a binary to the client associated with the + /// specified . /// - /// - /// This method does not wait for the send to be complete. - /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// /// - /// An array of that contains a binary data to send. + /// An array of that contains the binary data to send. /// public void SendTo (string id, byte [] data) { - SendTo (id, data, null); + IWebSocketSession session; + if (TryGetSession (id, out session)) + session.Context.WebSocket.Send (data); } /// - /// Sends a text to the client associated with the specified - /// . + /// Sends a text to the client associated with the + /// specified . /// - /// - /// This method does not wait for the send to be complete. - /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// /// - /// A that contains a text data to send. + /// A that represents the text data to send. /// public void SendTo (string id, string data) - { - SendTo (id, data, null); - } - - /// - /// Sends a binary to the client associated with the specified - /// . - /// - /// - /// This method does not wait for the send to be complete. - /// - /// - /// A that contains a session ID that represents the destination - /// for the data. - /// - /// - /// An array of that 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 void SendTo (string id, byte [] data, Action completed) { IWebSocketSession session; if (TryGetSession (id, out session)) - session.Context.WebSocket.Send (data, completed); + session.Context.WebSocket.Send (data); } /// - /// Sends a text to the client associated with the specified - /// . - /// - /// - /// This method does not wait for the send to be complete. - /// - /// - /// A that contains a session ID that represents the destination - /// for the data. - /// - /// - /// A that contains a text 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 void SendTo (string id, string data, Action completed) - { - IWebSocketSession session; - if (TryGetSession (id, out session)) - session.Context.WebSocket.Send (data, completed); - } - - /// - /// Sends a binary data from the specified to the client + /// Sends a binary asynchronously to the client /// associated with the specified . /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't wait for the send to be complete. /// /// - /// A that contains a session ID that represents the destination - /// for the data. + /// A that represents the session ID that represents the + /// destination for the data. /// - /// - /// A object from which contains a binary data to send. - /// - /// - /// An that contains the number of bytes to send. - /// - public void SendTo (string id, Stream stream, int length) - { - SendTo (id, stream, length, null); - } - - /// - /// Sends a binary data from the specified to the client - /// associated with the specified . - /// - /// - /// This method does not wait for the send to be complete. - /// - /// - /// A that contains a session ID that represents the destination - /// for the data. - /// - /// - /// A object from which contains a binary data to send. - /// - /// - /// An that contains the number of bytes to send. + /// + /// An array of that contains the 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. + /// A passed to this delegate is true if the send is + /// complete successfully; otherwise, false. /// - public void SendTo ( + public void SendToAsync (string id, byte [] data, Action completed) + { + IWebSocketSession session; + if (TryGetSession (id, out session)) + session.Context.WebSocket.SendAsync (data, completed); + } + + /// + /// Sends a text asynchronously to the client + /// associated with the specified . + /// + /// + /// This method doesn't wait for the send to be complete. + /// + /// + /// A that represents the session ID that represents the + /// destination for the data. + /// + /// + /// A that represents the text 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 void SendToAsync (string id, string data, Action completed) + { + IWebSocketSession session; + if (TryGetSession (id, out session)) + session.Context.WebSocket.SendAsync (data, completed); + } + + /// + /// Sends a binary data from the specified asynchronously + /// to the client associated with the specified . + /// + /// + /// This method doesn't wait for the send to be complete. + /// + /// + /// A that represents the session ID that represents the + /// destination for the data. + /// + /// + /// A object from which contains the binary data to send. + /// + /// + /// An that represents the number of bytes 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 void SendToAsync ( string id, Stream stream, int length, Action completed) { IWebSocketSession session; if (TryGetSession (id, out session)) - session.Context.WebSocket.Send (stream, length, completed); + session.Context.WebSocket.SendAsync (stream, length, completed); } /// diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 1d50cc42..770ea2a4 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -1055,8 +1055,7 @@ namespace WebSocketSharp private bool send (byte [] frameAsBytes) { - if (_readyState != WebSocketState.OPEN) - { + if (_readyState != WebSocketState.OPEN) { var msg = "A WebSocket connection isn't established or has been closed."; _logger.Error (msg); error (msg); @@ -1070,22 +1069,25 @@ namespace WebSocketSharp // As client private void send (HandshakeRequest request) { - _logger.Debug (String.Format ( - "A WebSocket connection request to {0}:\n{1}", _uri, request)); + _logger.Debug ( + String.Format ( + "A WebSocket connection request to {0}:\n{1}", _uri, request)); + _stream.WriteHandshake (request); } // As server private bool send (HandshakeResponse response) { - _logger.Debug ("A response to a WebSocket connection request:\n" + response.ToString ()); + _logger.Debug ( + "A response to the WebSocket connection request:\n" + response.ToString ()); + return _stream.WriteHandshake (response); } private bool send (WsFrame frame) { - if (_readyState != WebSocketState.OPEN) - { + if (_readyState != WebSocketState.OPEN) { var msg = "A WebSocket connection isn't established or has been closed."; _logger.Error (msg); error (msg); @@ -1098,23 +1100,22 @@ namespace WebSocketSharp private bool send (Opcode opcode, byte [] data) { - lock (_forSend) - { + lock (_forSend) { var sent = false; try { var compressed = false; - if (_compression != CompressionMethod.NONE) - { + if (_compression != CompressionMethod.NONE) { data = data.Compress (_compression); compressed = true; } - sent = send (WsFrame.CreateFrame ( - Fin.FINAL, opcode, _client ? Mask.MASK : Mask.UNMASK, data, compressed)); + var mask = _client ? Mask.MASK : Mask.UNMASK; + sent = send ( + WsFrame.CreateFrame (Fin.FINAL, opcode, mask, data, compressed)); } catch (Exception ex) { _logger.Fatal (ex.ToString ()); - error ("An exception has occurred."); + error ("An exception has occurred while sending a data."); } return sent; @@ -1123,24 +1124,22 @@ namespace WebSocketSharp private bool send (Opcode opcode, Stream stream) { - lock (_forSend) - { + lock (_forSend) { var sent = false; - var src = stream; var compressed = false; try { - if (_compression != CompressionMethod.NONE) - { + if (_compression != CompressionMethod.NONE) { stream = stream.Compress (_compression); compressed = true; } - sent = sendFragmented (opcode, stream, _client ? Mask.MASK : Mask.UNMASK, compressed); + var mask = _client ? Mask.MASK : Mask.UNMASK; + sent = sendFragmented (opcode, stream, mask, compressed); } catch (Exception ex) { _logger.Fatal (ex.ToString ()); - error ("An exception has occurred."); + error ("An exception has occurred while sending a data."); } finally { if (compressed) @@ -1153,47 +1152,48 @@ namespace WebSocketSharp } } - private void send (Opcode opcode, byte [] data, Action completed) + private void sendAsync (Opcode opcode, byte [] data, Action completed) { Func sender = send; - AsyncCallback callback = ar => - { - try { - var sent = sender.EndInvoke (ar); - if (completed != null) - completed (sent); - } - catch (Exception ex) - { - _logger.Fatal (ex.ToString ()); - error ("An exception has occurred."); - } - }; - - sender.BeginInvoke (opcode, data, callback, null); + 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 send (Opcode opcode, Stream stream, Action completed) + private void sendAsync (Opcode opcode, Stream stream, Action completed) { Func sender = send; - AsyncCallback callback = ar => - { - try { - var sent = sender.EndInvoke (ar); - if (completed != null) - completed (sent); - } - catch (Exception ex) - { - _logger.Fatal (ex.ToString ()); - error ("An exception has occurred."); - } - }; - - sender.BeginInvoke (opcode, stream, callback, null); + 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) + private bool sendFragmented ( + Opcode opcode, Stream stream, Mask mask, bool compressed) { var len = stream.Length; if (sendFragmented (opcode, stream, len, mask, compressed) == len) @@ -1219,12 +1219,12 @@ namespace WebSocketSharp byte [] buffer = null; // Not fragment - if (quo == 0) - { + if (quo == 0) { buffer = new byte [rem]; readLen = stream.Read (buffer, 0, rem); if (readLen == rem && - send (WsFrame.CreateFrame (Fin.FINAL, opcode, mask, buffer, compressed))) + send ( + WsFrame.CreateFrame (Fin.FINAL, opcode, mask, buffer, compressed))) sentLen = readLen; return sentLen; @@ -1235,17 +1235,18 @@ namespace WebSocketSharp // First readLen = stream.Read (buffer, 0, FragmentLength); if (readLen == FragmentLength && - send (WsFrame.CreateFrame (Fin.MORE, opcode, mask, buffer, compressed))) + send ( + WsFrame.CreateFrame (Fin.MORE, opcode, mask, buffer, compressed))) sentLen = readLen; else return sentLen; // Mid - for (long i = 0; i < count; i++) - { + for (long i = 0; i < count; i++) { readLen = stream.Read (buffer, 0, FragmentLength); if (readLen == FragmentLength && - send (WsFrame.CreateFrame (Fin.MORE, Opcode.CONT, mask, buffer, compressed))) + send ( + WsFrame.CreateFrame (Fin.MORE, Opcode.CONT, mask, buffer, compressed))) sentLen += readLen; else return sentLen; @@ -1258,7 +1259,8 @@ namespace WebSocketSharp readLen = stream.Read (buffer, 0, tmpLen); if (readLen == tmpLen && - send (WsFrame.CreateFrame (Fin.FINAL, Opcode.CONT, mask, buffer, compressed))) + send ( + WsFrame.CreateFrame (Fin.FINAL, Opcode.CONT, mask, buffer, compressed))) sentLen += readLen; return sentLen; @@ -1864,66 +1866,13 @@ 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. + /// An array of that contains the binary data to send. /// - public void Send (byte[] data) - { - Send (data, null); - } - - /// - /// Sends a binary data from the specified - /// using the WebSocket connection. - /// - /// - /// This method does not wait for the send to be complete. - /// - /// - /// A from which contains a binary data to send. - /// - public void Send (FileInfo file) - { - Send (file, 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) - { - Send (data, null); - } - - /// - /// 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 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 Send (byte [] data, Action completed) + public void Send (byte [] data) { var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData (); - if (msg != null) - { + if (msg != null) { _logger.Error (msg); error (msg); @@ -1934,64 +1883,45 @@ namespace WebSocketSharp if (len <= FragmentLength) send ( Opcode.BINARY, - len > 0 && _client && _compression == CompressionMethod.NONE ? data.Copy (len) : data, - completed); + len > 0 && _client && _compression == CompressionMethod.NONE + ? data.Copy (len) + : data); else - send (Opcode.BINARY, new MemoryStream (data), completed); + send (Opcode.BINARY, new MemoryStream (data)); } /// - /// Sends a binary data from the specified - /// 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 from which contains a binary data to send. + /// A from which contains the 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 void Send (FileInfo file, Action completed) + public void Send (FileInfo file) { var msg = _readyState.CheckIfOpen () ?? (file == null ? "'file' must not be null." : null); - if (msg != null) - { + if (msg != null) { _logger.Error (msg); error (msg); return; } - send (Opcode.BINARY, file.OpenRead (), completed); + send (Opcode.BINARY, file.OpenRead ()); } /// /// 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. + /// A that represents the text 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 void Send (string data, Action completed) + public void Send (string data) { var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData (); - if (msg != null) - { + if (msg != null) { _logger.Error (msg); error (msg); @@ -2000,41 +1930,20 @@ namespace WebSocketSharp var rawData = Encoding.UTF8.GetBytes (data); if (rawData.LongLength <= FragmentLength) - send (Opcode.TEXT, rawData, completed); + send (Opcode.TEXT, rawData); else - send (Opcode.TEXT, new MemoryStream (rawData), completed); + send (Opcode.TEXT, new MemoryStream (rawData)); } /// - /// Sends a binary data from the specified - /// using the WebSocket connection. + /// Sends a binary asynchronously using the WebSocket + /// connection. /// /// - /// This method does not wait for the send to be complete. + /// This method doesn't 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. - /// - public void Send (Stream stream, int length) - { - Send (stream, length, 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. - /// - /// - /// An that contains the number of bytes to send. + /// + /// An array of that contains the binary data to send. /// /// /// An Action<bool> delegate that references the method(s) called when @@ -2042,14 +1951,118 @@ namespace WebSocketSharp /// A passed to this delegate is true if the send is /// complete successfully; otherwise, false. /// - public void Send (Stream stream, int length, Action completed) + public void SendAsync (byte [] data, Action completed) + { + var msg = _readyState.CheckIfOpen () ?? data.CheckIfValidSendData (); + if (msg != null) { + _logger.Error (msg); + error (msg); + + 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); + } + + /// + /// Sends a binary data from the specified + /// asynchronously using the WebSocket connection. + /// + /// + /// This method doesn't wait for the send to be complete. + /// + /// + /// A from which contains the 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 void SendAsync (FileInfo file, Action completed) + { + var msg = _readyState.CheckIfOpen () ?? + (file == null ? "'file' must not be null." : null); + + if (msg != null) { + _logger.Error (msg); + error (msg); + + return; + } + + sendAsync (Opcode.BINARY, file.OpenRead (), completed); + } + + /// + /// Sends a text asynchronously using the WebSocket + /// connection. + /// + /// + /// This method doesn't wait for the send to be complete. + /// + /// + /// A that represents the text 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 void SendAsync (string data, Action completed) + { + 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) + sendAsync (Opcode.TEXT, rawData, completed); + else + sendAsync (Opcode.TEXT, new MemoryStream (rawData), completed); + } + + /// + /// Sends a binary data from the specified asynchronously + /// using the WebSocket connection. + /// + /// + /// This method doesn't wait for the send to be complete. + /// + /// + /// A object from which contains the binary data to send. + /// + /// + /// An that represents the number of bytes 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 void SendAsync (Stream stream, int length, Action completed) { var msg = _readyState.CheckIfOpen () ?? stream.CheckIfCanRead () ?? (length < 1 ? "'length' must be greater than 0." : null); - if (msg != null) - { + if (msg != null) { _logger.Error (msg); error (msg); @@ -2058,11 +2071,9 @@ namespace WebSocketSharp stream.ReadBytesAsync ( length, - data => - { + data => { var len = data.Length; - if (len == 0) - { + if (len == 0) { var err = "A data cannot be read from 'stream'."; _logger.Error (err); error (err); @@ -2071,10 +2082,11 @@ namespace WebSocketSharp } if (len < length) - _logger.Warn (String.Format ( - "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}", - length, - len)); + _logger.Warn ( + String.Format ( + "A data with 'length' cannot be read from 'stream'.\nexpected: {0} actual: {1}", + length, + len)); var sent = len <= FragmentLength ? send (Opcode.BINARY, data) @@ -2083,10 +2095,9 @@ namespace WebSocketSharp if (completed != null) completed (sent); }, - ex => - { + ex => { _logger.Fatal (ex.ToString ()); - error ("An exception has occurred."); + error ("An exception has occurred while sending a data."); }); }