Example #1
0
        public override void RemoveChannel(uint channelId)
        {
            KChannel channel = null;

            if (this.idChannels.TryGetValue(channelId, out channel))
            {
                if (channel != null)
                {
                    this.removedChannels.Enqueue(channelId);
                    channel.Dispose();
                }
            }
        }
Example #2
0
 /// <summary>
 /// 请求连接服务器
 /// </summary>
 /// <param name="ipEndPoint"></param>
 /// <returns></returns>
 public override Task <AChannel> ConnectChannelAsync(IPEndPoint ipEndPoint)
 {
     if (connectTcs == null)
     {
         connectTcs = new TaskCompletionSource <AChannel>();
         //随机一个临时ID,连接成功后会被服务器替换
         uint     channelId = (uint)RandomHelper.RandomNumber(1000, int.MaxValue);
         KChannel channel   = new KChannel(ChannelType.Connect, this, channelId, ipEndPoint, this.socket);
         //将相同id的channel销毁???
         KChannel oldChannel;
         if (this.idChannels.TryGetValue(channelId, out oldChannel))
         {
             this.idChannels.Remove(channelId);
             oldChannel.Dispose();
         }
         this.idChannels[channelId] = channel;
         Log.Debug($"KService.ConnectChannelAsync.Start: channelId={channel.Id}, thread={System.Threading.Thread.CurrentThread.ManagedThreadId}");
         return(connectTcs.Task);
     }
     else
     {
         return(null);
     }
 }
Example #3
0
        private async void StartRecv()
        {
            while (true)
            {
                if (this.socket == null)
                {
                    return;
                }

                //接收数据
                UdpReceiveResult udpReceiveResult;
                try
                {
                    udpReceiveResult = await this.socket.ReceiveAsync();
                }
                catch (Exception e)
                {
                    Log.Error(e.ToString());
                    continue;
                }

                int messageLength = udpReceiveResult.Buffer.Length;
                // 长度小于4,不是正常的消息
                if (messageLength < 4)
                {
                    continue;
                }

                //数据包的类型/或channelId
                uint ptype = BitConverter.ToUInt32(udpReceiveResult.Buffer, 0);
                Log.Info($"StartRecv.ReceiveAsync: thread={System.Threading.Thread.CurrentThread.ManagedThreadId}, ptype={ptype}, messageLength={messageLength}");

                switch ((KcpProtocalType)ptype)
                {
                case KcpProtocalType.SYN:
                    // 长度!=8,不是accpet消息
                    if (messageLength != 8)
                    {
                        break;
                    }
                    //尚未开始等待连接
                    if (this.acceptTcs == null)
                    {
                        return;
                    }

                    //发送者的ID
                    uint remoteId = BitConverter.ToUInt32(udpReceiveResult.Buffer, 4);

                    KChannel sChannel;
                    // 如果已经连接上,则重新响应请求
                    if (this.idChannels.TryGetValue(remoteId, out sChannel))
                    {
                        sChannel.HandleAccept(remoteId);
                        return;
                    }

                    TaskCompletionSource <AChannel> tcs = this.acceptTcs;
                    this.acceptTcs = null;

                    //创建新的channel
                    sChannel = new KChannel(ChannelType.Accept, this, ++this.IdGenerater, udpReceiveResult.RemoteEndPoint, socket);
                    //如已有同ID的channel,销毁旧的
                    if (this.idChannels.TryGetValue(sChannel.Id, out KChannel oldChannel))
                    {
                        this.idChannels.Remove(oldChannel.Id);
                        oldChannel.Dispose();
                    }
                    //记录channel
                    this.idChannels[sChannel.Id] = sChannel;
                    Log.Debug($"StartRecv.KcpProtocalType.SYN: channelId={sChannel.Id}, thread={System.Threading.Thread.CurrentThread.ManagedThreadId}");

                    //向remote返回ACK
                    sChannel.HandleAccept(remoteId);

                    //异步回调
                    tcs.SetResult(sChannel);

                    //test:开始接收
                    //sChannel.StartRecvAsync();
                    break;

                case KcpProtocalType.ACK:
                    // 长度!=12,不是connect消息
                    if (messageLength != 12)
                    {
                        break;
                    }

                    uint channelId = BitConverter.ToUInt32(udpReceiveResult.Buffer, 4);
                    uint tmpId     = BitConverter.ToUInt32(udpReceiveResult.Buffer, 8);
                    Log.Debug($"StartRecv.KcpProtocalType.ACK: tmpId={tmpId}, channelId={channelId}, thread={System.Threading.Thread.CurrentThread.ManagedThreadId}");

                    //已有连接,
                    if (this.idChannels.TryGetValue(tmpId, out KChannel aChannel))
                    {
                        //处理chanel
                        aChannel.HandleConnnect(channelId);
                        //移除旧ID的,替换为新ID
                        this.idChannels.Remove(tmpId);
                        this.idChannels[channelId] = aChannel;
                        //异步回调
                        if (connectTcs != null)
                        {
                            connectTcs.SetResult(aChannel);
                            connectTcs = null;
                            Log.Debug($"KService.ConnectChannelAsync.Finish: channelId={aChannel.Id}, thread={System.Threading.Thread.CurrentThread.ManagedThreadId}");
                        }
                    }
                    break;

                case KcpProtocalType.FIN:
                    // 长度!= 8,不是DisConnect消息
                    if (messageLength != 8)
                    {
                        break;
                    }

                    uint closeId = BitConverter.ToUInt32(udpReceiveResult.Buffer, 4);
                    if (this.idChannels.TryGetValue(closeId, out KChannel fChannel))
                    {
                        // 处理chanel
                        this.idChannels.Remove(closeId);
                        fChannel.Dispose();
                        Log.Debug($"StartRecv.KcpProtocalType.FIN: channelId={closeId}, thread={System.Threading.Thread.CurrentThread.ManagedThreadId}");
                    }
                    break;

                case KcpProtocalType.HEART:
                    if (messageLength != 8)
                    {
                        break;
                    }

                    uint hId = BitConverter.ToUInt32(udpReceiveResult.Buffer, 4);
                    if (this.idChannels.TryGetValue(hId, out KChannel hChannel))
                    {
                        //回应
                        hChannel.HeartbeatAck(this.TimeNow);
                    }
                    break;

                case KcpProtocalType.HEARTACK:
                    if (messageLength != 8)
                    {
                        break;
                    }

                    uint haId = BitConverter.ToUInt32(udpReceiveResult.Buffer, 4);
                    if (this.idChannels.TryGetValue(haId, out KChannel haChannel))
                    {
                        haChannel.FinishHeartbeat(this.TimeNow);
                    }
                    break;

                default:
                    var cid = ptype;
                    if (this.idChannels.TryGetValue(cid, out KChannel rChannel))
                    {
                        // 处理chanel
                        rChannel.HandleRecv(udpReceiveResult.Buffer, this.TimeNow);
                    }
                    break;
                }
            }
        }