Inheritance: IDisposable
 public TokenChecker(GatewayInitiator initiator, TcpGateway gateway, Socket socket)
 {
     _initiator = initiator;
     _gateway = gateway;
     _logger = initiator.CreateChannelLogger(socket.RemoteEndPoint, socket);
     _socket = socket;
     _connection = new TcpConnection(_logger, socket) { Settings = initiator.ConnectionSettings };
 }
 public TcpChannel(GatewayInitiator initiator, Socket socket, object tag)
 {
     // open by client connection.
     _initiator = initiator;
     _logger = _initiator.CreateChannelLogger(socket.RemoteEndPoint, socket);
     _socket = socket;
     _connection = new TcpConnection(_logger, _socket) { Settings = initiator.ConnectionSettings };
     _tag = tag;
 }
        public TcpChannel(GatewayInitiator initiator, TcpConnection connection, object tag, Tuple<IActorRef, TaggedType[], ActorBindingFlags> bindingActor)
        {
            // open by registerd token.
            _initiator = initiator;
            _logger = initiator.CreateChannelLogger(connection.RemoteEndPoint, connection.Socket);
            _socket = connection.Socket;
            _connection = connection;
            _tag = tag;

            BindActor(bindingActor.Item1, bindingActor.Item2.Select(t => new BoundType(t)), bindingActor.Item3);
        }
        protected void OnConnectionReceive(TcpConnection connection, object packet)
        {
            _connection.Closed -= OnConnectionClose;
            _connection.Received -= OnConnectionReceive;

            try
            {
                // Before token is validated

                var p = packet as Packet;
                if (p == null)
                {
                    _eventStream.Publish(new Warning(
                        _self.Path.ToString(), GetType(),
                        $"Receives null packet from {_connection?.RemoteEndPoint}"));
                    return;
                }

                if (p.Type != PacketType.System || (p.Message is string) == false)
                {
                    _eventStream.Publish(new Warning(
                        _self.Path.ToString(), GetType(),
                        $"Receives a bad packet without a message from {_connection?.RemoteEndPoint}"));
                    return;
                }

                // Try to open

                var token = (string)p.Message;
                var succeeded = _gateway.EstablishChannel(token, _connection);
                if (succeeded)
                {
                    // set null to avoid closing connection in PostStop
                    _connection = null;
                }
                else
                {
                    _eventStream.Publish(new Warning(
                        _self.Path.ToString(), GetType(),
                        $"Receives wrong token({token}) from {_connection?.RemoteEndPoint}"));
                    return;
                }
            }
            finally
            {
                // This actor will be destroyed anyway after this call.
                _self.Tell(PoisonPill.Instance);
            }
        }
 public AcceptByTokenMessage(TcpConnection connection, object tag, Tuple<IActorRef, TaggedType[], ActorBindingFlags> bindingActor)
 {
     Connection = connection;
     Tag = tag;
     BindingActor = bindingActor;
 }
        // Called by Another Worker Threads
        internal bool EstablishChannel(string token, TcpConnection connection)
        {
            WaitingItem item;

            lock (_waitingMap)
            {
                if (_waitingMap.TryGetValue(token, out item) == false)
                    return false;

                _waitingMap.Remove(token);
            }

            _self.Tell(new AcceptByTokenMessage(connection, item.Tag, item.BindingActor), _self);
            return true;
        }
 protected void OnConnectionClose(TcpConnection connection, int reason)
 {
     _self.Tell(PoisonPill.Instance);
 }
 protected void OnConnectionClose(TcpConnection connection, int reason)
 {
     _self.Tell(PoisonPill.Instance);
 }
        // BEWARE: Called by Network Thread
        private void OnConnectionReceive(TcpConnection connection, object packet)
        {
            // The thread that call this function is different from actor context thread.
            // To deal with this contention lock protection is required.

            var p = packet as Packet;
            if (p == null)
            {
                _eventStream.Publish(new Warning(
                    _self.Path.ToString(), GetType(),
                    $"Receives null packet from {_connection?.RemoteEndPoint}"));
                return;
            }

            var msg = p.Message as IInterfacedPayload;
            if (msg == null)
            {
                _eventStream.Publish(new Warning(
                    _self.Path.ToString(), GetType(),
                    $"Receives a bad packet without a message from {_connection?.RemoteEndPoint}"));
                return;
            }

            var actor = GetBoundActor(p.ActorId);
            if (actor == null)
            {
                if (p.RequestId != 0)
                {
                    _connection.Send(new Packet
                    {
                        Type = PacketType.Response,
                        ActorId = p.ActorId,
                        RequestId = p.RequestId,
                        Message = null,
                        Exception = new RequestTargetException()
                    });
                }
                return;
            }

            var boundType = actor.FindBoundType(msg.GetInterfaceType());
            if (boundType == null)
            {
                if (p.RequestId != 0)
                {
                    _connection.Send(new Packet
                    {
                        Type = PacketType.Response,
                        ActorId = p.ActorId,
                        RequestId = p.RequestId,
                        Message = null,
                        Exception = new RequestHandlerNotFoundException()
                    });
                }
                return;
            }

            if (boundType.IsTagOverridable)
            {
                var tagOverridable = (IPayloadTagOverridable)p.Message;
                tagOverridable.SetTag(boundType.TagValue);
            }

            var observerUpdatable = p.Message as IPayloadObserverUpdatable;
            if (observerUpdatable != null)
            {
                observerUpdatable.Update(o =>
                {
                    var observer = (InterfacedObserver)o;
                    if (observer != null)
                        observer.Channel = new AkkaReceiverNotificationChannel(_self);
                });
            }

            actor.Actor.Tell(new RequestMessage
            {
                RequestId = p.RequestId,
                InvokePayload = (IInterfacedPayload)p.Message
            }, _self);
        }
 // BEWARE: Called by Network Thread
 private void OnConnectionClose(TcpConnection connection, int reason)
 {
     RunTask(() => Close(), _self);
 }
 public AcceptByTokenMessage(TcpConnection connection, object tag, Tuple <IActorRef, TaggedType[], ActorBindingFlags> bindingActor)
 {
     Connection   = connection;
     Tag          = tag;
     BindingActor = bindingActor;
 }
        // BEWARE: Called by Network Thread
        private void OnConnectionReceive(TcpConnection connection, object packet)
        {
            // The thread that call this function is different from actor context thread.
            // To deal with this contention lock protection is required.

            var p = packet as Packet;

            if (p == null)
            {
                _eventStream.Publish(new Warning(
                                         _self.Path.ToString(), GetType(),
                                         $"Receives null packet from {_connection?.RemoteEndPoint}"));
                return;
            }

            var msg = p.Message as IInterfacedPayload;

            if (msg == null)
            {
                _eventStream.Publish(new Warning(
                                         _self.Path.ToString(), GetType(),
                                         $"Receives a bad packet without a message from {_connection?.RemoteEndPoint}"));
                return;
            }

            var actor = GetBoundActor(p.ActorId);

            if (actor == null)
            {
                if (p.RequestId != 0)
                {
                    _connection.Send(new Packet
                    {
                        Type      = PacketType.Response,
                        ActorId   = p.ActorId,
                        RequestId = p.RequestId,
                        Message   = null,
                        Exception = new RequestTargetException()
                    });
                }
                return;
            }

            var boundType = actor.FindBoundType(msg.GetInterfaceType());

            if (boundType == null)
            {
                if (p.RequestId != 0)
                {
                    _connection.Send(new Packet
                    {
                        Type      = PacketType.Response,
                        ActorId   = p.ActorId,
                        RequestId = p.RequestId,
                        Message   = null,
                        Exception = new RequestHandlerNotFoundException()
                    });
                }
                return;
            }

            if (boundType.IsTagOverridable)
            {
                var tagOverridable = (IPayloadTagOverridable)p.Message;
                tagOverridable.SetTag(boundType.TagValue);
            }

            var observerUpdatable = p.Message as IPayloadObserverUpdatable;

            if (observerUpdatable != null)
            {
                observerUpdatable.Update(o =>
                {
                    var observer = (InterfacedObserver)o;
                    if (observer != null)
                    {
                        observer.Channel = new AkkaReceiverNotificationChannel(_self);
                    }
                });
            }

            actor.Actor.Tell(new RequestMessage
            {
                RequestId     = p.RequestId,
                InvokePayload = (IInterfacedPayload)p.Message
            }, _self);
        }
 // BEWARE: Called by Network Thread
 private void OnConnectionClose(TcpConnection connection, int reason)
 {
     RunTask(() => Close(), _self);
 }