private async void ListenerOnMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) { object outObj; if (CoreApplication.Properties.TryGetValue("remotePeer", out outObj)) { EchoMessage((RemotePeer)outObj, args); return; } // We do not have an output stream yet so create one. try { IOutputStream outputStream = await listener.GetOutputStreamAsync(args.RemoteAddress, args.RemotePort); // It might happen that the OnMessage was invoked more than once before the GetOutputStreamAsync completed. // In this case we will end up with multiple streams - make sure we have just one of it. RemotePeer peer; lock (this) { if (CoreApplication.Properties.TryGetValue("remotePeer", out outObj)) { peer = (RemotePeer)outObj; } else { peer = new RemotePeer(outputStream, args.RemoteAddress, args.RemotePort); CoreApplication.Properties.Add("remotePeer", peer); } } EchoMessage(peer, args); } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } // NotifyUserFromAsyncThread("Connect failed with error: " + exception.Message, NotifyType.ErrorMessage); } }
async void EchoMessage(RemotePeer peer, DatagramSocketMessageReceivedEventArgs eventArguments) { if (!peer.IsMatching(eventArguments.RemoteAddress, eventArguments.RemotePort)) { // In the sample we are communicating with just one peer. To communicate with multiple peers application // should cache output streams (i.e. by using a hash map), because creating an output stream for each // received datagram is costly. Keep in mind though, that every cache requires logic to remove old // or unused elements; otherwise cache turns into a memory leaking structure. //NotifyUserFromAsyncThread(String.Format("Got datagram from {0}:{1}, but already 'connected' to {3}", eventArguments.RemoteAddress, eventArguments.RemotePort, peer), NotifyType.ErrorMessage); } try { var reader = eventArguments.GetDataReader(); var size = reader.UnconsumedBufferLength; StringBuilder sb = new StringBuilder(); while (reader.UnconsumedBufferLength > 0) { var b = reader.ReadByte(); sb.Append((char) b); } var msg = sb.ToString(); if (msg.StartsWith("VS:")) { msg = msg.Substring(3); var colon = msg.IndexOf(':'); var typename = msg.Substring(0, colon); var equals = msg.IndexOf('='); var ip = msg.Substring(colon + 1, equals - colon - 1); var name = msg.Substring(equals + 1); var colon2 = name.IndexOf(':'); if (colon2 > -1) { name = name.Substring(0, colon2); } if (string.IsNullOrWhiteSpace(name)) { name = $"({typename}):{ip}"; } var port = peer.Port; var portColon = ip.IndexOf(':'); if (portColon > -1) { port = ip.Substring(portColon + 1); ip = ip.Substring(0, portColon); } peer.IP = ip; peer.Name = name; peer.Message = msg; peer.Pinged = DateTime.Now; peer.OriginalPort = peer.Port; peer.Port = port; var connection = new Connection(name, peer); if (!clients.ContainsKey(ip)) { clients[ip] = connection; } } } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } } }
async void EchoMessage(RemotePeer peer, DatagramSocketMessageReceivedEventArgs eventArguments) { if (!peer.IsMatching(eventArguments.RemoteAddress, eventArguments.RemotePort)) { // In the sample we are communicating with just one peer. To communicate with multiple peers application // should cache output streams (i.e. by using a hash map), because creating an output stream for each // received datagram is costly. Keep in mind though, that every cache requires logic to remove old // or unused elements; otherwise cache turns into a memory leaking structure. //NotifyUserFromAsyncThread(String.Format("Got datagram from {0}:{1}, but already 'connected' to {3}", eventArguments.RemoteAddress, eventArguments.RemotePort, peer), NotifyType.ErrorMessage); } try { var reader = eventArguments.GetDataReader(); var size = reader.UnconsumedBufferLength; StringBuilder sb = new StringBuilder(); while (reader.UnconsumedBufferLength > 0) { var b = reader.ReadByte(); sb.Append((char)b); } var msg = sb.ToString(); if (msg.StartsWith("VS:")) { msg = msg.Substring(3); var colon = msg.IndexOf(':'); var typename = msg.Substring(0, colon); var equals = msg.IndexOf('='); var ip = msg.Substring(colon + 1, equals - colon - 1); var name = msg.Substring(equals + 1); var colon2 = name.IndexOf(':'); if (colon2 > -1) { name = name.Substring(0, colon2); } if (string.IsNullOrWhiteSpace(name)) { name = $"({typename}):{ip}"; } var port = peer.Port; var portColon = ip.IndexOf(':'); if (portColon > -1) { port = ip.Substring(portColon + 1); ip = ip.Substring(0, portColon); } peer.IP = ip; peer.Name = name; peer.Message = msg; peer.Pinged = DateTime.Now; peer.OriginalPort = peer.Port; peer.Port = port; var connection = new Connection(name, peer); if (!clients.ContainsKey(ip)) { clients[ip] = connection; } } } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } } }