/// <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); }
/// <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); } }
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}"); })); }
/// <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}"); } }
/// <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}"); } }