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
}
}