Пример #1
0
        internal static void AsyncRaiseConnecting(object sender, ReconnectArgs reconnectArgs)
        {
            if (Connecting == null)
            {
                return;
            }

            object[] args = { sender, new ConnectingEventArgs(reconnectArgs) };
            AnycastEventThrower.QueueUserWorkItem(new RaiseEvent(_RaiseConnecting), args);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
                    });
                }
            }
        }
Пример #4
0
 public ConnectServerException(IPEndPoint serverEndPoint, Exception ex, ReconnectArgs reconnectArgs)
     : base(Strings.ConnectServerError, ex)
 {
     this.ServerEndPoint = serverEndPoint;
     this.ReconnectArgs  = reconnectArgs;
 }
Пример #5
0
 internal ConnectingEventArgs(ReconnectArgs reconnectArgs)
 {
     this.ReconnectArgs = reconnectArgs;
 }