using System; using System.Collections.Generic; using System.Configuration; using System.ServiceProcess; using System.Text; using SuperSocket.SocketBase.Config; using SuperSocket.WebSocket; using Newtonsoft.Json; using EShang.Common.GeneralMethod; using EShang.Common.Model; using HZQR.Common; namespace SocketService { public partial class SocketService : ServiceBase { protected static string ServicePort = ConfigurationManager.AppSettings["ServicePort"]; /// /// 存储日志的数据库连接字符串(151orcl数据库) /// string _OracleConnStr = ConfigurationManager.AppSettings["OracleConnStr"].ToString(); WebSocketServer SocketServer { get; set; } /// /// 在线用户列表 /// List SocketSessionList { get; set; } public SocketService() { InitializeComponent(); } #region 方法 -> 启动服务事件 /// /// 启动服务事件 /// /// protected override void OnStart(string[] args) { SocketServer = new WebSocketServer(); SocketServer.NewSessionConnected += SocketServer_NewSessionConnected; //当有新的客户端连入时的事件 SocketServer.NewMessageReceived += SocketServer_NewMessageReceived; //当有新的消息传入时的事件 SocketServer.NewDataReceived += SocketServer_NewDataReceived; //当有新的数据传入时的事件 SocketServer.SessionClosed += SocketServer_SessionClosed; //当有客户端断开连接时的事件 ServerConfig serverConfig = new ServerConfig { Name = "ESServer", ServerTypeName = "SServer", ClearIdleSession = true, //60秒执行一次清理90秒没数据传送的连接 ClearIdleSessionInterval = 60, IdleSessionTimeOut = 90,//会话连接超时时间(秒) //MaxRequestLength = 2048, //最大包长度 Ip = System.Net.IPAddress.Any.ToString(), Port = ServicePort.TryParseToInt(), MaxConnectionNumber = 100000 }; if (SocketServer.Setup(serverConfig)) { SocketServer.Start(); } } #endregion #region 方法 -> 关闭服务事件 /// /// 关闭服务事件 /// protected override void OnStop() { if (SocketServer.State == SuperSocket.SocketBase.ServerState.Running) { SocketServer.Stop(); } SocketServer.Dispose(); } #endregion #region 方法 -> 新的客户端连入时的事件 /// /// 新的客户端连入时的事件 /// /// private void SocketServer_NewSessionConnected(WebSocketSession session) { string LogCentent = string.Format("{0}上线,Path:" + session.Path, session.RemoteEndPoint); SocketUserModel socketUserModel = new SocketUserModel(); try { //解析收银机上线时,传输的地址参数,地址格式:地址?服务区编码&门店编码&机器编码 string sessionPath = session.Path.Contains("?") ? session.Path.Split('?')[1] : ""; if (!string.IsNullOrWhiteSpace(sessionPath)) { foreach (string ReqStr in sessionPath.Split('&')) { switch (ReqStr.Split('=')[0].ToLower()) { //服务区编码 case "serverpartcode": socketUserModel.ServerpartCode = ReqStr.Split('=')[1]; break; //解析门店编码 case "shopcode": socketUserModel.ShopCode = ReqStr.Split('=')[1]; break; //解析机器编码 case "machinecode": socketUserModel.MachineCode = ReqStr.Split('=')[1]; break; } } LogCentent = string.Format("收银机【服务区编码:{0},门店编码:{1},机器编号:{2}】已上线", socketUserModel.ServerpartCode, socketUserModel.ShopCode, socketUserModel.MachineCode); } LogUtil.WriteLog(null, LogCentent, DateTime.Now.ToString("yyyyMMdd") + "_on_off_line"); } catch (Exception ex) { LogUtil.WriteLog(ex, JsonConvert.SerializeObject(socketUserModel), DateTime.Now.ToString("yyyyMMdd") + "_online_ErrorLog"); } //存储在线机器对象UserSession socketUserModel.UserSession = session; if (SocketSessionList == null) { SocketSessionList = new List(); } SocketSessionList.Add(socketUserModel); //通知收银机服务端在线 session.Send("online"); //发送离线消息给收银机 WebSocketHelper.SendOfflineMsgToRemotePoint(SocketSessionList, session, socketUserModel, _OracleConnStr); } #endregion #region 方法 -> 客户端断开连接时的事件 /// /// 客户端断开连接时的事件 /// /// /// private void SocketServer_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value) { try { List SocketSessionListCopy = SocketSessionList; foreach (SocketUserModel socketUserModel in SocketSessionListCopy.FindAll( p => p.UserSession.RemoteEndPoint == session.RemoteEndPoint)) { LogUtil.WriteLog(null, string.Format("{0} {1}已下线", value, "【服务区编码:" + socketUserModel.ServerpartCode + ",门店编码:" + socketUserModel.ShopCode + ",机器编号:" + socketUserModel.MachineCode + "】"), DateTime.Now.ToString("yyyyMMdd") + "_on_off_line"); if (session != null) { //从在线机器列表中移除已下线的机器 SocketSessionList.Remove(socketUserModel); } } } catch (Exception ex) { LogUtil.WriteLog(ex, string.Format("{0} {1}下线", value, session.RemoteEndPoint), DateTime.Now.ToString("yyyyMMdd") + "_offline_ErrorLog"); } } #endregion #region 方法 -> 新的数据传入时的事件 /// /// 新的数据传入时的事件(数据内容为byte数组) /// /// /// private void SocketServer_NewDataReceived(WebSocketSession session, byte[] value) { string ReceivedStr = Encoding.UTF8.GetString(value); if (ReceivedStr.ToLower() == "state") { //收银机与服务端保持长链接,通讯标识为“state” //LogUtil.WriteLog(null, $"接收{ session.RemoteEndPoint }发送的消息:" + ReceivedStr, // DateTime.Now.ToString("yyyyMMdd") + "_state"); //通知收银系统服务端在线,可以正常通讯 WebSocketHelper.SendMsgToRemotePoint(SocketSessionList, session, "online", null); } else if (!string.IsNullOrWhiteSpace(ReceivedStr)) { //创建数据库连接 EShang.Common.OracleHelper _OracleHelper = new EShang.Common.OracleHelper(_OracleConnStr.Split(',')[0], _OracleConnStr.Split(',')[1], _OracleConnStr.Split(',')[2], _OracleConnStr.Split(',')[3]); //接收到新消息发送内容给收银机 WebSocketHelper.SendNewMsgToClient(SocketSessionList, session, ReceivedStr, _OracleHelper); LogUtil.WriteLog("///------------发送结束------------///"); } } /// /// 新的消息传入时的事件(数据内容为字符串) /// /// /// private void SocketServer_NewMessageReceived(WebSocketSession session, string value) { if (value.ToLower() == "state") { //收银机与服务端保持长链接,通讯标识为“state” //LogUtil.WriteLog(null, $"接收{ session.RemoteEndPoint }发送的消息:" + value, // DateTime.Now.ToString("yyyyMMdd") + "_state"); //返回收银系统,告知服务端在线 WebSocketHelper.SendMsgToRemotePoint(SocketSessionList, session, "online", null); } else if (!string.IsNullOrWhiteSpace(value)) { //创建数据库连接 EShang.Common.OracleHelper _OracleHelper = new EShang.Common.OracleHelper(_OracleConnStr.Split(',')[0], _OracleConnStr.Split(',')[1], _OracleConnStr.Split(',')[2], _OracleConnStr.Split(',')[3]); //接收到新消息发送内容给收银机 WebSocketHelper.SendNewMsgToClient(SocketSessionList, session, value, _OracleHelper); LogUtil.WriteLog("///------------发送结束------------///"); } } #endregion } }