upm_guru_kcp/Runtime/csharp-kcp/dotNetty-kcp/ServerChannelHandler.cs

102 lines
3.5 KiB
C#

using System;
using base_kcp;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using dotNetty_kcp.thread;
using DotNetty.Buffers;
using fec;
using fec.fec;
namespace dotNetty_kcp
{
public class ServerChannelHandler:ChannelHandlerAdapter
{
private readonly IChannelManager _channelManager;
private readonly ChannelConfig _channelConfig ;
private readonly IExecutorPool _executorPool;
private readonly KcpListener _kcpListener;
private readonly IScheduleThread _scheduleThread;
public ServerChannelHandler(IChannelManager channelManager, ChannelConfig channelConfig, IExecutorPool executorPool, KcpListener kcpListener, IScheduleThread scheduleThread)
{
_channelManager = channelManager;
_channelConfig = channelConfig;
_executorPool = executorPool;
_kcpListener = kcpListener;
_scheduleThread = scheduleThread;
}
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
Console.WriteLine(exception);
}
public override void ChannelRead(IChannelHandlerContext context, object message)
{
var msg = (DatagramPacket) message;
var channel = context.Channel;
var ukcp = _channelManager.get(msg);
var content = msg.Content;
User user;
if (ukcp != null)
{
user = ukcp.user();
//每次收到消息重绑定地址
user.RemoteAddress = msg.Sender;
ukcp.read(content);
return;
}
//如果是新连接第一个包的sn必须为0
var sn = getSn(content,_channelConfig);
if(sn!=0)
{
msg.Release();
return;
}
var messageExecutor = _executorPool.GetAutoMessageExecutor();
KcpOutput kcpOutput = new KcpOutPutImp();
ReedSolomon reedSolomon = null;
if(_channelConfig.FecDataShardCount!=0&&_channelConfig.FecParityShardCount!=0){
reedSolomon = ReedSolomon.create(_channelConfig.FecDataShardCount,_channelConfig.FecParityShardCount);
}
ukcp = new Ukcp(kcpOutput,_kcpListener,messageExecutor,reedSolomon,_channelConfig);
user = new User(channel,msg.Sender,msg.Recipient);
ukcp.user(user);
_channelManager.New(msg.Sender,ukcp,msg);
messageExecutor.execute(new ConnectTask(ukcp, _kcpListener));
ukcp.read(content);
var scheduleTask = new ScheduleTask(_channelManager,ukcp,_scheduleThread);
_scheduleThread.schedule(scheduleTask, TimeSpan.FromMilliseconds(ukcp.getInterval()));
}
private int getSn(IByteBuffer byteBuf,ChannelConfig channelConfig){
var headerSize = 0;
if (channelConfig.Crc32Check)
{
headerSize+=Ukcp.HEADER_CRC;
}
if(channelConfig.FecDataShardCount!=0&&channelConfig.FecParityShardCount!=0){
headerSize+= Fec.fecHeaderSizePlus2;
}
var sn = byteBuf.GetIntLE(byteBuf.ReaderIndex+Kcp.IKCP_SN_OFFSET+headerSize);
return sn;
}
}
}