public override void ChannelRead(IChannelHandlerContext context, object message) { SafeProcess(() => { var msg = (Message)message; if (msg.Type == MessageType.LoginResponse) { var result = CertifiedResult.FromMessage(msg); if (result.IsOK) { //认证成功 Online(context); context.FireChannelRead(msg); } else { //认证失败 ClientEvents.AsyncRaiseError(this.Client, new LoginFailedException(result.Info)); context.CloseAsync(); } } else { //不是登录认证的响应,那么交由下一个通道处理器 context.FireChannelRead(msg); } }, context); }
public override void ChannelRead(IChannelHandlerContext context, object message) { SafeProcess(() => { var msg = (Message)message; if (msg.Type == MessageType.LoginResponse) { DisposeCancellation(); _heartBeatCancellation = new CancellationTokenSource(); //得到登录响应后,开始心跳 context.Executor.ScheduleAsync(RunHeartBeat, context, _delay, _heartBeatCancellation.Token); } else if (msg.Type == MessageType.HeartBeatResponse) { //得到回复后继续心跳 context.Executor.ScheduleAsync(RunHeartBeat, context, _delay, _heartBeatCancellation.Token); ClientEvents.AsyncRaiseHeartBeatReceived(this.Client, this.Client.ServerEndPoint); } else { context.FireChannelRead(message); } }, context); }
internal void AddOrUpdateParticipant(Participant participant) { lock (_participants) { if (!_participants.ContainsKey(participant.Id)) { _participants.Add(participant.Id, participant); ClientEvents.AsyncRaiseParticipantAdded(this.Client, this, participant, IsLocal(participant)); } else { _participants[participant.Id] = participant; ClientEvents.AsyncRaiseParticipantUpdated(this.Client, this, participant, IsLocal(participant)); } if (!string.IsNullOrEmpty(participant.Orgin)) { if (!_participantsForOrigin.ContainsKey(participant.Orgin)) { _participantsForOrigin.Add(participant.Orgin, participant); } else { _participantsForOrigin[participant.Orgin] = participant; } } //exist.LastActiveTime = DateTime.Now; //更新最后一次活跃时间 } }
/// <summary> /// 会话上线 /// </summary> /// <param name="session"></param> /// <param name="package"></param> protected void Online(IChannelHandlerContext ctx) { this.Client.Status = ConnectionStatus.Connected; this.Client.Channel = ctx.Channel; //原本是不需要再这里设置的,但是在一些很偶然的情况下, //我们发现通过Channel = bootstrap.ConnectAsync(this.ServerEndPoint).Result; //会比这里更加晚执行,导致Channel为null //所以此处手动赋值一次 ClientEvents.AsyncRaiseConnected(this.Client, this.Client.ServerEndPoint); //触发已连接的事件 }
protected void SafeProcess(Action action, IChannelHandlerContext context) { try { action(); } catch (Exception ex) { Offline(context); ClientEvents.AsyncRaiseError(this.Client, ex); } }
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) { SafeProcess(() => { if (Util.OfflineHandle(context, exception)) { return; } ClientEvents.AsyncRaiseError(this.Client, exception); context.FireExceptionCaught(exception); }, context); }
/// <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); }
internal void RemoveParticipant(Participant participant) { lock (_participants) { if (_participants.Remove(participant.Id)) { ClientEvents.AsyncRaiseParticipantRemoved(this.Client, this, participant, IsLocal(participant)); } if (!string.IsNullOrEmpty(participant.Orgin)) { _participantsForOrigin.Remove(participant.Orgin); } } }
private void _Disconnect(bool isDropped) { if (_disposed) { return; } if (this.Status != ConnectionStatus.Connected) { return; } this.Status = ConnectionStatus.Disconnected; try { DisposeReconnectCancellation(); if (Channel != null) { this.LeaveAll(); _DisposeChannel(); ClientEvents.AsyncRaiseDisconnected(this, isDropped); } } catch (Exception ex) { ClientEvents.AsyncRaiseError(this, ex); } finally { if (isDropped) { _pipeline.Queue(() => { _Reconnect(new ReconnectArgs()); }); } } }
private void ReceivedMessage(Message message) { //触发接收消息的事件 ClientEvents.AsyncRaiseMessageReceived(this.Client, message); }
/// <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); }); } } }