using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ChatRoomServer.Main { using System.Collections.Concurrent; using System.Net; using System.Timers; using ChatRoomServer.Main.Room; using FSLib.Logs.Log4Net; using FSLib.Network.Http; using FSLib.Network.SuperSocket.Protocols.WebSocket; using FSLib.Network.SuperSocket.SocketBase; using Newtonsoft.Json; class ChatServer : WebSocketServer { static ILog _log; static readonly object _lockObject = new object(); internal static HashSet PresetAdministrators = (System.Configuration.ConfigurationManager.AppSettings["chat:admin"] ?? "").Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).ToHashSet(StringComparer.OrdinalIgnoreCase); static ChatServer() { FSLib.Logs.Log4NetBootStraper.Initialize("log4net.server.config", "Server"); _log = GetLogger(typeof(ChatServer).Name); } ConcurrentDictionary _containers = new ConcurrentDictionary(); ConcurrentDictionary _roomContainers = new ConcurrentDictionary(); internal static ILog GetLogger(string name) { return LogManager.GetLogger("Server", name); } /// /// Called when [started]. /// protected override void OnStarted() { base.OnStarted(); NewSessionConnected += ChatServer_NewSessionConnected; NewDataReceived += ChatServer_NewDataReceived; SessionClosed += ChatServer_SessionClosed; InitOnlineCountSync(); } #region 在线人数上报 System.Timers.Timer _syncOnlineCountTimer; void InitOnlineCountSync() { _syncOnlineCountTimer = new Timer(60 * 1000); _syncOnlineCountTimer.AutoReset = false; _syncOnlineCountTimer.Elapsed += (s, e) => { UploadOnlineCount(); _syncOnlineCountTimer.Start(); }; } void UploadOnlineCount() { var datas = _roomContainers.ToArray(); var data = new { data = JsonConvert.SerializeObject(datas.Select(s => new { id = s.Key, count = s.Value.SessionCount }).ToArray()) }; var client = new HttpClient(); string url; #if DEBUG url = "http://chatdev.fishlee.net/api/room/updateOnlineCount"; #else url = "http://127.0.0.1/api/room/updateOnlineCount"; #endif var ctx = client.Create(HttpMethod.Post, url, data: data).Send(); if (ctx.IsValid()) { _log.Info("同步房间在线人数成功。"); } else { _log.InfoFormat("同步房间在线人数失败。错误信息:" + (ctx.Exception?.Message ?? "") + ",状态码:" + (ctx.Status ?? HttpStatusCode.Unused)); } } #endregion private void ChatServer_SessionClosed(ChatSession session, CloseReason value) { RoomContainer roomContainer; if (_containers.TryRemove(session, out roomContainer)) { roomContainer.Remove(session); if (roomContainer.SessionCount == 0) { _roomContainers.TryRemove(roomContainer.Id, out roomContainer); } } } private void ChatServer_NewSessionConnected(ChatSession session) { var cmd = session.Command; if (cmd == "room" && session.PathSegements.Length >= 4) { var roomid = session.Id; //TODO check roomid var roomCtx = _roomContainers.GetOrAdd(roomid, _ => new RoomContainer(_)); _containers.AddOrUpdate(session, roomCtx); roomCtx.Add(session); //send online count } else { session.Close(CloseReason.ProtocolError); } } private void ChatServer_NewDataReceived(ChatSession session, byte[] value) { session.ProcessData(value); } } }