private void Handshake(ActorTransportDataReceivedEventArgs e)
        {
            var actorHandshakeRequest = _decoder.Decode <ActorHandshakeRequest>(e.Data, e.DataOffset, e.DataLength);
            var remoteActor           = actorHandshakeRequest.ActorDescription;

            if (remoteActor == null)
            {
                _log.ErrorFormat("Handshake with remote [{0}] failed, invalid actor description.", e.SessionKey);
                _listener.CloseSession(e.SessionKey);
            }
            else
            {
                var actorHandshakeResponse = new ActorHandshakeResponse()
                {
                    ActorDescription = _localActor,
                };
                var actorHandshakeResponseBuffer = _encoder.Encode(actorHandshakeResponse);
                _listener.SendToAsync(e.SessionKey, actorHandshakeResponseBuffer);

                _log.InfoFormat("Handshake with remote [{0}] successfully, SessionKey[{1}].", remoteActor, e.SessionKey);
                _remoteActors.Add(e.SessionKey, remoteActor);
                _actorKeys.Add(remoteActor.GetKey(), e.SessionKey);

                if (Connected != null)
                {
                    Connected(this, new ActorConnectedEventArgs(e.SessionKey, remoteActor));
                }
            }
        }
        public IPEndPoint LookupRemoteActorEndPoint(string actorType, string actorName)
        {
            var actorLookupRequest       = new ActorLookupRequest();
            var actorLookupRequestBuffer = _encoder.Encode(actorLookupRequest);

            ManualResetEventSlim       waitingResponse = new ManualResetEventSlim(false);
            ActorDataReceivedEventArgs responseEvent   = null;
            EventHandler <ActorDataReceivedEventArgs> onDataReceived =
                (s, e) =>
            {
                responseEvent = e;
                waitingResponse.Set();
            };

            _centerChannel.DataReceived += onDataReceived;
            _centerChannel.SendAsync(_centerActor.Type, _centerActor.Name, actorLookupRequestBuffer);

            bool lookedup = waitingResponse.Wait(TimeSpan.FromSeconds(15));

            _centerChannel.DataReceived -= onDataReceived;
            waitingResponse.Dispose();

            if (lookedup && responseEvent != null)
            {
                var actorLookupResponse = _decoder.Decode <ActorLookupResponse>(
                    responseEvent.Data, responseEvent.DataOffset, responseEvent.DataLength);
                var actors = actorLookupResponse.Actors;
                if (actors != null)
                {
                    _log.InfoFormat("Lookup actors [{0}].", actors.Count);
                    var actor = actors.FirstOrDefault(a => a.Type == actorType && a.Name == actorName);
                    if (actor != null)
                    {
                        IPAddress actorAddress  = ResolveIPAddress(actor.Address);
                        int       actorPort     = int.Parse(actor.Port);
                        var       actorEndPoint = new IPEndPoint(actorAddress, actorPort);
                        return(actorEndPoint);
                    }
                }
            }

            throw new ActorNotFoundException(string.Format(
                                                 "Cannot lookup remote actor, Type[{0}], Name[{1}].", actorType, actorName));
        }
        private void Handshake(TimeSpan timeout)
        {
            var actorHandshakeRequest = new ActorHandshakeRequest()
            {
                ActorDescription = _localActor,
            };
            var actorHandshakeRequestBuffer = _encoder.Encode(actorHandshakeRequest);

            ManualResetEventSlim waitingHandshaked = new ManualResetEventSlim(false);
            ActorTransportDataReceivedEventArgs handshakeResponseEvent      = null;
            EventHandler <ActorTransportDataReceivedEventArgs> onHandshaked =
                (s, e) =>
            {
                handshakeResponseEvent = e;
                waitingHandshaked.Set();
            };

            _connector.DataReceived += onHandshaked;
            _log.InfoFormat("Handshake request from local actor [{0}].", _localActor);
            _connector.SendAsync(actorHandshakeRequestBuffer);

            bool handshaked = waitingHandshaked.Wait(timeout);

            _connector.DataReceived -= onHandshaked;
            waitingHandshaked.Dispose();

            if (handshaked && handshakeResponseEvent != null)
            {
                var actorHandshakeResponse = _decoder.Decode <ActorHandshakeResponse>(
                    handshakeResponseEvent.Data, handshakeResponseEvent.DataOffset, handshakeResponseEvent.DataLength);
                _remoteActor = actorHandshakeResponse.ActorDescription;
                _log.InfoFormat("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.InfoFormat("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;
                }
            }
            else
            {
                _log.ErrorFormat("Handshake with remote [{0}] timeout [{1}].", this.ConnectToEndPoint, timeout);
                Close();
            }
        }