/// <summary> /// Checks if the other Client/Host has disconnected and /// automatically closes the Host/Client Socket connection if disconnected. /// </summary> /// <param name="reloadedSocket"></param> /// <returns></returns> public static void CloseIfDisconnected(this ReloadedSocket reloadedSocket) { if (reloadedSocket.IsSocketConnected() == false) { reloadedSocket.Socket.Close(); } }
/// <summary> /// Callback for the BeginSend asynchronous method. /// Asynchronously sends data in the buffer to the target client. /// </summary> /// <param name="asyncResult"></param> private static void SendAsyncCallback(IAsyncResult asyncResult) { try { // Get our reloadedSocket back. ReloadedSocket clientSocket = (ReloadedSocket)asyncResult.AsyncState; // End the send operation. int bytesSent = clientSocket.Socket.EndSend(asyncResult); // Increment the amount of bytes sent. clientSocket.AsyncSentBytes += bytesSent; // Loop back if not all of the data was sent. if (clientSocket.AsyncSentBytes < clientSocket.AsyncBytesToSend) { // Begin sending the rest of the message. clientSocket.Socket.BeginSend(clientSocket.DataToSend, clientSocket.AsyncSentBytes, clientSocket.DataToSend.Length - clientSocket.AsyncSentBytes, SocketFlags.None, SendAsyncCallback, clientSocket); return; } // Else reset the bytes that are to be sent/received. clientSocket.AsyncBytesToSend = 0; clientSocket.AsyncSentBytes = 0; } catch { // Get our reloadedSocket back. ReloadedSocket clientSocket = (ReloadedSocket)asyncResult.AsyncState; clientSocket.AsyncBytesToSend = 0; clientSocket.AsyncSentBytes = 0; } }
/// <summary> /// Send the data in a byte array to the server. /// Expects a delegate to be assigned to ProcessBytesMethod which will handle the data. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> /// <param name="message">The message that is to be sent to the server.</param> /// <param name="awaitResponse">Set true to wait for a response from the server, else false.</param> /// <param name="receiveDataDelegate">The method to call to process the received data from the server/client.</param> public static void SendData(this ReloadedSocket reloadedSocket, Message.MessageStruct message, bool awaitResponse, ProcessBytesDelegate receiveDataDelegate) { // Call the other overload and get our data back. Message.MessageStruct messageLocal = SendData(reloadedSocket, message, awaitResponse); // If we want a response from the client, receive it, copy to a buffer array and send it back to the method delegate linked to the method we want to process the outcome with. if (awaitResponse) { receiveDataDelegate(messageLocal, reloadedSocket); } }
/// <summary> /// Send the data in a byte array to the server. /// Expects a delegate to be assigned to ProcessBytesMethod which will handle the data. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> /// <param name="message">The message that is to be sent to the server.</param> /// <param name="awaitResponse">Set true to wait for a response from the server, else false.</param> public static Message.MessageStruct SendData(this ReloadedSocket reloadedSocket, Message.MessageStruct message, bool awaitResponse) { try { // Return empty message if socket not connected. if (!reloadedSocket.Socket.Connected) { return(null); } // Convert the message struct into bytes to send. byte[] data = message.BuildMessage(); // Get the amount of bytes sent. int bytesSent = 0; // Ensure we send all bytes. while (bytesSent < data.Length) { // Offset: Bytes Sent // Length to Send: Length to send - Already Sent int bytesSuccessfullySent = reloadedSocket.Socket.Send(data, bytesSent, data.Length - bytesSent, SocketFlags.None); // Send serialized Message! bytesSent += bytesSuccessfullySent; // If the reloadedSocket is not connected, return empty message struct. if (bytesSuccessfullySent == 0) { if (!IsSocketConnected(reloadedSocket)) { return(null); } } } // If we want a response from the client, receive it, copy to a buffer array and send it back to the method delegate linked to the method we want to process the outcome with. if (awaitResponse) { return(ReceiveData(reloadedSocket)); } return(null); } catch // Probably lost connection. { reloadedSocket.CloseIfDisconnected(); return(null); } }
/// <summary> /// Polls the reloadedSocket, returns true if the reloadedSocket is cononected, else false. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object to check.</param> public static bool IsSocketConnected(this ReloadedSocket reloadedSocket) { // First check if reloadedSocket itself reports as connected. if (!reloadedSocket.Socket.Connected) { return(false); } // Poll the reloadedSocket and check if there is anything readible. if (reloadedSocket.Socket.Poll(1000, SelectMode.SelectRead) && (reloadedSocket.Socket.Available == 0)) { return(false); } return(true); }
/// <summary> /// Send the data in a byte array to the server. /// Expects a delegate to be assigned to ProcessBytesMethod which will handle the data. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> /// <param name="message">The message that is to be sent to the server.</param> public static void SendDataAsync(this ReloadedSocket reloadedSocket, Message.MessageStruct message) { try { // Return empty message if socket not connected. if (!reloadedSocket.Socket.Connected) { return; } // Convert the message struct into bytes to send. reloadedSocket.DataToSend = message.BuildMessage(); // Set sent bytes to 0. reloadedSocket.AsyncBytesToSend = reloadedSocket.DataToSend.Length; reloadedSocket.AsyncSentBytes = 0; // Begin sending the message. reloadedSocket.Socket.BeginSend(reloadedSocket.DataToSend, 0, reloadedSocket.DataToSend.Length, SocketFlags.None, SendAsyncCallback, reloadedSocket); } catch { reloadedSocket.CloseIfDisconnected(); } }
/// <summary> /// Waits for data to be received from the websocket host. /// Can be used to wait for a response from the server in question. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> /// <param name="receiveDataDelegate">The method to call to process the received data from the server/client.</param> public static void ReceiveData(this ReloadedSocket reloadedSocket, ProcessBytesDelegate receiveDataDelegate) { // ReceiveData using the other overload, but instead of passing // the result back, call the receive data delegate. receiveDataDelegate(ReceiveData(reloadedSocket), reloadedSocket); }
/// <summary> /// Waits for data to be received from the websocket host. /// Can be used to wait for a response from the server in question. /// This version returns the result from the host as a byte array. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> public static Message.MessageStruct ReceiveData(this ReloadedSocket reloadedSocket) { try { // Return empty message if socket not connected. if (!reloadedSocket.Socket.Connected) { return(null); } // ReceiveData the information from the host onto the buffer. // ClientSocket.Receive() returns the data length, stored here. int bytesToReceive = sizeof(uint); int bytesReceived = 0; bytesReceived += reloadedSocket.Socket.Receive(reloadedSocket.ReceiveBuffer, bytesToReceive, SocketFlags.None); // Receive packets until all information is acquired. while (bytesReceived < bytesToReceive) { // Receive extra bytes int newBytesReceived = reloadedSocket.Socket.Receive(reloadedSocket.ReceiveBuffer, bytesReceived, bytesToReceive - bytesReceived, SocketFlags.None); bytesReceived += newBytesReceived; // If the reloadedSocket is not connected, return empty message struct. if (newBytesReceived == 0) { if (!IsSocketConnected(reloadedSocket)) { return(null); } } } // Get the true length of the message to be received. bytesToReceive = BitConverter.ToInt32(reloadedSocket.ReceiveBuffer, 0); bytesReceived = 0; // Increase buffer size if necessary. bool messageTooLarge = false; if (bytesToReceive > reloadedSocket.ReceiveBuffer.Length) { reloadedSocket.ReceiveBuffer = new byte[bytesToReceive]; messageTooLarge = true; } // Receive packets until all information is acquired. while (bytesReceived < bytesToReceive) { // Receive extra bytes int newBytesReceived = reloadedSocket.Socket.Receive(reloadedSocket.ReceiveBuffer, bytesReceived, bytesToReceive - bytesReceived, SocketFlags.None); bytesReceived += newBytesReceived; // If the reloadedSocket is not connected, return empty message struct. if (newBytesReceived == 0) { if (!IsSocketConnected(reloadedSocket)) { return(null); } } } // Create a receive buffer with our own data length to be received. byte[] receiveBuffer = new byte[bytesToReceive]; // Copy the received data into the buffer. Array.Copy(reloadedSocket.ReceiveBuffer, receiveBuffer, bytesToReceive); // Convert Received Bytes into a Message Struct Message.MessageStruct receivedData = Message.ParseMessage(receiveBuffer); // Reset buffer size to smaller (for Garbage Collector to pick up old buffer) if (messageTooLarge) { reloadedSocket.ReceiveBuffer = new byte[reloadedSocket.DefaultBufferSize]; } // Process the received bytes. return(receivedData); } catch // Probably lost connection. { reloadedSocket.CloseIfDisconnected(); return(null); } }