private void Handshake(byte[] data, int dataOffset, int dataLength) { ActorFrameHeader actorHandshakeRequestFrameHeader = null; bool isHeaderDecoded = _channelConfiguration.FrameBuilder.TryDecodeFrameHeader( data, dataOffset, dataLength, out actorHandshakeRequestFrameHeader); if (isHeaderDecoded && actorHandshakeRequestFrameHeader.OpCode == OpCode.Hello) { byte[] payload; int payloadOffset; int payloadCount; _channelConfiguration.FrameBuilder.DecodePayload( data, dataOffset, actorHandshakeRequestFrameHeader, out payload, out payloadOffset, out payloadCount); var actorHandshakeRequestData = _channelConfiguration .FrameBuilder .ControlFrameDataDecoder .DecodeFrameData <ActorIdentity>(payload, payloadOffset, payloadCount); _remoteActor = actorHandshakeRequestData; } if (_remoteActor == null) { _log.ErrorFormat("Handshake with remote [{0}] failed, invalid actor description.", this.SessionKey); _innerSession.Close(); } else { var actorHandshakeResponseData = _channelConfiguration.FrameBuilder.ControlFrameDataEncoder.EncodeFrameData(_localActor); var actorHandshakeResponse = new WelcomeFrame(actorHandshakeResponseData); var actorHandshakeResponseBuffer = _channelConfiguration.FrameBuilder.EncodeFrame(actorHandshakeResponse); _innerSession.BeginSend(actorHandshakeResponseBuffer); IsHandshaked = true; _log.DebugFormat("Handshake with remote [{0}] successfully, SessionKey[{1}].", _remoteActor, this.SessionKey); if (Handshaked != null) { Handshaked(this, new ActorChannelSessionHandshakedEventArgs(this, _remoteActor)); } _keepAliveTracker.StartTimer(); } }
public void OnDataReceived(object sender, byte[] data, int dataOffset, int dataLength) { if (!IsHandshaked) { Handshake(data, dataOffset, dataLength); } else { _keepAliveTracker.OnDataReceived(); StopKeepAliveTimeoutTimer(); // intend to disable keep-alive timeout when receive anything ActorFrameHeader actorKeepAliveRequestFrameHeader = null; bool isHeaderDecoded = _channelConfiguration.FrameBuilder.TryDecodeFrameHeader( data, dataOffset, dataLength, out actorKeepAliveRequestFrameHeader); if (isHeaderDecoded && actorKeepAliveRequestFrameHeader.OpCode == OpCode.Ping) { _log.DebugFormat("KeepAlive receive request from remote actor [{0}] to local actor [{1}].", _remoteActor, _localActor); var actorKeepAliveResponse = new PongFrame(); var actorKeepAliveResponseBuffer = _channelConfiguration.FrameBuilder.EncodeFrame(actorKeepAliveResponse); _log.DebugFormat("KeepAlive send response from local actor [{0}] to remote actor [{1}].", _localActor, _remoteActor); _innerSession.Send(actorKeepAliveResponseBuffer); } else if (isHeaderDecoded && actorKeepAliveRequestFrameHeader.OpCode == OpCode.Pong) { _log.DebugFormat("KeepAlive receive response from remote actor [{0}] to local actor [{1}].", _remoteActor, _localActor); StopKeepAliveTimeoutTimer(); } else { if (SessionDataReceived != null) { SessionDataReceived(this, new ActorChannelSessionDataReceivedEventArgs( this, _remoteActor, data, dataOffset, dataLength)); } } } }
protected override void OnActorChannelDataReceived(object sender, ActorChannelDataReceivedEventArgs e) { ActorFrameHeader actorLookupRequestFrameHeader = null; bool isHeaderDecoded = this.ChannelConfiguration.FrameBuilder.TryDecodeFrameHeader( e.Data, e.DataOffset, e.DataLength, out actorLookupRequestFrameHeader); if (isHeaderDecoded && actorLookupRequestFrameHeader.OpCode == OpCode.Where) { byte[] payload; int payloadOffset; int payloadCount; this.ChannelConfiguration.FrameBuilder.DecodePayload( e.Data, e.DataOffset, actorLookupRequestFrameHeader, out payload, out payloadOffset, out payloadCount); var actorLookupRequestData = this.ChannelConfiguration .FrameBuilder .ControlFrameDataDecoder .DecodeFrameData <ActorIdentityLookup>(payload, payloadOffset, payloadCount); var lookupActorType = actorLookupRequestData != null ? actorLookupRequestData.Type : null; var actorCollection = new ActorIdentityCollection(); actorCollection.Items.AddRange(this.GetAllActors().Where(a => a.Type == lookupActorType).ToList()); var actorLookupResponseData = this.ChannelConfiguration.FrameBuilder.ControlFrameDataEncoder.EncodeFrameData(actorCollection); var actorLookupResponse = new HereFrame(actorLookupResponseData); var actorLookupRequestBuffer = this.ChannelConfiguration.FrameBuilder.EncodeFrame(actorLookupResponse); _log.DebugFormat("Lookup actors, ActorType[{0}], Count[{1}], RemoteActor[{2}].", lookupActorType, actorCollection.Items.Count, e.RemoteActor); this.Send(e.RemoteActor, actorLookupRequestBuffer); } else { base.OnActorChannelDataReceived(sender, e); } }
private void Handshake(TimeSpan timeout) { var actorHandshakeRequestData = _channelConfiguration.FrameBuilder.ControlFrameDataEncoder.EncodeFrameData(_localActor); var actorHandshakeRequest = new HelloFrame(actorHandshakeRequestData); var actorHandshakeRequestBuffer = _channelConfiguration.FrameBuilder.EncodeFrame(actorHandshakeRequest); ManualResetEventSlim waitingHandshaked = new ManualResetEventSlim(false); ActorTransportDataReceivedEventArgs handshakeResponseEvent = null; EventHandler <ActorTransportDataReceivedEventArgs> onHandshaked = (s, e) => { handshakeResponseEvent = e; waitingHandshaked.Set(); }; _connector.DataReceived += onHandshaked; _log.DebugFormat("Handshake request from local actor [{0}].", _localActor); _connector.BeginSend(actorHandshakeRequestBuffer); bool handshaked = waitingHandshaked.Wait(timeout); _connector.DataReceived -= onHandshaked; waitingHandshaked.Dispose(); if (handshaked && handshakeResponseEvent != null) { ActorFrameHeader actorHandshakeResponseFrameHeader = null; bool isHeaderDecoded = _channelConfiguration.FrameBuilder.TryDecodeFrameHeader( handshakeResponseEvent.Data, handshakeResponseEvent.DataOffset, handshakeResponseEvent.DataLength, out actorHandshakeResponseFrameHeader); if (isHeaderDecoded && actorHandshakeResponseFrameHeader.OpCode == OpCode.Welcome) { byte[] payload; int payloadOffset; int payloadCount; _channelConfiguration.FrameBuilder.DecodePayload( handshakeResponseEvent.Data, handshakeResponseEvent.DataOffset, actorHandshakeResponseFrameHeader, out payload, out payloadOffset, out payloadCount); var actorHandshakeResponseData = _channelConfiguration.FrameBuilder.ControlFrameDataDecoder.DecodeFrameData <ActorIdentity>( payload, payloadOffset, payloadCount); _remoteActor = actorHandshakeResponseData; _log.DebugFormat("Handshake response from remote actor [{0}].", _remoteActor); } if (_remoteActor == null) { _log.ErrorFormat("Handshake with remote [{0}] failed, invalid actor description.", this.ConnectToEndPoint); Close(); } else { _log.DebugFormat("Handshake with remote [{0}] successfully, RemoteActor[{1}].", this.ConnectToEndPoint, _remoteActor); IsHandshaked = true; if (Connected != null) { Connected(this, new ActorConnectedEventArgs(this.ConnectToEndPoint.ToString(), _remoteActor)); } _connector.DataReceived += OnDataReceived; _keepAliveTracker.StartTimer(); } } else { _log.ErrorFormat("Handshake with remote [{0}] timeout [{1}].", this.ConnectToEndPoint, timeout); Close(); } }
private IPEndPoint LookupRemoteActorEndPoint(string actorType, Func <IEnumerable <ActorIdentity>, ActorIdentity> matchActorFunc) { var actorLookupCondition = new ActorIdentityLookup() { Type = actorType, }; var actorLookupRequestData = _channelConfiguration.FrameBuilder.ControlFrameDataEncoder.EncodeFrameData(actorLookupCondition); var actorLookupRequest = new WhereFrame(actorLookupRequestData); var actorLookupRequestBuffer = _channelConfiguration.FrameBuilder.EncodeFrame(actorLookupRequest); ManualResetEventSlim waitingResponse = new ManualResetEventSlim(false); ActorDataReceivedEventArgs lookupResponseEvent = null; EventHandler <ActorDataReceivedEventArgs> onDataReceived = (s, e) => { lookupResponseEvent = e; waitingResponse.Set(); }; _centerChannel.DataReceived += onDataReceived; _centerChannel.BeginSend(_centerActor.Type, _centerActor.Name, actorLookupRequestBuffer); bool lookedup = waitingResponse.Wait(TimeSpan.FromSeconds(15)); _centerChannel.DataReceived -= onDataReceived; waitingResponse.Dispose(); if (lookedup && lookupResponseEvent != null) { ActorFrameHeader actorLookupResponseFrameHeader = null; bool isHeaderDecoded = _channelConfiguration.FrameBuilder.TryDecodeFrameHeader( lookupResponseEvent.Data, lookupResponseEvent.DataOffset, lookupResponseEvent.DataLength, out actorLookupResponseFrameHeader); if (isHeaderDecoded && actorLookupResponseFrameHeader.OpCode == OpCode.Here) { byte[] payload; int payloadOffset; int payloadCount; _channelConfiguration.FrameBuilder.DecodePayload( lookupResponseEvent.Data, lookupResponseEvent.DataOffset, actorLookupResponseFrameHeader, out payload, out payloadOffset, out payloadCount); var actorLookupResponseData = _channelConfiguration.FrameBuilder.ControlFrameDataDecoder.DecodeFrameData <ActorIdentityCollection>( payload, payloadOffset, payloadCount); var actors = actorLookupResponseData != null ? actorLookupResponseData.Items : null; if (actors != null) { _log.DebugFormat("Lookup actors [{0}].", actors.Count); var actor = matchActorFunc(actors); if (actor != null) { IPAddress actorAddress = ResolveIPAddress(actor.Address); int actorPort = int.Parse(actor.Port); var actorEndPoint = new IPEndPoint(actorAddress, actorPort); return(actorEndPoint); } } } } return(null); }