2023-08-01 10:55:45 +08:00
|
|
|
|
using NetCoreServer;
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using OnlineUserPool.Model;
|
2021-01-18 20:24:19 +08:00
|
|
|
|
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
|
|
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
private PfTcpServer _server;
|
2021-01-18 20:24:19 +08:00
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
public void Close()
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
public void RunServer(Action<IPEndPoint, ReceiveModel, IService> action, Action<EndPoint> disconnected = null)
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
_server = new PfTcpServer(IPAddress.Any, ConfigHelp.TcpPort, (ip, model) => { action(ip, model, this); },
|
|
|
|
|
|
disconnected);
|
2021-01-18 20:24:19 +08:00
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
_server.Start();
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
public void Send(byte[] dgram, int bytes, IPEndPoint endPoint)
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
if (dgram == null || !dgram.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var session = _server.FindSession(endPoint);
|
|
|
|
|
|
if (session is { IsConnected: true })
|
|
|
|
|
|
{
|
|
|
|
|
|
session.SendAsync(dgram);
|
|
|
|
|
|
}
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
private class PfTcpServer : TcpServer
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
private class PfTcpSession : TcpSession
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
Action<IPEndPoint, ReceiveModel> _action;
|
|
|
|
|
|
public IPEndPoint IPEndPoint { get; private set; }
|
|
|
|
|
|
|
|
|
|
|
|
public PfTcpSession(TcpServer server, Action<IPEndPoint, ReceiveModel> action) : base(server)
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
_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断开连接");
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
private readonly StringBuilder _dataBuffer = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
|
|
protected override void OnReceived(byte[] buffer, long offset, long size)
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
var data = string.Empty;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
data = Encoding.UTF8.GetString(buffer, (int)offset, (int)size);
|
|
|
|
|
|
foreach (var item in data)
|
2021-01-18 20:24:19 +08:00
|
|
|
|
{
|
2023-08-01 10:55:45 +08:00
|
|
|
|
this._dataBuffer.Append(item);
|
|
|
|
|
|
if (item != '}') continue;
|
|
|
|
|
|
Debug.WriteLine("收到消息:" + this._dataBuffer);
|
2024-02-01 16:49:22 +08:00
|
|
|
|
var s = this._dataBuffer.ToString();
|
|
|
|
|
|
var msg = JsonConvert.DeserializeObject<ReceiveModel>(s);
|
2023-08-01 10:55:45 +08:00
|
|
|
|
var ipEndPoint = IPEndPoint.Parse(this.Socket.RemoteEndPoint.ToString());
|
|
|
|
|
|
switch (msg.CommandType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint, JsonConvert.DeserializeObject<MsgModel>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint, JsonConvert.DeserializeObject<SetClientCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
switch (msg.SubType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint,JsonConvert.DeserializeObject<CreateGameRoomCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 1:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint,JsonConvert.DeserializeObject<JoinGameRoomCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint,JsonConvert.DeserializeObject<GameRoomReadyCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint,JsonConvert.DeserializeObject<GameRoomStartCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 4:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint,JsonConvert.DeserializeObject<GameRoomKickCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 5:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint,JsonConvert.DeserializeObject<GameRoomProcessCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case 6:
|
2024-02-01 16:49:22 +08:00
|
|
|
|
_action(ipEndPoint,JsonConvert.DeserializeObject<QueryGameRoomListCommand>(s));
|
2023-08-01 10:55:45 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
_action(ipEndPoint, msg);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
this._dataBuffer.Clear();
|
2024-02-01 16:49:22 +08:00
|
|
|
|
s = null;
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
2023-08-01 10:55:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Log.Error($"接受到的数据处理时出错:{data}\r\n{ex.Message}\r\n{ex.StackTrace}");
|
|
|
|
|
|
}
|
2024-02-01 16:49:22 +08:00
|
|
|
|
|
|
|
|
|
|
data = null;
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-01 10:55:45 +08:00
|
|
|
|
protected override void OnError(SocketError error)
|
|
|
|
|
|
{
|
|
|
|
|
|
//base.OnError(error);
|
|
|
|
|
|
Debug.WriteLine(error);
|
|
|
|
|
|
}
|
2021-01-18 20:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|