using System; using System.Text; using System.Threading; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Protocol; namespace Aitex.Sorter.RT.EFEMs.Servers { public class RData { public string StartMark { get; set; } public string EndMark { get; set; } public string Key { get; set; } public byte[] BodyBuffer { get; set; } public string BodyString { get; set; } } public class RRequestInfo : RequestInfo { public RRequestInfo(string key, RData data) { Initialize(key, data); } } public class RReceiveFilter : IReceiveFilter { public int leftBufferSize; public Encoding Encoder = Encoding.GetEncoding("gbk"); public string StartMark = "!Start"; public string EndMark = "$End"; public RReceiveFilter(Encoding encoder, string startMark, string endMark) { Encoder = encoder; StartMark = startMark; EndMark = endMark; } public RRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { rest = 0; byte[] startMarkBuffer = Encoder.GetBytes(StartMark); byte[] endMarkBuffer = Encoder.GetBytes(EndMark); if (length < startMarkBuffer.Length + endMarkBuffer.Length) return null; byte[] data = new byte[length]; Buffer.BlockCopy(readBuffer, offset, data, 0, length); string receiveStartMark = Encoder.GetString(data, 0, startMarkBuffer.Length); string receiveEndMark = Encoder.GetString(data, length - endMarkBuffer.Length, endMarkBuffer.Length); RData receiveData = new RData(); receiveData.StartMark = StartMark; receiveData.Key = Guid.NewGuid().ToString("B"); receiveData.BodyBuffer = new byte[length - startMarkBuffer.Length - endMarkBuffer.Length]; Buffer.BlockCopy(data, startMarkBuffer.Length, receiveData.BodyBuffer, 0, length - startMarkBuffer.Length - endMarkBuffer.Length); receiveData.EndMark = EndMark; receiveData.BodyString = Encoder.GetString(receiveData.BodyBuffer); leftBufferSize = length - startMarkBuffer.Length - endMarkBuffer.Length; if (!receiveStartMark.Equals(StartMark) || !receiveEndMark.Equals(EndMark)) return null; return new RRequestInfo(receiveData.Key, receiveData); } public int LeftBufferSize { get { return leftBufferSize; } } /// /// /// public SuperSocket.SocketBase.Protocol.IReceiveFilter NextReceiveFilter { get { return this; } } public void Reset() { } public SuperSocket.SocketBase.Protocol.FilterState State { get; private set; } } public class RReceiveFilterFactory : SuperSocket.SocketBase.Protocol.IReceiveFilterFactory { /// /// 字符编码 /// public Encoding Encoder = Encoding.GetEncoding("gbk"); public string StartMark = "!Start"; public string EndMark = "$End"; public RReceiveFilterFactory(Encoding encoder, string startMark, string endMark) { Encoder = encoder; StartMark = startMark; EndMark = endMark; } public SuperSocket.SocketBase.Protocol.IReceiveFilter CreateFilter(SuperSocket.SocketBase.IAppServer appServer, SuperSocket.SocketBase.IAppSession appSession, System.Net.IPEndPoint remoteEndPoint) { return new RReceiveFilter(Encoder, StartMark, EndMark); } } public class RAppSession : SuperSocket.SocketBase.AppSession { public uint DeviceUDID; protected override void HandleException(Exception e) { } } public class InvalidPackageException : ApplicationException { public InvalidPackageException(string msg) : base(msg) { } public override string Message { get { return base.Message; } } } public class RAppServer : SuperSocket.SocketBase.AppServer { public static Encoding Encoder = Encoding.GetEncoding("gbk"); public static string StartMark = string.Empty; public static string EndMark = ";\r"; public RAppServer() : base(new RReceiveFilterFactory(Encoder, StartMark, EndMark)) { } public RAppServer(Encoding encoder, string startMark, string endMark) : base(new RReceiveFilterFactory(encoder, startMark, endMark)) { RAppServer.Encoder = encoder; RAppServer.StartMark = startMark; RAppServer.EndMark = endMark; } } public interface IEfemServerSocketCallback { void OnConnected(string sessionId); void OnDisconnected(string sessionId); void OnReceived(string msg); } public class EfemServerSocket { private RAppServer _server = null; private static Object _lockerSession = new Object(); private RAppSession _session = null; private string _endMark; private IEfemServerSocketCallback _callback; private int _port; private bool _isFirstTimeReadyInfoMessage = true; public EfemServerSocket(IEfemServerSocketCallback callback, int port, string endMark = ";\r") { _endMark = endMark; _callback = callback; _port = port; _server = new RAppServer(Encoding.ASCII, string.Empty, _endMark); _server.NewSessionConnected += OnNewSessionConnected; _server.SessionClosed += OnSessionClosed; _server.NewRequestReceived += OnReceive; } public void Send(string msg) { if (_session != null) { if (!msg.StartsWith("INFO:READY") || (msg.StartsWith("INFO:READY") && _isFirstTimeReadyInfoMessage)) { EV.PostInfoLog("Server", string.Format("[Send] {0};", msg)); _isFirstTimeReadyInfoMessage = false; } lock (_lockerSession) { _session.Send(string.Format("{0};\r", msg)); } } else { LOG.Write($"Session is null, can not send out {msg}"); } } void OnNewSessionConnected(RAppSession session) { EV.PostInfoLog("Server", string.Format("Client {0} connected", session.SessionID)); lock (_lockerSession) { if (_session != null) { EV.PostWarningLog("Server", string.Format("New connection in, previous connection {0} removed", _session.SessionID)); _session.Close(); } _session = session; } _callback.OnConnected(_session.SessionID); } void OnSessionClosed(RAppSession session, CloseReason reason) { EV.PostInfoLog("Server", $"Client {session.SessionID} Disconnected, {reason}"); lock (_lockerSession) { if (_session != null && _session.SessionID == session.SessionID) { _session = null; } } _callback.OnDisconnected(session.SessionID); } void OnReceive(RAppSession session, RRequestInfo requestInfo) { string msgOrigin = requestInfo.Body.BodyString; EV.PostInfoLog("Server", string.Format("[Recv] {0};", msgOrigin)); string[] cmdList = msgOrigin.Split(new char[] {';', '\r'}, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < cmdList.Length; i++) { _callback.OnReceived(cmdList[i]); Thread.Sleep(50); } } public bool Start(string server, int port) { _server.Stop(); if (_server.State == ServerState.NotInitialized) { if (!_server.Setup(server, port)) { EV.PostAlarmLog("Server", $"Can not create server {server}:{port}"); return false; } } if (!_server.Start()) { EV.PostAlarmLog("Server", $"Can not listen on {server}:{port}"); return false; } EV.PostInfoLog("Server", $"Listen on {server}:{port}"); return true; } public void Stop() { if (_session != null) { lock (_lockerSession) { _session.Close(); } } _server.Stop(); EV.PostInfoLog("EFEM", $"Stopped Listen on {_port}"); } } }