using NetCoreServer; using Newtonsoft.Json; using OnlineUserPool.Model; using OnlineUserPool.Unility; using Serilog; using System; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; namespace OnlineUserPool.Services { public class TcpService : IService { private PfTcpServer _server; public void Close() { } public void RunServer(Action action, Action disconnected = null) { _server = new PfTcpServer(IPAddress.Any, ConfigHelp.TcpPort, (ip, model) => { action(ip, model, this); }, disconnected); _server.Start(); } public void Send(byte[] dgram, int bytes, IPEndPoint endPoint) { if (dgram == null || !dgram.Any()) { return; } var session = _server.FindSession(endPoint); if (session is { IsConnected: true }) { session.SendAsync(dgram); } } private class PfTcpServer : TcpServer { private Action _action; private Action _disconnected; public PfTcpServer(IPAddress address, int port, Action action, Action disconnected = null) : base(address, port) { _action = action; _disconnected = disconnected; } protected override TcpSession CreateSession() { return new PfTcpSession(this, _action); } protected override void OnError(SocketError error) { //base.OnError(error); Debug.WriteLine(error); } public TcpSession FindSession(IPEndPoint ip) { try { var item = this.Sessions.Values.FirstOrDefault(t => t.Socket.Connected && t.Socket.RemoteEndPoint.ToString() == ip.ToString()); return item; } catch (Exception e) { Log.Error( $"Fail to FindSession:{e}"); return null; } } protected override void OnDisconnected(TcpSession session) { var currentSession = (session as PfTcpSession); if (currentSession?.IPEndPoint != null) { _disconnected?.Invoke(currentSession.IPEndPoint); } base.OnDisconnected(session); } } private class PfTcpSession : TcpSession { Action _action; public IPEndPoint IPEndPoint { get; private set; } public PfTcpSession(TcpServer server, Action action) : base(server) { _action = action; } protected override void OnConnected() { base.OnConnected(); Debug.WriteLine("有新的Tcp连接"); IPEndPoint = IPEndPoint.Parse(this.Socket.RemoteEndPoint.ToString()); } protected override void OnDisconnected() { base.OnDisconnected(); Debug.WriteLine("Tcp断开连接"); } private readonly StringBuilder _dataBuffer = new StringBuilder(); protected override void OnReceived(byte[] buffer, long offset, long size) { var data = string.Empty; try { data = Encoding.UTF8.GetString(buffer, (int)offset, (int)size); foreach (var item in data) { this._dataBuffer.Append(item); if (item != '}') continue; Debug.WriteLine("收到消息:" + this._dataBuffer); var s = this._dataBuffer.ToString(); var msg = JsonConvert.DeserializeObject(s); var ipEndPoint = IPEndPoint.Parse(this.Socket.RemoteEndPoint.ToString()); switch (msg.CommandType) { case 1: _action(ipEndPoint, JsonConvert.DeserializeObject(s)); break; case 2: _action(ipEndPoint, JsonConvert.DeserializeObject(s)); break; case 3: switch (msg.SubType) { case 0: _action(ipEndPoint,JsonConvert.DeserializeObject(s)); break; case 1: _action(ipEndPoint,JsonConvert.DeserializeObject(s)); break; case 2: _action(ipEndPoint,JsonConvert.DeserializeObject(s)); break; case 3: _action(ipEndPoint,JsonConvert.DeserializeObject(s)); break; case 4: _action(ipEndPoint,JsonConvert.DeserializeObject(s)); break; case 5: _action(ipEndPoint,JsonConvert.DeserializeObject(s)); break; case 6: _action(ipEndPoint,JsonConvert.DeserializeObject(s)); break; } break; default: _action(ipEndPoint, msg); break; } this._dataBuffer.Clear(); s = null; } } catch (Exception ex) { Log.Error($"接受到的数据处理时出错:{data}\r\n{ex.Message}\r\n{ex.StackTrace}"); } data = null; } protected override void OnError(SocketError error) { //base.OnError(error); Debug.WriteLine(error); } } } }