102 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			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;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
} |