/// <summary> /// Send a message. /// </summary> public void SendMessage(string stringToSend) { //If we have tried to send a zero length string we just return if (stringToSend.Trim() == "") return; //We may or may not have entered some server connection information ConnectionInfo serverConnectionInfo = null; if (ServerIPAddress != "") { try { serverConnectionInfo = new ConnectionInfo(ServerIPAddress, ServerPort); } catch (Exception) { ShowMessage("Failed to parse the server IP and port. Please ensure it is correct and try again"); return; } } //We wrap everything we want to send in the ChatMessage class we created ChatMessage chatMessage = new ChatMessage(NetworkComms.NetworkIdentifier, LocalName, stringToSend, messageSendIndex++); //We add our own message to the message history in case it gets relayed back to us lock (lastPeerMessageDict) lastPeerMessageDict[NetworkComms.NetworkIdentifier] = chatMessage; //We write our own message to the chatBox AppendLineToChatHistory(chatMessage.SourceName + " - " + chatMessage.Message); //Clear the input box text ClearInputLine(); //If we provided server information we send to the server first if (serverConnectionInfo != null) { //We perform the send within a try catch to ensure the application continues to run if there is a problem. try { if (ConnectionType == ConnectionType.TCP) TCPConnection.GetConnection(serverConnectionInfo).SendObject("ChatMessage", chatMessage); else if (ConnectionType == ConnectionType.UDP) UDPConnection.GetConnection(serverConnectionInfo, UDPOptions.None).SendObject("ChatMessage", chatMessage); else throw new Exception("An invalid connectionType is set."); } catch (CommsException) { AppendLineToChatHistory("Error: A communication error occurred while trying to send message to " + serverConnectionInfo + ". Please check settings and try again."); } catch (Exception) { AppendLineToChatHistory("Error: A general error occurred while trying to send message to " + serverConnectionInfo + ". Please check settings and try again."); } } //If we have any other connections we now send the message to those as well //This ensures that if we are the server everyone who is connected to us gets our message //We want a list of all established connections not including the server if set List<ConnectionInfo> otherConnectionInfos; if (serverConnectionInfo != null) otherConnectionInfos = (from current in NetworkComms.AllConnectionInfo() where current.RemoteEndPoint != serverConnectionInfo.RemoteEndPoint select current).ToList(); else otherConnectionInfos = NetworkComms.AllConnectionInfo(); foreach (ConnectionInfo info in otherConnectionInfos) { //We perform the send within a try catch to ensure the application continues to run if there is a problem. try { if (ConnectionType == ConnectionType.TCP) TCPConnection.GetConnection(info).SendObject("ChatMessage", chatMessage); else if (ConnectionType == ConnectionType.UDP) UDPConnection.GetConnection(info, UDPOptions.None).SendObject("ChatMessage", chatMessage); else throw new Exception("An invalid connectionType is set."); } catch (CommsException) { AppendLineToChatHistory("Error: A communication error occurred while trying to send message to " + info + ". Please check settings and try again."); } catch (Exception) { AppendLineToChatHistory("Error: A general error occurred while trying to send message to " + info + ". Please check settings and try again."); } } return; }
public static void Deserialize(System.IO.Stream inputStream, out ChatMessage result) { result = new ChatMessage(); result.Deserialize(inputStream); }
/// <summary> /// Performs whatever functions we might so desire when we receive an incoming ChatMessage /// </summary> /// <param name="header">The PacketHeader corresponding with the received object</param> /// <param name="connection">The Connection from which this object was received</param> /// <param name="incomingMessage">The incoming ChatMessage we are after</param> protected virtual void HandleIncomingChatMessage(PacketHeader header, Connection connection, ChatMessage incomingMessage) { //We only want to write a message once to the chat window //Because we support relaying and may receive the same message twice from multiple sources //we use our history and message indexes to ensure we have a new message //We perform this action within a lock as HandleIncomingChatMessage could be called in parallel lock (lastPeerMessageDict) { if (lastPeerMessageDict.ContainsKey(incomingMessage.SourceIdentifier)) { if (lastPeerMessageDict[incomingMessage.SourceIdentifier].MessageIndex < incomingMessage.MessageIndex) { //If this message index is greater than the last seen from this source we can safely //write the message to the ChatBox AppendLineToChatHistory(incomingMessage.SourceName + " - " + incomingMessage.Message); //We now replace the last received message with the current one lastPeerMessageDict[incomingMessage.SourceIdentifier] = incomingMessage; } } else { //If we have never had a message from this source before then it has to be new //by definition lastPeerMessageDict.Add(incomingMessage.SourceIdentifier, incomingMessage); AppendLineToChatHistory(incomingMessage.SourceName + " - " + incomingMessage.Message); } } //This last section of the method is the relay feature //We start by checking to see if this message has already been relayed the maximum number of times if (incomingMessage.RelayCount < relayMaximum) { //If we are going to relay this message we need an array of //all known connections, excluding the current one var allRelayConnections = (from current in NetworkComms.GetExistingConnection() where current != connection select current).ToArray(); //We increment the relay count before we send incomingMessage.IncrementRelayCount(); //We now send the message to every other connection foreach (var relayConnection in allRelayConnections) { //We ensure we perform the send within a try catch //To ensure a single failed send will not prevent the //relay to all working connections. try { relayConnection.SendObject("ChatMessage", incomingMessage); } catch (CommsException) { /* Catch the general comms exception, ignore and continue */ } } } }