internal static void AsyncRaiseConnecting(object sender, ReconnectArgs reconnectArgs) { if (Connecting == null) { return; } object[] args = { sender, new ConnectingEventArgs(reconnectArgs) }; AnycastEventThrower.QueueUserWorkItem(new RaiseEvent(_RaiseConnecting), args); }
/// <summary> /// 重连 /// </summary> private void _Reconnect(ReconnectArgs arg) { DisposeReconnectCancellation(); if (this.Config.ReconnectTimes > 0 && arg.Times == this.Config.ReconnectTimes) { //this.Config.ReconnectTimes小于或者等于0的时候,不触发错误,因为无限重连 ClientEvents.AsyncRaiseError(this, new ReconnectFailedException()); return; } arg.Times++; _Connect(arg); }
/// <summary> /// 连接 /// </summary> /// <returns></returns> private void _Connect(ReconnectArgs reconnectArgs) { if (_disposed) { return; } if (this.Status != ConnectionStatus.Disconnected) { return; } this.Status = ConnectionStatus.Connecting; if (_group == null) { _group = new MultithreadEventLoopGroup(); } X509Certificate2 cert = null; string targetHost = null; if (this.Config.IsSsl) { cert = new X509Certificate2(Path.Combine(AppContext.ProcessDirectory, "anycast.pfx"), "password"); targetHost = cert.GetNameInfo(X509NameType.DnsName, false); } var bootstrap = new Bootstrap(); bootstrap .Group(_group) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) //由于断线重连有内存泄露问题,所以我们使用 非池的字节缓冲区 .Handler(new ActionChannelInitializer <ISocketChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (cert != null) { pipeline.AddLast("tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost))); } pipeline.AddLast(new LoggingHandler()); pipeline.AddLast("framing-enc", new MessageEncoder()); pipeline.AddLast("framing-dec", new MessageDecoder()); pipeline.AddLast("ReadTimeout", new ReadTimeoutHandler(Settings.Timeout)); //超过指定时间没有接收到任何信息,自动关闭 pipeline.AddLast("LoginAuthReq", new LoginAuthReqHandler(this)); pipeline.AddLast("HeartBeatReq", new HeartBeatReqHandler(this)); pipeline.AddLast("ClientLogic", new ClientLogicHandler(this)); })); this.ServerEndPoint = new IPEndPoint(IPAddress.Parse(this.Config.Host), this.Config.Port); ClientEvents.AsyncRaiseConnecting(this, reconnectArgs); try { if (reconnectArgs != null && reconnectArgs.Times > 0) //第0次重连意味着是直接连接,不用等待 { _reconnectCancellation = new CancellationTokenSource(); Task.Delay(TimeSpan.FromSeconds(this.Config.ReconnectDelayTime), _reconnectCancellation.Token).Wait(); } this.Channel = bootstrap.ConnectAsync(this.ServerEndPoint).Result; this.Address = this.Channel.LocalAddress.ToString(); //在client,我们的地址是通道的本地地址 //while (true) //{ // this.Channel = bootstrap.ConnectAsync(this.ServerEndPoint).Result; // this.Address = this.Channel.LocalAddress.ToString(); //在client,我们的地址是通道的本地地址 // System.Threading.Thread.Sleep(2000); // this.Channel.CloseAsync().Wait(); //} } catch (Exception ex) { this.Status = ConnectionStatus.Disconnected; var args = reconnectArgs?.Clone(); ClientEvents.AsyncRaiseError(this, new ConnectServerException(this.ServerEndPoint, ex, args)); if (reconnectArgs != null) { _pipeline.Queue(() => { _Reconnect(reconnectArgs); }); } } }
public ConnectServerException(IPEndPoint serverEndPoint, Exception ex, ReconnectArgs reconnectArgs) : base(Strings.ConnectServerError, ex) { this.ServerEndPoint = serverEndPoint; this.ReconnectArgs = reconnectArgs; }
internal ConnectingEventArgs(ReconnectArgs reconnectArgs) { this.ReconnectArgs = reconnectArgs; }