Пример #1
0
        /// <summary>
        /// 执行与服务端连接
        /// </summary>
        /// <returns></returns>
        private async Task DoConnectAsync()
        {
            LogsManager.Debug($"Client connect beginning. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");


            try
            {
                status = ClientStatus.Connecting;
                //发起异步连接操作
                if (!string.IsNullOrEmpty(localHost) && localPort != null)
                {
                    channel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(host), port), new IPEndPoint(IPAddress.Parse(localHost), localPort.Value));
                }
                else
                {
                    channel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(host), port));
                }

                status = ClientStatus.Connected;
                LogsManager.Debug($"Client connect finished. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");
            }
            catch (AggregateException ex)
            {
                status = ClientStatus.Closed;
                LogsManager.Error(ex, $"Client connect has error. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}, ExceptionMessage={ex.InnerException.Message}, ExceptionStackTrace={ex.InnerException.StackTrace}");
                throw new NetworkException(host, port, ex.InnerException.Message);
            }
        }
Пример #2
0
        /// <summary>
        /// 创建请求信息对象
        /// </summary>
        /// <param name="timeout">请求超时时长(毫秒)</param>
        /// <param name="serialNumber">唯一序列号</param>
        /// <returns></returns>
        public RequestInfo CreateRequest(int timeout, string serialNumber)
        {
            var request = new RequestInfo();

            requestList.TryAdd(serialNumber, request);

            var tcs = new TaskCompletionSource <DotNettyData>();
            var cts = new CancellationTokenSource(timeout);

            var token = cts.Token;

            token.Register(() =>
            {
                if (!requestList.TryRemove(serialNumber, out request))
                {
                    return;
                }

                try
                {
                    tcs.SetException(new RequestTimeoutExcption("Request timeout.", request));
                }
                catch { }
            });

            request.Id = serialNumber;
            request.TaskCompletionSource    = tcs;
            request.CancellationTokenSource = cts;

            LogsManager.Debug($"Create request. RequestId={request.Id}");

            return(request);
        }
Пример #3
0
 protected override void ChannelRead0(IChannelHandlerContext ctx, byte[] msg)
 {
     ThreadPool.QueueUserWorkItem((object state) =>
     {
         try
         {
             byte[] bytes        = (byte[])state;
             DotNettyData result = (DotNettyData)ByteExtension.ByteArrayToObject(bytes);
             requestManager.CompleteRequest(result.SerialNumber, result);
         }
         catch (Exception ex)
         {
             LogsManager.Error("处理服务端结果失败");
         }
     }, msg);
 }
Пример #4
0
        public async override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
        {
            if (exception is SocketException)
            {
                LogsManager.Error(exception, $"Socket exception. Local={context.GetLocalNetString()}, Remote={context.GetRemoteNetString()}, ExceptionMessage={exception.Message}");
                await socketExceptionHandler?.Invoke();
            }
            else
            {
                LogsManager.Error(exception, $"Unhandle exception. Local={context.GetLocalNetString()}, Remote={context.GetRemoteNetString()}, ExceptionMessage={exception.Message}");
                await context.CloseAsync();

                LogsManager.Info($"Channel closed because has an unhandle exception. Local={context.GetLocalNetString()}, Remote={context.GetRemoteNetString()}");
                context.FireExceptionCaught(exception);
            }
        }
Пример #5
0
        private Task ReconnectAsync()
        {
            return(Task.Run(async() =>
            {
                if (reconnectCount == 0 || Interlocked.CompareExchange(ref isReconnecting, 1, 0) == 1)
                {
                    return;
                }

                status = ClientStatus.Closed;
                await channel.CloseAsync();

                LogsManager.Debug($"Client reconnect: close connect. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");

                int i = 0;

                while (reconnectCount == -1 || i < reconnectCount)
                {
                    if (reconnectCount != -1)
                    {
                        i++;
                    }

                    Thread.Sleep(reconnectInterval);

                    if (!allowReconnect)
                    {
                        break;
                    }

                    try
                    {
                        LogsManager.Debug($"Client reconnect: connecting. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");
                        await DoConnectAsync();
                        LogsManager.Debug($"Client reconnect: connect success. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");
                        break;
                    }
                    catch (Exception ex)
                    {
                        LogsManager.Error(ex, $"Client reconnect: connect error. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}, ExceptionMessage={ex.Message}, ExceptionStackTrace={ex.StackTrace}");
                    }
                }
                isReconnecting = 0;
                LogsManager.Debug($"Client reconnect finished. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");
            }));
        }
