Exemple #1
0
        /// <summary>
        /// 连接服务端
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async static Task <IChannel> ConnectAsync(DotNettyClientInfo info)
        {
            IChannel channel;

            try
            {
                if (!string.IsNullOrEmpty(info.LocalHost) && info.LocalPort != null)
                {
                    channel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(info.Host), info.Port), new IPEndPoint(IPAddress.Parse(info.LocalHost), info.LocalPort.Value));
                }
                else
                {
                    channel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(info.Host), info.Port));
                }
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }
                logger.LogError(ex, $"Channel connect failed. Host={info.Host}, Port={info.Port}, LocalHost={info.LocalHost}, LocalPort={info.LocalPort}");
                clientInfoList.TryRemove(info.ChannelName, out info);
                throw ex;
            }

            var localIPEndPoint = ((IPEndPoint)channel.LocalAddress);

            info.LocalHost = localIPEndPoint.Address.ToIPString();
            info.LocalPort = localIPEndPoint.Port;
            info.Channel   = channel;

            var clientInfoAddResult = clientInfoList.TryAdd(info.ChannelName, info);

            if (!clientInfoAddResult)
            {
                logger.LogError($"Channel is exist. Host={info.Host}, Port={info.Port}, LocalHost={info.LocalHost}, LocalPort={info.LocalPort}");
                await channel.CloseAsync();

                throw new InvalidOperationException("Channel is exist.");
            }

            return(channel);
        }
Exemple #2
0
        private static Func <string, Task <LoginRequestData> > CreateGetLoginRequestDataHandler()
        {
            return(new Func <string, Task <LoginRequestData> >(async channelName =>
            {
                DotNettyClientInfo result = null;

                for (var i = 0; i < 3 && !clientInfoList.TryGetValue(channelName, out result); i++)
                {
                    await Task.Delay(100);
                }

                if (result != null)
                {
                    return await result.GetLoginRequestDataHandler();
                }

                return new LoginRequestData();
            }));
        }
Exemple #3
0
        /// <summary>
        /// 执行与服务端连接
        /// </summary>
        /// <returns></returns>
        private async Task DoConnectAsync()
        {
            if (Status == ClientStatus.Connected)
            {
                return;
            }

            if (Status == ClientStatus.Connecting)
            {
                logger.LogError($"Client connect has begun. Host={Host}, Port={Port}, LocalHost={LocalHost}, LocalPort={LocalPort}");
                throw new InvalidOperationException($"Client connect has begun. Host={Host}, Port={Port}, LocalHost={LocalHost}, LocalPort={LocalPort}");
            }

            Status = ClientStatus.Connecting;

            logger.LogDebug($"Client connect beginning. Host={Host}, Port={Port}, LocalHost={LocalHost}, LocalPort={LocalPort}");

            try
            {
                var dotNettyClientInfo = new DotNettyClientInfo()
                {
                    Host                       = Host,
                    Port                       = Port,
                    LocalHost                  = LocalHost,
                    LocalPort                  = LocalPort,
                    RequestManager             = requestManager,
                    InactiveHandler            = InactiveHandler,
                    GetLoginRequestDataHandler = GetLoginRequestData,
                    LoginResponseHandler       = LoginResponse
                };
                //发起异步连接操作
                var oldChannel = channel;
                channel = await BootstrapManager.ConnectAsync(dotNettyClientInfo);

                if (oldChannel != null)
                {
                    await oldChannel.CloseAsync();
                }

                channelName = dotNettyClientInfo.ChannelName;
            }
            catch (Exception ex)
            {
                Status = ClientStatus.PassiveClosed;
                logger.LogError(ex, $"Client connect has error. Host={Host}, Port={Port}, LocalHost={LocalHost}, LocalPort={LocalPort}, ExceptionMessage={ex.Message}, ExceptionStackTrace={ex.StackTrace}");
                throw new NetworkException(Host, Port, ex.Message);
            }

            try
            {
                connectTcs = new TaskCompletionSource <object>();
                connectCts = new CancellationTokenSource(3000);     //登录验证响应超时
                var token = connectCts.Token;
                token.Register(() =>
                {
                    try
                    {
                        connectTcs.SetException(new TimeoutException("Login response timeout."));
                    }
                    catch { }
                });

                await connectTcs.Task;      //等待登录验证响应
            }
            catch (Exception ex)
            {
                await CloseAsync();

                logger.LogError(ex, $"Client login has error. Host={Host}, Port={Port}, LocalHost={LocalHost}, LocalPort={LocalPort}, ExceptionMessage={ex.Message}, ExceptionStackTrace={ex.StackTrace}");
                throw new NetworkException(Host, Port, ex.Message);
            }
            finally
            {
                connectCts = null;
                connectTcs = null;
            }

            Status = ClientStatus.Connected;
            logger.LogDebug($"Client connect finished. Host={Host}, Port={Port}, LocalHost={LocalHost}, LocalPort={LocalPort}");
        }