powerfun-new-net/Services/TcpService.cs
2023-08-01 11:02:04 +08:00

199 lines
7.5 KiB
C#

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<IPEndPoint, ReceiveModel, IService> action, Action<EndPoint> 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<IPEndPoint, ReceiveModel> _action;
private Action<EndPoint> _disconnected;
public PfTcpServer(IPAddress address, int port, Action<IPEndPoint, ReceiveModel> action,
Action<EndPoint> 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<IPEndPoint, ReceiveModel> _action;
public IPEndPoint IPEndPoint { get; private set; }
public PfTcpSession(TcpServer server, Action<IPEndPoint, ReceiveModel> 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 msg = JsonConvert.DeserializeObject<ReceiveModel>(this._dataBuffer.ToString());
var ipEndPoint = IPEndPoint.Parse(this.Socket.RemoteEndPoint.ToString());
switch (msg.CommandType)
{
case 1:
_action(ipEndPoint, JsonConvert.DeserializeObject<MsgModel>(this._dataBuffer.ToString()));
break;
case 2:
_action(ipEndPoint, JsonConvert.DeserializeObject<SetClientCommand>(this._dataBuffer.ToString()));
break;
case 3:
switch (msg.SubType)
{
case 0:
_action(ipEndPoint,
JsonConvert.DeserializeObject<CreateGameRoomCommand>(this._dataBuffer.ToString()));
break;
case 1:
_action(ipEndPoint,
JsonConvert.DeserializeObject<JoinGameRoomCommand>(this._dataBuffer.ToString()));
break;
case 2:
_action(ipEndPoint,
JsonConvert.DeserializeObject<GameRoomReadyCommand>(this._dataBuffer.ToString()));
break;
case 3:
_action(ipEndPoint,
JsonConvert.DeserializeObject<GameRoomStartCommand>(this._dataBuffer.ToString()));
break;
case 4:
_action(ipEndPoint,
JsonConvert.DeserializeObject<GameRoomKickCommand>(this._dataBuffer.ToString()));
break;
case 5:
_action(ipEndPoint,
JsonConvert.DeserializeObject<GameRoomProcessCommand>(this._dataBuffer.ToString()));
break;
case 6:
_action(ipEndPoint,
JsonConvert.DeserializeObject<QueryGameRoomListCommand>(this._dataBuffer.ToString()));
break;
}
break;
default:
_action(ipEndPoint, msg);
break;
}
this._dataBuffer.Clear();
}
}
catch (Exception ex)
{
Log.Error($"接受到的数据处理时出错:{data}\r\n{ex.Message}\r\n{ex.StackTrace}");
}
}
protected override void OnError(SocketError error)
{
//base.OnError(error);
Debug.WriteLine(error);
}
}
}
}