예제 #1
0
        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();
            }
        }
예제 #2
0
        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));
                    }
                }
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
        }