using SuperSocket.SocketBase; using SuperSocket.SocketBase.Protocol; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace StandardDomeNewApp.Communication.Sockets { public class SingleSocketServer { public SingleSocketServer(string encoding = null) { this.encoding = string.IsNullOrEmpty(encoding) ? Encoding.Default : Encoding.GetEncoding(encoding); } /// /// 服务类型 1是supersocket 2是iocp /// private int serverType { set; get; } /// /// 解码方式 /// public Encoding encoding { private set; get; } /// /// 服务对象 /// private AppServer appServer { set; get; } /// /// /// private socket.core.Server.TcpPushServer iocpServer { set; get; } /// /// /// private Regex regex { set; get; } = new Regex(@"^%.*|.*%$"); /// /// 会话字典 /// public Dictionary SessionIDDic { private set; get; } = new Dictionary(); /// /// 消息委托 /// public Action ShowMessageAction { set; get; } /// /// 接收消息委托 二进制数组的 /// public Action RequestReceivedAction { set; get; } /// /// 会话进来 /// public Action OnSessionAccept { set; get; } /// /// 会话结束 /// public Action OnSessionClose { set; get; } public bool IsOpenServer { private set; get; } public string ServerName { private set; get; } /// /// 是否允许接收字典 /// public ConcurrentDictionary IsAllowReceiveDic { set; get; } = new ConcurrentDictionary(); /// /// 会话数据字典 /// public ConcurrentDictionary SessionDataDic { set; get; } = new ConcurrentDictionary(); #region 方法 /// /// 启动服务 /// /// 服务端口 /// servertype为2时才有意义 结尾符 public void StartServer(string serverkey, int port, byte[] enddata = null) { ServerName = serverkey; if (enddata == null) { //当为空时使用iocp的方式 serverType = 2; iocpServer = new socket.core.Server.TcpPushServer(100, 1024 * 2, 0); if (ushort.TryParse(port.ToString(), out ushort port2)) { try { iocpServer.Start(port); } catch (Exception ex) { ShowMessageAction?.Invoke("启动失败!" + ex.Message, false, Core.SysEnumInfon.MessageLogType.Warn); } IsOpenServer = true; iocpServer.OnAccept += IocpServer_OnAccept; iocpServer.OnClose += IocpServer_OnClose; iocpServer.OnReceive += IocpServer_OnReceive; } else { ShowMessageAction?.Invoke("端口输入范围在:0-65535的值!", false, Core.SysEnumInfon.MessageLogType.Warn); } return; } //使用supersocket组件 serverType = 1; if (enddata.Length < 1) { appServer = new AppServer(); } else { appServer = new AppServer(new TerminatorReceiveFilterFactory(encoding.GetString(enddata))); } appServer.NewRequestReceived += AppServer_NewRequestReceived; appServer.NewSessionConnected += AppServer_NewSessionConnected; appServer.SessionClosed += AppServer_SessionClosed; var serverconfig = new SuperSocket.SocketBase.Config.ServerConfig(); serverconfig.Port = port; serverconfig.TextEncoding = encoding.EncodingName; if (ushort.TryParse(port.ToString(), out ushort port1)) { if (!appServer.Setup(serverconfig)) { ShowMessageAction?.Invoke("设置错误!", false, Core.SysEnumInfon.MessageLogType.Warn); return; } if (!appServer.Start()) { ShowMessageAction?.Invoke("启动失败!", false, Core.SysEnumInfon.MessageLogType.Warn); return; } IsOpenServer = true; } else { ShowMessageAction?.Invoke("端口输入范围在:0-65535的值!", false, Core.SysEnumInfon.MessageLogType.Warn); } } /// /// 结束服务 /// public void StopServer() { if (!IsOpenServer) { ShowMessageAction?.Invoke("当前状态不需要断开监听!", false, Core.SysEnumInfon.MessageLogType.Info); return; } if (serverType == 1) { appServer.Stop(); appServer.Dispose(); appServer = null; } else if (serverType == 2) { var dic = new Dictionary(iocpServer.ClientList); foreach (var item in dic) { iocpServer.Close(item.Key); } } IsOpenServer = false; } /// /// 会话发送 /// /// /// 为空时为广播 public void SessionSend(byte[] datas, string sessionid = null) { if (datas == null || datas.Length < 1) { ShowMessageAction?.Invoke("数据为空,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info); return; } if (string.IsNullOrEmpty(sessionid)) { if (serverType == 1) { var allsessions = appServer.GetAllSessions(); foreach (var item in allsessions) { item.Send(encoding.GetString(datas)); } } else if (serverType == 2) { foreach (var item in iocpServer.ClientList) { iocpServer.Send(item.Key, datas, 0, datas.Length); } } } else { if (serverType == 1) { var one = appServer.GetSessionByID(sessionid); if (one != null) { one.Send(encoding.GetString(datas)); } else { ShowMessageAction?.Invoke("请检查传入的会话ID是否有效!当前无法查询到相关会话信息,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info); } } else if (serverType == 2) { if (int.TryParse(sessionid, out int num) && iocpServer.ClientList.ContainsKey(num)) { iocpServer.Send(num, datas, 0, datas.Length); } else { ShowMessageAction?.Invoke("请检查传入的会话ID是否有效!当前无法查询到相关会话信息,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info); } } } } /// /// 会话发送 /// /// /// 为空时为广播 public void SessionSend(string datas, string sessionid = null) { if (string.IsNullOrEmpty(datas)) { ShowMessageAction?.Invoke("数据为空,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info); return; } if (string.IsNullOrEmpty(sessionid)) { if (serverType == 1) { var allsessions = appServer.GetAllSessions(); foreach (var item in allsessions) { item.Send(datas); } } else if (serverType == 2) { foreach (var item in iocpServer.ClientList) { iocpServer.Send(item.Key, encoding.GetBytes(datas), 0, datas.Length); } } } else { if (serverType == 1) { var one = appServer.GetSessionByID(sessionid); if (one != null) { one.Send(datas); } else { ShowMessageAction?.Invoke("请检查传入的会话ID是否有效!当前无法查询到相关会话信息,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info); } } else if (serverType == 2) { if (int.TryParse(sessionid, out int num) && iocpServer.ClientList.ContainsKey(num)) { iocpServer.Send(num, encoding.GetBytes(datas), 0, datas.Length); } else { ShowMessageAction?.Invoke("请检查传入的会话ID是否有效!当前无法查询到相关会话信息,无效发送!", false, Core.SysEnumInfon.MessageLogType.Info); } } } } /// /// 返回地址对应的sessionid 可能返回为空 /// /// /// public string GetSessionID(string ipaddress) { string sessionid = null; var datas = SessionIDDic.Where(d => d.Value == ipaddress); if (datas != null) { var list = datas.ToList(); if (list.Count > 0) { var oneitem = list.ElementAt(0); sessionid = oneitem.Key; } } return sessionid; } /// /// 返回id对应的地址 可能返回为空 /// /// /// public string GetIpAddress(string sessionid) { if (SessionIDDic.ContainsKey(sessionid)) { return SessionIDDic[sessionid]; } return null; } #endregion #region 事件 /// /// 会话关闭 /// /// /// private void AppServer_SessionClosed(AppSession session, CloseReason value) { if (SessionIDDic.ContainsKey(session.SessionID)) { SessionIDDic.Remove(session.SessionID); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("会话:"); stringBuilder.Append(session.SessionID); stringBuilder.Append("("); stringBuilder.Append(session.RemoteEndPoint.Address); stringBuilder.Append(":"); stringBuilder.Append(session.RemoteEndPoint.Port.ToString()); stringBuilder.Append(")"); stringBuilder.Append("关闭!关闭原因:"); stringBuilder.Append(value.ToString()); ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info); OnSessionClose?.Invoke(session.SessionID); } } private void IocpServer_OnClose(int obj) { if (SessionIDDic.ContainsKey(obj.ToString())) { SessionIDDic.Remove(obj.ToString()); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("会话:"); stringBuilder.Append(obj.ToString()); stringBuilder.Append("("); if (iocpServer.ClientList.ContainsKey(obj)) { stringBuilder.Append(iocpServer.ClientList[obj]); } stringBuilder.Append(")"); stringBuilder.Append("关闭!关闭原因:用户退出!"); ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info); OnSessionClose?.Invoke(obj.ToString()); } } /// /// 会话新连接 /// /// private void AppServer_NewSessionConnected(AppSession session) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(session.RemoteEndPoint.Address); stringBuilder.Append(":"); stringBuilder.Append(session.RemoteEndPoint.Port.ToString()); string info = stringBuilder.ToString(); //记录会话id与物理地址的关系 SessionIDDic[session.SessionID] = info; stringBuilder.Remove(0, stringBuilder.Length); stringBuilder.Append("新进会话:"); stringBuilder.Append(session.SessionID); stringBuilder.Append("("); stringBuilder.Append(info); stringBuilder.Append(")"); ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info); OnSessionAccept?.Invoke(session.SessionID); } /// /// 新的会话进来 /// /// private void IocpServer_OnAccept(int obj) { StringBuilder stringBuilder = new StringBuilder(); if (!iocpServer.ClientList.ContainsKey(obj)) { return; } stringBuilder.Append(iocpServer.ClientList[obj]); string info = stringBuilder.ToString(); //记录会话id与物理地址的关系 SessionIDDic[obj.ToString()] = info; stringBuilder.Remove(0, stringBuilder.Length); stringBuilder.Append("新进会话:"); stringBuilder.Append(obj.ToString()); stringBuilder.Append("("); stringBuilder.Append(info); stringBuilder.Append(")"); ShowMessageAction?.Invoke(stringBuilder.ToString(), false, Core.SysEnumInfon.MessageLogType.Info); OnSessionAccept?.Invoke(obj.ToString()); } /// /// 会话信息接收 /// /// /// private void AppServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo) { var sessionid = session.SessionID; var bdatas = requestInfo.Key + "%" + requestInfo.Body; if (string.IsNullOrEmpty(bdatas)) { //空数据不解析 return; } if (regex.IsMatch(bdatas)) { //如果有%在头或者尾 bdatas = bdatas.Replace("%", "").Trim(); } RequestReceivedAction(sessionid, bdatas); } /// /// 接收消息 /// /// /// private void IocpServer_OnReceive(int arg1, byte[] arg2) { RequestReceivedAction(arg1.ToString(), encoding.GetString(arg2)); } #endregion } }