static void DispatchNewMessage (Peer from, string message) { _MessageBuilder.Remove(0, _MessageBuilder.Length); if (from != null) { _MessageBuilder.Append("<"); _MessageBuilder.Append(from); _MessageBuilder.Append("> "); _MessageBuilder.Append(message); } else { _MessageBuilder.Append("*** "); _MessageBuilder.Append(message); } Messages.Add(new Message { From = from, Text = message, DisplayText = _MessageBuilder.ToString() }); if (Messages.Count > MaxMessagesToStore) { int numToRemove = MaxMessagesToStore / 2; Messages.RemoveRange(0, numToRemove); MessageIdBase += numToRemove; } if (WaitingForMessages != null) { WaitingForMessages.Complete(); WaitingForMessages = null; } }
static IEnumerator<object> AcceptConnectionsTask (TcpListener server) { server.Start(); try { int nextId = 0; while (true) { var connection = server.AcceptIncomingConnection(); yield return connection; Peer peer = new Peer { PeerId = nextId++ }; TcpClient client = connection.Result as TcpClient; client.Client.Blocking = false; var peerTask = PeerTask(client, peer); Scheduler.Start(peerTask, TaskExecutionPolicy.RunAsBackgroundTask); } } finally { server.Stop(); } }
static void PeerDisconnected (Peer peer) { if (!peer.Connected) return; Peers.Remove(peer); peer.Connected = false; Console.WriteLine("User {0} has disconnected", peer); DispatchNewMessage(null, String.Format("{0} has left the chat", peer)); }
static IEnumerator<object> PeerTask (TcpClient client, Peer peer) { var adapter = new SocketDataAdapter(client.Client, true); var input = new AsyncTextReader(adapter, Encoding.ASCII); var output = new AsyncTextWriter(adapter, Encoding.ASCII); adapter.ThrowOnDisconnect = false; adapter.ThrowOnFullSendBuffer = false; output.AutoFlush = true; peer.Input = input; peer.Output = output; yield return output.WriteLine("Welcome! Please enter your name."); string name = null; yield return input.ReadLine().Bind(() => name); if (name == null) { PeerDisconnected(peer); yield break; } peer.Name = name; PeerConnected(peer); yield return output.Write(VT100.EraseScreen); string nextLine = null; while (peer.Connected) { var f = input.ReadLine(); yield return f; if (!f.GetResult(out nextLine) || nextLine == null) { PeerDisconnected(peer); yield break; } if (nextLine.Length > 0) DispatchNewMessage(peer, nextLine); } }
static void PeerConnected (Peer peer) { if (peer.Connected) return; peer.Connected = true; Console.WriteLine("User {0} has connected", peer); DispatchNewMessage(null, String.Format("{0} has joined the chat", peer)); Peers.Add(peer); }