Пример #6
0
        /// <summary>
        /// 关闭与服务端的连接
        /// </summary>
        /// <returns></returns>
        public async Task CloseAsync()
        {
            try
            {
                status         = ClientStatus.Closed;
                allowReconnect = false;
                await channel.CloseAsync();

                LogsManager.Debug($"Client closed. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");
            }
            finally
            {
                await group.ShutdownGracefullyAsync();

                LogsManager.Debug($"Group shutdowned. Host={host}, Port={port}, LocalHost={localHost}, LocalPort={localPort}");
            }
        }
Пример #7
0
        /// <summary>
        /// 请求完成
        /// </summary>
        /// <param name="requestId">RequestId</param>
        /// <param name="result">承载请求响应的消息对象</param>
        public void CompleteRequest(string requestId, DotNettyData result)
        {
            if (!requestList.TryRemove(requestId, out RequestInfo request))
            {
                return;
            }

            try
            {
                request.CancellationTokenSource.Dispose();
                request.TaskCompletionSource.SetResult(result);
                LogsManager.Debug($"Request completed. Request={request.Id}");
            }
            catch (Exception ex)
            {
                LogsManager.Error(ex, $"Request has error. ExceptionMessage={ex.Message}");
            }
        }
Пример #8
0
        public async Task RunAsync(int threadCount, CancellationToken cancellationToken, RecieveServiceRequestDelegate recieveServiceRequest)
        {
            Contract.Requires(threadCount > 0);
            try
            {
                LogsManager.Info("通用服务开始启动!");
                this.parentEventLoopGroup = new MultithreadEventLoopGroup(1);
                this.eventLoopGroup       = new MultithreadEventLoopGroup(threadCount);
                ServerBootstrap bootstrap = this.SetupBootstrap(recieveServiceRequest);

                this.serverChannel = await bootstrap.BindAsync(port);

                cancellationToken.Register(this.CloseAsync);
                LogsManager.Info("通用服务成功启动!");
            }
            catch (Exception ex)
            {
                LogsManager.Error("通用服务启动失败");
                this.CloseAsync();
            }
        }
Пример #9
0
 async void CloseAsync()
 {
     try
     {
         if (this.serverChannel != null)
         {
             await this.serverChannel.CloseAsync();
         }
         if (this.eventLoopGroup != null)
         {
             await this.eventLoopGroup.ShutdownGracefullyAsync();
         }
     }
     catch (Exception ex)
     {
         LogsManager.Error("通用服务停止失败");
     }
     finally
     {
         this.closeCompletionSource.TryComplete();
     }
 }
Пример #10
0
        protected override void Decode(IChannelHandlerContext context, IByteBuffer directBuf, List <object> output)
        {
            int length = directBuf.ReadableBytes;

            if (length <= 0)
            {
                return;
            }
            try
            {
                if (directBuf.HasArray)
                {
                    byte[] bytes = new byte[length];
                    directBuf.GetBytes(directBuf.ReaderIndex, bytes);
                    output.Add(bytes);
                }
            }
            catch (Exception ex)
            {
                LogsManager.Error(ex, "");
            }
        }
Пример #11
0
 public override void ChannelUnregistered(IChannelHandlerContext context)
 {
     LogsManager.Info($"Channel unregistered. Local={context.GetLocalNetString()}, Remote={context.GetRemoteNetString()}");
     base.ChannelUnregistered(context);
 }
Пример #12
0
 public override void ChannelInactive(IChannelHandlerContext context)
 {
     LogsManager.Info($"Channel inactived. Local={context.GetLocalNetString()}, Remote={context.GetRemoteNetString()}");
     base.ChannelInactive(context);
 }