2025-03-28 09:49:56 +08:00

228 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"];
/// <summary>
/// 存储日志的数据库连接字符串151orcl数据库
/// </summary>
string _OracleConnStr = ConfigurationManager.AppSettings["OracleConnStr"].ToString();
WebSocketServer SocketServer { get; set; }
/// <summary>
/// 在线用户列表
/// </summary>
List<SocketUserModel> SocketSessionList { get; set; }
public SocketService()
{
InitializeComponent();
}
#region ->
/// <summary>
/// 启动服务事件
/// </summary>
/// <param name="args"></param>
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 ->
/// <summary>
/// 关闭服务事件
/// </summary>
protected override void OnStop()
{
if (SocketServer.State == SuperSocket.SocketBase.ServerState.Running)
{
SocketServer.Stop();
}
SocketServer.Dispose();
}
#endregion
#region ->
/// <summary>
/// 新的客户端连入时的事件
/// </summary>
/// <param name="session"></param>
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<SocketUserModel>();
}
SocketSessionList.Add(socketUserModel);
//通知收银机服务端在线
session.Send("online");
//发送离线消息给收银机
WebSocketHelper.SendOfflineMsgToRemotePoint(SocketSessionList, session, socketUserModel, _OracleConnStr);
}
#endregion
#region ->
/// <summary>
/// 客户端断开连接时的事件
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
private void SocketServer_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value)
{
try
{
List<SocketUserModel> 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 ->
/// <summary>
/// 新的数据传入时的事件数据内容为byte数组
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
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("///------------发送结束------------///");
}
}
/// <summary>
/// 新的消息传入时的事件(数据内容为字符串)
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
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
}
}