2015-07-01 16:18:25 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace ChatRoomServer.Main
|
|
|
|
|
{
|
|
|
|
|
using System.Collections.Concurrent;
|
2015-07-08 17:24:45 +08:00
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Timers;
|
2015-07-01 16:18:25 +08:00
|
|
|
|
using ChatRoomServer.Main.Room;
|
|
|
|
|
using FSLib.Logs.Log4Net;
|
2015-07-08 17:24:45 +08:00
|
|
|
|
using FSLib.Network.Http;
|
2015-07-01 16:18:25 +08:00
|
|
|
|
using FSLib.Network.SuperSocket.Protocols.WebSocket;
|
|
|
|
|
using FSLib.Network.SuperSocket.SocketBase;
|
2015-07-08 17:24:45 +08:00
|
|
|
|
using Newtonsoft.Json;
|
2015-07-01 16:18:25 +08:00
|
|
|
|
|
|
|
|
|
class ChatServer : WebSocketServer<ChatSession>
|
|
|
|
|
{
|
|
|
|
|
static ILog _log;
|
|
|
|
|
static readonly object _lockObject = new object();
|
2015-07-08 20:49:11 +08:00
|
|
|
|
internal static HashSet<string> PresetAdministrators = (System.Configuration.ConfigurationManager.AppSettings["chat:admin"] ?? "").Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
2015-07-01 16:18:25 +08:00
|
|
|
|
|
|
|
|
|
static ChatServer()
|
|
|
|
|
{
|
|
|
|
|
FSLib.Logs.Log4NetBootStraper.Initialize("log4net.server.config", "Server");
|
|
|
|
|
_log = GetLogger(typeof(ChatServer).Name);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 17:24:45 +08:00
|
|
|
|
ConcurrentDictionary<ChatSession, RoomContainer> _containers = new ConcurrentDictionary<ChatSession, RoomContainer>();
|
|
|
|
|
ConcurrentDictionary<string, RoomContainer> _roomContainers = new ConcurrentDictionary<string, RoomContainer>();
|
2015-07-01 16:18:25 +08:00
|
|
|
|
|
|
|
|
|
internal static ILog GetLogger(string name)
|
|
|
|
|
{
|
|
|
|
|
return LogManager.GetLogger("Server", name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when [started].
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected override void OnStarted()
|
|
|
|
|
{
|
|
|
|
|
base.OnStarted();
|
|
|
|
|
|
|
|
|
|
NewSessionConnected += ChatServer_NewSessionConnected;
|
2015-07-08 17:24:45 +08:00
|
|
|
|
NewDataReceived += ChatServer_NewDataReceived;
|
2015-07-01 16:18:25 +08:00
|
|
|
|
SessionClosed += ChatServer_SessionClosed;
|
2015-07-08 17:24:45 +08:00
|
|
|
|
|
|
|
|
|
InitOnlineCountSync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 在线人数上报
|
|
|
|
|
|
|
|
|
|
System.Timers.Timer _syncOnlineCountTimer;
|
|
|
|
|
|
|
|
|
|
void InitOnlineCountSync()
|
|
|
|
|
{
|
|
|
|
|
_syncOnlineCountTimer = new Timer(60 * 1000);
|
|
|
|
|
_syncOnlineCountTimer.AutoReset = false;
|
|
|
|
|
_syncOnlineCountTimer.Elapsed += (s, e) =>
|
|
|
|
|
{
|
|
|
|
|
UploadOnlineCount();
|
|
|
|
|
_syncOnlineCountTimer.Start();
|
|
|
|
|
};
|
2015-07-01 16:18:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-08 17:24:45 +08:00
|
|
|
|
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<string>(HttpMethod.Post, url, data: data).Send();
|
|
|
|
|
|
|
|
|
|
if (ctx.IsValid())
|
|
|
|
|
{
|
|
|
|
|
_log.Info("同步房间在线人数成功。");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_log.InfoFormat("同步房间在线人数失败。错误信息:" + (ctx.Exception?.Message ?? "") + ",状态码:" + (ctx.Status ?? HttpStatusCode.Unused));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2015-07-01 16:18:25 +08:00
|
|
|
|
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;
|
|
|
|
|
|
2015-07-08 17:24:45 +08:00
|
|
|
|
if (cmd == "room" && session.PathSegements.Length >= 4)
|
2015-07-01 16:18:25 +08:00
|
|
|
|
{
|
|
|
|
|
var roomid = session.Id;
|
|
|
|
|
|
|
|
|
|
//TODO check roomid
|
|
|
|
|
|
|
|
|
|
var roomCtx = _roomContainers.GetOrAdd(roomid, _ => new RoomContainer(_));
|
|
|
|
|
_containers.AddOrUpdate(session, roomCtx);
|
|
|
|
|
roomCtx.Add(session);
|
|
|
|
|
|
2015-07-08 17:24:45 +08:00
|
|
|
|
//send online count
|
2015-07-01 16:18:25 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
session.Close(CloseReason.ProtocolError);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ChatServer_NewDataReceived(ChatSession session, byte[] value)
|
|
|
|
|
{
|
2015-07-08 17:24:45 +08:00
|
|
|
|
session.ProcessData(value);
|
2015-07-01 16:18:25 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|