mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-27 02:36:14 +00:00
Tile服务器雏形..
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Google.Protobuf;
|
||||
using System;
|
||||
using Google.Protobuf;
|
||||
|
||||
namespace Plugins.JNGame.Network.Entity
|
||||
{
|
||||
@@ -27,6 +28,7 @@ namespace Plugins.JNGame.Network.Entity
|
||||
{
|
||||
_hId = hId;
|
||||
_id = id;
|
||||
_bytes = Array.Empty<byte>();
|
||||
}
|
||||
|
||||
//构造器
|
||||
|
@@ -59,8 +59,6 @@ namespace Plugins.JNGame.Network
|
||||
}
|
||||
|
||||
public virtual void SendBytes(byte[] data){ }
|
||||
|
||||
public abstract Task StartConnect();
|
||||
|
||||
//获取字节大小
|
||||
public int GetByteSize(int hId = 0)
|
||||
|
@@ -15,7 +15,7 @@ namespace Plugins.JNGame.Network
|
||||
public class JNServerParam
|
||||
{
|
||||
|
||||
public int Client;
|
||||
public string Client;
|
||||
|
||||
public byte[] Message;
|
||||
|
||||
|
@@ -26,7 +26,7 @@ namespace Plugins.JNGame.Network
|
||||
await StartConnect();
|
||||
}
|
||||
|
||||
public override async Task StartConnect()
|
||||
public async Task StartConnect()
|
||||
{
|
||||
|
||||
var url = $"{await this.GetUrl()}";
|
||||
|
@@ -2,96 +2,122 @@
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using Google.Protobuf;
|
||||
using Plugins.JNGame.Network;
|
||||
using Plugins.JNGame.Network.Action;
|
||||
using Plugins.JNGame.Network.Entity;
|
||||
using TestNetty.Client.Initializers;
|
||||
using Plugins.JNGame.Network.Util;
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
using UnityEngine;
|
||||
using NotImplementedException = System.NotImplementedException;
|
||||
|
||||
namespace Plugins.JNGame.Network
|
||||
namespace JNGame.Network
|
||||
{
|
||||
public class JNTCPClient : JNClientBase
|
||||
{
|
||||
|
||||
private IChannel clientChannel;
|
||||
private IEventLoopGroup group;
|
||||
private Bootstrap bootstrap;
|
||||
|
||||
public bool IsOpen => clientChannel is not null && clientChannel.Open;
|
||||
|
||||
private TcpClient tcpClient;
|
||||
public bool IsOpen => tcpClient is not null && tcpClient.Online;
|
||||
|
||||
|
||||
public override async Task OnInit()
|
||||
{
|
||||
tcpClient = new TcpClient();
|
||||
await tcpClient.SetupAsync(
|
||||
new TouchSocketConfig()
|
||||
.ConfigurePlugins(a =>
|
||||
{
|
||||
a.UseReconnection(-1, true, 1000); //如需永远尝试连接,tryCount设置为-1即可。
|
||||
})
|
||||
.SetTcpDataHandlingAdapter(() => new FixedHeaderPackageAdapter())
|
||||
);
|
||||
tcpClient.Connecting = OnConnecting;
|
||||
tcpClient.Connected = OnConnected;//成功连接到服务器
|
||||
tcpClient.Disconnected = OnDisconnected;//从服务器断开连接,当连接不成功时不会触发。
|
||||
tcpClient.Received = OnReceived;
|
||||
|
||||
await base.OnInit();
|
||||
|
||||
await StartConnect();
|
||||
|
||||
tcpClient.Connect(await GetEndPoint());
|
||||
}
|
||||
|
||||
public override async Task StartConnect()
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private Task OnConnecting(ITcpClient client, ConnectingEventArgs e)
|
||||
{
|
||||
|
||||
if (!isStart) return;
|
||||
await CloseNetty();
|
||||
|
||||
group = new MultithreadEventLoopGroup();
|
||||
bootstrap = new Bootstrap();
|
||||
bootstrap
|
||||
.Group(group)
|
||||
.Channel<TcpSocketChannel>()
|
||||
.Option(ChannelOption.TcpNodelay, true)
|
||||
.Handler(new TcpClientInitializer(this));
|
||||
|
||||
try
|
||||
{
|
||||
if (bootstrap is not null)
|
||||
{
|
||||
Debug.Log($"[JNTCPClient] 开始连接");
|
||||
clientChannel = await bootstrap.ConnectAsync( await GetEndPoint() );
|
||||
Debug.Log($"[JNTCPClient] 连接成功");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
Debug.Log($"[JNTCPClient] 连接失败 1s后重试");
|
||||
await UniTask.DelayFrame(1000);
|
||||
await StartConnect();
|
||||
}
|
||||
Debug.Log($"[JNTCPClient] 开始连接服务器");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
protected virtual async UniTask<IPEndPoint> GetEndPoint()
|
||||
|
||||
/// <summary>
|
||||
/// 成功连接到服务器
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private Task OnConnected(ITcpClient client, ConnectedEventArgs e)
|
||||
{
|
||||
await UniTask.NextFrame();
|
||||
return new IPEndPoint(IPAddress.Parse("127.0.0.1"),9001);
|
||||
Debug.Log($"[JNTCPClient] 服务器连接成功");
|
||||
Dispatch(new JNetParam(_id++,(int)NActionEnum.ClientConnect));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从服务器断开连接,当连接不成功时不会触发。
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private Task OnDisconnected(ITcpClientBase client, DisconnectEventArgs e)
|
||||
{
|
||||
Debug.Log($"[JNTCPClient] 服务器断开");
|
||||
Dispatch(new JNetParam(_id++,(int)NActionEnum.ClientDisconnect));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收到消息
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
private Task OnReceived(TcpClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
byte[] data = new byte[e.ByteBlock.Len];
|
||||
Array.Copy(e.ByteBlock.Buffer,data, data.Length);
|
||||
var param = NDataUtil.Parse(data);
|
||||
Dispatch(param);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
public override void SendBytes(byte[] data)
|
||||
{
|
||||
if (IsOpen)
|
||||
{
|
||||
tcpClient.Send(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void OnClose()
|
||||
{
|
||||
base.OnClose();
|
||||
CloseNetty();
|
||||
tcpClient.Close();
|
||||
}
|
||||
|
||||
private async Task CloseNetty()
|
||||
protected virtual async UniTask<string> GetEndPoint()
|
||||
{
|
||||
clientChannel?.CloseAsync();
|
||||
if (group is not null) await group.ShutdownGracefullyAsync();
|
||||
group = null;
|
||||
clientChannel = null;
|
||||
bootstrap = null;
|
||||
}
|
||||
|
||||
public override void Send(int hId, IMessage data = null)
|
||||
{
|
||||
base.Send(hId, data);
|
||||
if (IsOpen)
|
||||
{
|
||||
// clientChannel?.WriteAndFlushAsync(JNetParam.Build(this._id++, hId).SetData(data));
|
||||
}
|
||||
await UniTask.NextFrame();
|
||||
return "127.0.0.1:9001";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -1,70 +1,118 @@
|
||||
using System;
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using DotRecast.Core.Collections;
|
||||
using Google.Protobuf;
|
||||
using JNGame.Network.Netty.TCP;
|
||||
using Plugins.JNGame.Network;
|
||||
using Plugins.JNGame.Network.Action;
|
||||
using Plugins.JNGame.Network.Entity;
|
||||
using Plugins.JNGame.Network.Util;
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Sockets;
|
||||
using UnityEngine;
|
||||
|
||||
namespace JNGame.Network
|
||||
{
|
||||
public class JNTCPServer : JNServerBase
|
||||
{
|
||||
|
||||
private TcpService service;
|
||||
|
||||
private int _port = 0;
|
||||
private int _port;
|
||||
public int Port => _port;
|
||||
|
||||
private ServerBootstrap bootstrap;
|
||||
private IEventLoopGroup bossGroup;
|
||||
private IEventLoopGroup workerGroup;
|
||||
private IChannel channel;
|
||||
|
||||
private TcpServerInitializer server;
|
||||
|
||||
public override async Task OnInit()
|
||||
{
|
||||
|
||||
bossGroup = new MultithreadEventLoopGroup(1);
|
||||
workerGroup = new MultithreadEventLoopGroup(4);
|
||||
bootstrap = new ServerBootstrap();
|
||||
bootstrap.Group(bossGroup, workerGroup);
|
||||
bootstrap.Channel<TcpServerSocketChannel>();
|
||||
bootstrap
|
||||
.Option(ChannelOption.SoBacklog, 1024)
|
||||
//ByteBuf的分配器(重用缓冲区)大小
|
||||
.Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
|
||||
.Option(ChannelOption.RcvbufAllocator, new FixedRecvByteBufAllocator(1024 * 8))
|
||||
.ChildOption(ChannelOption.SoKeepalive, true) //保持长连接
|
||||
.ChildOption(ChannelOption.TcpNodelay, true) //端口复用
|
||||
.ChildOption(ChannelOption.SoReuseport, true)
|
||||
//自定义初始化Tcp服务
|
||||
.ChildHandler(server = new TcpServerInitializer(this));
|
||||
|
||||
await StartBind();
|
||||
|
||||
service = new TcpService();
|
||||
await service.SetupAsync(
|
||||
new TouchSocketConfig()
|
||||
.SetTcpDataHandlingAdapter(() => new FixedHeaderPackageAdapter())
|
||||
);
|
||||
service.Connecting = OnConnecting;//有客户端正在连接
|
||||
service.Connected = OnConnected;//有客户端连接
|
||||
service.Disconnected = OnDisconnected;//有客户端断开连接
|
||||
service.Received = OnReceived;//客户端接收到消息
|
||||
await service.StartAsync(_port = await GetPort());//启动
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected async Task StartBind()
|
||||
/// <summary>
|
||||
/// 有客户端正在连接
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
private Task OnConnecting(SocketClient client, ConnectingEventArgs e)
|
||||
{
|
||||
try
|
||||
Debug.Log($"[JNTCPServer] 有客户端正在连接");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有客户端连接
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private Task OnConnected(SocketClient client, ConnectedEventArgs e)
|
||||
{
|
||||
Debug.Log($"[JNTCPServer] 有客户端连接成功");
|
||||
Dispatch((int)NActionEnum.ClientConnect,new JNServerParam()
|
||||
{
|
||||
channel = await bootstrap.BindAsync(_port = await GetPort());
|
||||
Debug.Log($"[JNTCPServer] 服务器创建成功");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
Debug.Log($"[JNTCPServer] 服务器创建失败 1s后重试");
|
||||
await UniTask.DelayFrame(1000);
|
||||
await StartBind();
|
||||
}
|
||||
Client = client.Id
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有客户端断开连接
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private Task OnDisconnected(SocketClient client, DisconnectEventArgs e)
|
||||
{
|
||||
Debug.Log($"[JNTCPServer] 有客户端断开连接");
|
||||
Dispatch((int)NActionEnum.ClientDisconnect,new JNServerParam()
|
||||
{
|
||||
Client = client.Id
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 客户端接收到消息
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private async Task OnReceived(SocketClient client, ReceivedDataEventArgs e)
|
||||
{
|
||||
|
||||
byte[] data = new byte[e.ByteBlock.Len];
|
||||
Array.Copy(e.ByteBlock.Buffer,data, data.Length);
|
||||
var param = NDataUtil.Parse(data);
|
||||
Dispatch(param.HId,new JNServerParam()
|
||||
{
|
||||
Client = client.Id,
|
||||
Message = param.Bytes,
|
||||
});
|
||||
await UniTask.NextFrame();
|
||||
|
||||
}
|
||||
|
||||
public override void OnClose()
|
||||
{
|
||||
base.OnClose();
|
||||
service.Stop();
|
||||
}
|
||||
|
||||
protected virtual async UniTask<int> GetPort()
|
||||
@@ -72,34 +120,22 @@ namespace JNGame.Network
|
||||
await UniTask.NextFrame();
|
||||
return 9001;
|
||||
}
|
||||
|
||||
public override void OnClose()
|
||||
|
||||
|
||||
public void Send(SocketClient client,int hId,IMessage data = null)
|
||||
{
|
||||
base.OnClose();
|
||||
CloseNetty();
|
||||
Debug.Log($"[JNTCPServer] 关闭连接");
|
||||
|
||||
}
|
||||
|
||||
private async Task CloseNetty()
|
||||
{
|
||||
channel?.CloseAsync();
|
||||
bossGroup?.ShutdownGracefullyAsync();
|
||||
workerGroup?.ShutdownGracefullyAsync();
|
||||
channel = null;
|
||||
bossGroup = null;
|
||||
workerGroup = null;
|
||||
var bytes = NDataUtil.Encrypt(JNetParam.Build(this._id++, hId).SetData(data));
|
||||
_byteSize[hId] = bytes.Length;
|
||||
service.SendAsync(client.Id, bytes);
|
||||
}
|
||||
|
||||
public void AllSend(int hId,IMessage data = null)
|
||||
{
|
||||
server.GetClients().ForEach(id => Send(id,hId,data));
|
||||
service.GetClients().ForEach(client =>
|
||||
{
|
||||
Send(client,hId,data);
|
||||
});
|
||||
}
|
||||
|
||||
public void Send(int client,int hId,IMessage data = null)
|
||||
{
|
||||
IChannelHandlerContext context = server.GetClient(client);
|
||||
context.WriteAsync(JNetParam.Build(this._id++, hId).SetData(data));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,107 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using JNGame.Util;
|
||||
using Plugins.JNGame.Network.Util;
|
||||
using UnityEngine;
|
||||
using NotImplementedException = System.NotImplementedException;
|
||||
|
||||
namespace Plugins.JNGame.Network
|
||||
{
|
||||
public abstract class JNTCPClient1 : JNClientBase
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 客户端
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Socket client;
|
||||
|
||||
/// <summary>
|
||||
/// 客户端线程
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Thread thread;
|
||||
|
||||
/// <summary>
|
||||
/// 是否连接
|
||||
/// </summary>
|
||||
public bool isConnect { get; private set; }
|
||||
|
||||
private Queue<byte[]> cache = new ();
|
||||
|
||||
public override async Task OnInit()
|
||||
{
|
||||
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
client.Connect(await GetEndPoint());
|
||||
thread = new Thread(CreatConnectSocket);
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
public override void OnClose()
|
||||
{
|
||||
Debug.Log($"[JNTCPClient] 关闭客户端");
|
||||
base.OnClose();
|
||||
client?.Close();
|
||||
thread?.Abort();
|
||||
}
|
||||
|
||||
protected virtual async UniTask<IPEndPoint> GetEndPoint()
|
||||
{
|
||||
await UniTask.NextFrame();
|
||||
return new IPEndPoint(IPAddress.Parse("127.0.0.1"),9001);
|
||||
}
|
||||
|
||||
private void CreatConnectSocket()
|
||||
{
|
||||
Debug.Log($"[JNTCPClient] 连接服务器成功");
|
||||
isConnect = true;
|
||||
PushCache();
|
||||
byte[] bytes = new byte[102400];
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var max = client.Receive(bytes);
|
||||
var message = new byte[max];
|
||||
Array.Copy(bytes, message, max);
|
||||
var param = NDataUtil.Parse(message);
|
||||
Dispatch(param);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// ignored
|
||||
Debug.LogWarning(e.Message);
|
||||
Debug.Log($"[JNTCPClient] 断开连接");
|
||||
isConnect = false;
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public override void SendBytes(byte[] data)
|
||||
{
|
||||
if (data is null || data.Length <= 0) return;
|
||||
cache.Enqueue(data);
|
||||
if (isConnect)
|
||||
{
|
||||
PushCache();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送缓存
|
||||
/// </summary>
|
||||
public void PushCache()
|
||||
{
|
||||
while (isConnect && cache.TryDequeue(out var bytes))
|
||||
{
|
||||
NetTool.SendAsync(client,bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cd63835ebd243888fb11eb3fb168a92
|
||||
timeCreated: 1723799588
|
@@ -1,172 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using DotRecast.Core.Collections;
|
||||
using Google.Protobuf;
|
||||
using JNGame.Util.Types;
|
||||
using Plugins.JNGame.Network.Action;
|
||||
using Plugins.JNGame.Network.Entity;
|
||||
using Plugins.JNGame.Network.Util;
|
||||
using Plugins.JNGame.System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Plugins.JNGame.Network
|
||||
{
|
||||
public abstract class JNTCPServer1 : JNServerBase
|
||||
{
|
||||
|
||||
// /// <summary>
|
||||
// /// 服务器
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// private TcpListener server;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 服务器线程
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// private Thread thread;
|
||||
// /// <summary>
|
||||
// /// 客户端线程
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// private Dictionary<string,Socket> threads = new();
|
||||
//
|
||||
// private int _clientIndex = 0;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 连接的客户端
|
||||
// /// </summary>
|
||||
// KeyValue<int,Socket> clients = new ();
|
||||
//
|
||||
// private int _port = 0;
|
||||
// public int Port => _port;
|
||||
//
|
||||
//
|
||||
// public override async Task OnInit()
|
||||
// {
|
||||
// await CreateServer();
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 关闭服务器
|
||||
// /// </summary>
|
||||
// public override void OnClose()
|
||||
// {
|
||||
// Debug.Log($"[JNUDPServer] 关闭服务器");
|
||||
// base.OnClose();
|
||||
// server?.Stop();
|
||||
// thread?.Abort();
|
||||
// threads.ForEach(child => child.Value.Close());
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 创建服务器
|
||||
// /// </summary>
|
||||
// private async UniTask CreateServer()
|
||||
// {
|
||||
//
|
||||
// server = new TcpListener(IPAddress.Any,_port = await GetPort());
|
||||
// server.Start();
|
||||
// thread = new Thread(CreatConnectSocket);
|
||||
// thread.Start();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// protected virtual async UniTask<int> GetPort()
|
||||
// {
|
||||
// await UniTask.NextFrame();
|
||||
// return 9001;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 接受监听后保存生成的通信客户端,并开启线程监听通信客户端消息
|
||||
// /// </summary>
|
||||
// void CreatConnectSocket()
|
||||
// {
|
||||
// Debug.Log($"[JNTCPServer] 创建服务器成功");
|
||||
// while (true)
|
||||
// {
|
||||
// _clientIndex += 1;
|
||||
// Socket socket = server.AcceptSocket();
|
||||
// clients.Add(_clientIndex,socket);
|
||||
// Thread thread1 = new Thread(() => { ListenConnectSocket(socket); });
|
||||
// thread1.Start();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 接受通信客户端消息并对消息进行处理
|
||||
// /// </summary>
|
||||
// /// <param name="socket"></param>
|
||||
// void ListenConnectSocket(Socket socket)
|
||||
// {
|
||||
// Debug.Log($"[JNTCPServer] 客户端连接");
|
||||
// //客户端连接
|
||||
// _event.Dispatch($"{(int)NActionEnum.ClientConnect}",new JNServerParam()
|
||||
// {
|
||||
// Client = socket,
|
||||
// Message = Array.Empty<byte>()
|
||||
// });
|
||||
// byte[] bytes = new byte[102400];
|
||||
// try
|
||||
// {
|
||||
// while (true)
|
||||
// {
|
||||
// var max = socket.Receive(bytes);
|
||||
// var message = new byte[max];
|
||||
// if (max >= 102400)
|
||||
// {
|
||||
// throw new Exception($"[JNTCPServer] 超出最大接收{max}");
|
||||
// }
|
||||
// Array.Copy(bytes,message,max);
|
||||
// var param = NDataUtil.Parse(message);
|
||||
// _byteSize[param.HId] = param.Bytes.Length;
|
||||
// _event.Dispatch($"{param.HId}",new JNServerParam()
|
||||
// {
|
||||
// Client = socket,
|
||||
// Message = param.Bytes
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Debug.LogWarning(e.Message);
|
||||
// Debug.Log($"[JNTCPServer] 断开客户端连接");
|
||||
// //客户端断开
|
||||
// _event.Dispatch($"{(int)NActionEnum.ClientDisconnect}",new JNServerParam()
|
||||
// {
|
||||
// Client = socket,
|
||||
// Message = Array.Empty<byte>()
|
||||
// });
|
||||
// socket.Close();
|
||||
// clients.RemoveByValue(socket);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void Send(Socket client,int hId,IMessage data = null)
|
||||
// {
|
||||
// var bytes = NDataUtil.Encrypt(JNetParam.Build(this._id++, hId).SetData(data));
|
||||
// _byteSize[hId] = bytes.Length;
|
||||
// client.SendAsync(bytes,SocketFlags.None);
|
||||
// }
|
||||
//
|
||||
// public void AllSend(int hId,IMessage data = null)
|
||||
// {
|
||||
// clients.Values.ForEach(child =>
|
||||
// {
|
||||
// Send(child.Value, hId, data);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
public override Task OnInit()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0133b6e17024e67a3e0c86689c7ba9b
|
||||
timeCreated: 1723725100
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5da486bbb35a4830bbf04c02e4d64dae
|
||||
timeCreated: 1723773802
|
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using DotNetty.Handlers.Timeout;
|
||||
using DotNetty.Transport.Channels;
|
||||
|
||||
namespace JNGame.Network.Netty
|
||||
{
|
||||
/// <summary>
|
||||
/// Heartbeat Handler Class.
|
||||
/// </summary>
|
||||
public class HeartBeatHandler : ChannelHandlerAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// Heart Beat Handler.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="evt"></param>
|
||||
public override void UserEventTriggered(IChannelHandlerContext context, object evt)
|
||||
{
|
||||
var eventState = evt as IdleStateEvent;
|
||||
if (eventState != null)
|
||||
{
|
||||
if (eventState.State == IdleState.ReaderIdle)
|
||||
{
|
||||
context.Channel.Flush();
|
||||
context.Channel.CloseAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base.UserEventTriggered(context, evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 428846a1397f4426b81f1b79876325ef
|
||||
timeCreated: 1723775429
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b093de57a09748848035e479d1248ea4
|
||||
timeCreated: 1723773808
|
@@ -1,111 +0,0 @@
|
||||
using System;
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Transport.Channels;
|
||||
using JNGame.Util.Types;
|
||||
using Plugins.JNGame.Network;
|
||||
using Plugins.JNGame.Network.Action;
|
||||
using Plugins.JNGame.Network.Entity;
|
||||
using UnityEngine;
|
||||
|
||||
namespace JNGame.Network.Netty.TCP
|
||||
{
|
||||
public class TcpClientHandler : ChannelHandlerAdapter
|
||||
{
|
||||
|
||||
private JNClientBase root;
|
||||
|
||||
public TcpClientHandler(JNClientBase client)
|
||||
{
|
||||
root = client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逻辑处理器被添加
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void HandlerAdded(IChannelHandlerContext context)
|
||||
{
|
||||
base.HandlerAdded(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定到线程
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelRegistered(IChannelHandlerContext context)
|
||||
{
|
||||
base.ChannelRegistered(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 准备就绪
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelActive(IChannelHandlerContext context)
|
||||
{
|
||||
|
||||
base.ChannelActive(context);
|
||||
Debug.Log($"[TcpClientHandler] 连接成功: {context.Channel.RemoteAddress}");
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有数据可读
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="message"></param>
|
||||
public override void ChannelRead(IChannelHandlerContext context, object message)
|
||||
{
|
||||
|
||||
base.ChannelRead(context, message);
|
||||
|
||||
if (message is not JNetParam data) return;
|
||||
|
||||
root.Dispatch(data);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 某次数据读完
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelReadComplete(IChannelHandlerContext context)
|
||||
{
|
||||
base.ChannelReadComplete(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 被关闭
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelInactive(IChannelHandlerContext context)
|
||||
{
|
||||
|
||||
base.ChannelInactive(context);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消线程(NioEventLoop) 的绑定
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelUnregistered(IChannelHandlerContext context)
|
||||
{
|
||||
base.ChannelUnregistered(context);
|
||||
context.Channel.EventLoop.Schedule(() =>
|
||||
{
|
||||
Debug.Log($"重连接: {context.Channel.RemoteAddress}");
|
||||
root.StartConnect();
|
||||
}, new TimeSpan(1000));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逻辑处理器被移除
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void HandlerRemoved(IChannelHandlerContext context)
|
||||
{
|
||||
base.HandlerRemoved(context);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a6cf562019b4e4eaf5fae1b4bb2b19f
|
||||
timeCreated: 1723799944
|
@@ -1,34 +0,0 @@
|
||||
using DotNetty.Handlers.Logging;
|
||||
using DotNetty.Handlers.Timeout;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using JNGame.Network.Netty;
|
||||
using JNGame.Network.Netty.TCP;
|
||||
using Plugins.JNGame.Network;
|
||||
using TestNetty.Service.Handlers;
|
||||
|
||||
namespace TestNetty.Client.Initializers
|
||||
{
|
||||
public class TcpClientInitializer : ChannelInitializer<ISocketChannel>
|
||||
{
|
||||
|
||||
private JNClientBase root;
|
||||
private TcpClientHandler handler;
|
||||
|
||||
public TcpClientInitializer(JNClientBase server)
|
||||
{
|
||||
root = server;
|
||||
handler = new TcpClientHandler(root);
|
||||
}
|
||||
|
||||
protected override void InitChannel(ISocketChannel channel)
|
||||
{
|
||||
IChannelPipeline pipeline = channel.Pipeline;
|
||||
pipeline.AddLast(new IdleStateHandler(30, 30, 60 * 5));
|
||||
pipeline.AddLast(new HeartBeatHandler());
|
||||
pipeline.AddLast("encoder", new TcpEncoderHandler());
|
||||
pipeline.AddLast("decoder", new TcpDecoderHandler());
|
||||
pipeline.AddLast(handler);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96db8fb3f65d44b798bc06f95a8246bb
|
||||
timeCreated: 1723799785
|
@@ -1,36 +0,0 @@
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
using System.Collections.Generic;
|
||||
using Plugins.JNGame.Network.Util;
|
||||
|
||||
namespace TestNetty.Service.Handlers
|
||||
{
|
||||
/// <summary>
|
||||
/// Decoder Packet
|
||||
/// </summary>
|
||||
public class TcpDecoderHandler : ByteToMessageDecoder
|
||||
{
|
||||
|
||||
//准备读取的消息长度
|
||||
private int? length;
|
||||
|
||||
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
|
||||
{
|
||||
|
||||
if (length is null && input.ReadableBytes >= 4)
|
||||
{
|
||||
length = input.ReadInt();
|
||||
}
|
||||
|
||||
if (length is not null && input.ReadableBytes >= length)
|
||||
{
|
||||
IByteBuffer result = input.ReadBytes(length.Value);
|
||||
output.Add(NDataUtil.Parse(result.Array));
|
||||
result.Clear();
|
||||
length = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9487ff44b5354bc4843ac7320680c10f
|
||||
timeCreated: 1723773916
|
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
using Plugins.JNGame.Network.Entity;
|
||||
using Plugins.JNGame.Network.Util;
|
||||
|
||||
namespace TestNetty.Service.Handlers
|
||||
{
|
||||
/// <summary>
|
||||
/// Encoder Packet
|
||||
/// </summary>
|
||||
public class TcpEncoderHandler : MessageToByteEncoder<JNetParam>
|
||||
{
|
||||
protected override void Encode(IChannelHandlerContext context, JNetParam message, IByteBuffer output)
|
||||
{
|
||||
var data = NDataUtil.Encrypt(message);
|
||||
output.WriteInt(data.Length);//4-8
|
||||
output.WriteBytes(data);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11f81d1e8543432c8226b6c42b605010
|
||||
timeCreated: 1723773916
|
@@ -1,11 +0,0 @@
|
||||
using Plugins.JNGame.Network.Entity;
|
||||
|
||||
namespace JNGame.Network.Netty.TCP
|
||||
{
|
||||
public class TcpPacket
|
||||
{
|
||||
public int Checkbit;
|
||||
public int Length;
|
||||
public JNetParam Data;
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5008afe7a554eafb1c684bef86362b0
|
||||
timeCreated: 1723774619
|
@@ -1,154 +0,0 @@
|
||||
using System;
|
||||
using DotNetty.Transport.Channels;
|
||||
using JNGame.Util.Types;
|
||||
using Plugins.JNGame.Network;
|
||||
using Plugins.JNGame.Network.Action;
|
||||
using Plugins.JNGame.Network.Entity;
|
||||
using UnityEngine;
|
||||
|
||||
namespace JNGame.Network.Netty.TCP
|
||||
{
|
||||
public class TcpServerHandler : ChannelHandlerAdapter
|
||||
{
|
||||
|
||||
private int _index = 0;
|
||||
public int Next()
|
||||
{
|
||||
return _index++;
|
||||
}
|
||||
|
||||
private JNServerBase root;
|
||||
|
||||
public readonly KeyValue<IChannelHandlerContext, int> ClientInts = new();
|
||||
|
||||
public TcpServerHandler(JNServerBase server)
|
||||
{
|
||||
root = server;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逻辑处理器被添加
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void HandlerAdded(IChannelHandlerContext context)
|
||||
{
|
||||
base.HandlerAdded(context);
|
||||
ClientInts.Add(context,Next());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定到线程
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelRegistered(IChannelHandlerContext context)
|
||||
{
|
||||
base.ChannelRegistered(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 准备就绪
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelActive(IChannelHandlerContext context)
|
||||
{
|
||||
|
||||
base.ChannelActive(context);
|
||||
|
||||
if (!(ClientInts.TryGetValueByKey(context,out var id)))
|
||||
{
|
||||
context.CloseAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"[TcpServerHandler] 连接成功: {context.Channel.RemoteAddress}");
|
||||
|
||||
//客户端连接
|
||||
root.Dispatch((int)NActionEnum.ClientConnect,new JNServerParam()
|
||||
{
|
||||
Client = id,
|
||||
Message = Array.Empty<byte>()
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 有数据可读
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="message"></param>
|
||||
public override void ChannelRead(IChannelHandlerContext context, object message)
|
||||
{
|
||||
|
||||
base.ChannelRead(context, message);
|
||||
|
||||
if (message is not JNetParam data) return;
|
||||
|
||||
if (!(ClientInts.TryGetValueByKey(context,out var id)))
|
||||
{
|
||||
context.CloseAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
root.Dispatch(data.HId,new JNServerParam()
|
||||
{
|
||||
Client = id,
|
||||
Message = data.Bytes
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 某次数据读完
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelReadComplete(IChannelHandlerContext context)
|
||||
{
|
||||
base.ChannelReadComplete(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 被关闭
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelInactive(IChannelHandlerContext context)
|
||||
{
|
||||
|
||||
base.ChannelInactive(context);
|
||||
|
||||
if (!(ClientInts.TryGetValueByKey(context,out var id)))
|
||||
{
|
||||
context.CloseAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"[TcpServerHandler] 断开连接: {context.Channel.RemoteAddress}");
|
||||
|
||||
//客户端断开
|
||||
root.Dispatch((int)NActionEnum.ClientDisconnect,new JNServerParam()
|
||||
{
|
||||
Client = id,
|
||||
Message = Array.Empty<byte>()
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消线程(NioEventLoop) 的绑定
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void ChannelUnregistered(IChannelHandlerContext context)
|
||||
{
|
||||
base.ChannelUnregistered(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逻辑处理器被移除
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public override void HandlerRemoved(IChannelHandlerContext context)
|
||||
{
|
||||
base.HandlerRemoved(context);
|
||||
ClientInts.RemoveByKey(context);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70f2f7800eb14ae189df47eb04e775aa
|
||||
timeCreated: 1723776097
|
@@ -1,42 +0,0 @@
|
||||
using DotNetty.Handlers.Timeout;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using Plugins.JNGame.Network;
|
||||
using TestNetty.Service.Handlers;
|
||||
|
||||
namespace JNGame.Network.Netty.TCP
|
||||
{
|
||||
public class TcpServerInitializer : ChannelInitializer<ISocketChannel>
|
||||
{
|
||||
|
||||
private JNServerBase root;
|
||||
private TcpServerHandler handler;
|
||||
|
||||
public TcpServerInitializer(JNServerBase server)
|
||||
{
|
||||
root = server;
|
||||
handler = new TcpServerHandler(root);
|
||||
}
|
||||
|
||||
protected override void InitChannel(ISocketChannel channel)
|
||||
{
|
||||
IChannelPipeline pipeline = channel.Pipeline;
|
||||
pipeline.AddLast(new IdleStateHandler(30,30,60 * 5));//心跳
|
||||
pipeline.AddLast(new HeartBeatHandler());
|
||||
pipeline.AddLast("encoder", new TcpEncoderHandler());
|
||||
pipeline.AddLast("decoder", new TcpDecoderHandler());
|
||||
pipeline.AddLast(handler);
|
||||
}
|
||||
|
||||
public IChannelHandlerContext GetClient(int index)
|
||||
{
|
||||
return handler.ClientInts.Value2Key(index);
|
||||
}
|
||||
|
||||
public int[] GetClients()
|
||||
{
|
||||
return handler.ClientInts.Values;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c734c16eb6b4ff98f41bb63524f3209
|
||||
timeCreated: 1723773874
|
Reference in New Issue
Block a user