using System.Collections.Concurrent; using System.Net; using System.Net.WebSockets; using System.Text; namespace SimpleWebChat.ConHost { public static class SimpleWebChatServerModule { private static readonly ConcurrentDictionary TextChatSessions = new(); private static readonly List HistoryMessage = new(); public static void ProcessRequest(HttpListenerContext context, int currentSessionId) { WebSocket sck = null; try { var wsc = context.AcceptWebSocketAsync("swcp").Result; Console.WriteLine($"Request #{currentSessionId:00000} TextChat WebSocket Session Start"); sck = TextChatSessions[currentSessionId] = wsc.WebSocket; var buffer = new byte[1024]; var r = sck.ReceiveAsync(buffer, default).Result; var s = Encoding.UTF8.GetString(buffer, 0, r.Count); byte[][] copy; lock (HistoryMessage) copy = HistoryMessage.ToArray(); foreach (var item in copy) { sck.SendAsync(item, WebSocketMessageType.Text, true, default).Wait(); } sck.BroadCastFaf($"SYS{Environment.NewLine}" + $" Session #{currentSessionId:X4}({s}) Connected.{Environment.NewLine}" + $" Now number of online session: {TextChatSessions.Count}"); while (true) { r = sck.ReceiveAsync(buffer, default).Result; if (r.Count == 0) { break; } else { s = Encoding.UTF8.GetString(buffer, 0, r.Count); sck.BroadCastFaf($"#{currentSessionId:X4}{Environment.NewLine} {s}"); } } } catch (Exception) { try { if (sck != null && sck.State != WebSocketState.Aborted) { sck.CloseAsync(WebSocketCloseStatus.InternalServerError, "Error", default).Wait(); } } catch (Exception e) { Console.WriteLine(e); } } TextChatSessions.TryRemove(currentSessionId, out _); sck.BroadCastFaf($"SYS{Environment.NewLine}" + $" Session #{currentSessionId:X4} Disconnected.{Environment.NewLine}" + $" Now number of online session: {TextChatSessions.Count}"); } private static void BroadCastFaf(this WebSocket sck, string content) { var now = DateTime.Now; string text = $"{now} {content}"; var buf = Encoding.UTF8.GetBytes(text); lock (HistoryMessage) { HistoryMessage.Add(buf); while (HistoryMessage.Count >= ConfigFile.Instance.HistoryMessageLength) { HistoryMessage.RemoveAt(0); } } var all = TextChatSessions.Values.ToArray(); foreach (var s in all) { try { s.SendAsync(text); } catch { //FUCK ERR } } } private static Task SendAsync(this WebSocket sck, string text) => sck.SendAsync(Encoding.UTF8.GetBytes(text), WebSocketMessageType.Text, true, default); } }