Azure / DotNetty

DotNetty project – a port of netty, event-driven asynchronous network application framework
Other
4.09k stars 977 forks source link

Storing stateful information #136

Closed Tochemey closed 8 years ago

Tochemey commented 8 years ago

Hello,

I am having a little challenge on how to store a state property on a handler and get the value of that state when needed. Let me paint a simple scenario. Assuming we have a client connecting to a remote server. When the connection is successful then the client sends some authentication message to the remote peer to get authenticated. This authentication can only be done when the remote peer requests for it during the connection process. This is the sample code I have written so far but I do not know how to get the _authenticated value because anytime I want to access it it is false but when I debug it is set to true.

    public class EslClientHandler : ChannelHandlerAdapter {
        private bool _authenticated;

        private readonly Queue<CommandAsyncEvent> _commandAsyncEvents; 
        /// <summary>
        ///     This password is used to connect to mod_event_socket module of freeSwitch.
        /// </summary>
        private readonly string _password;

        public EslClientHandler(string password) {
            _password = password;
            _commandAsyncEvents = new Queue<CommandAsyncEvent>();
        }

        public EslClientHandler() : this("ClueCon") {}

        /// <summary>
        ///     This helps read the data received from the socket client.
        /// </summary>
        /// <param name="context">Channel context</param>
        /// <param name="message">the decoded message received</param>
        public override async void ChannelRead(IChannelHandlerContext context,
            object message) {
            var decodedMessage = message as EslMessage;
            if (decodedMessage != null) {
                var contentType = decodedMessage.ContentType();
                if (contentType.Equals(EslHeadersValues.AuthRequest)) {
                    await Authenticate(context);
                    return;
                }

                if (contentType.Equals(EslHeadersValues.CommandReply)) {
                    CommandAsyncEvent  commandAsyncEvent = _commandAsyncEvents.Dequeue();
                    CommandReply reply = new CommandReply(commandAsyncEvent.Command.Command, decodedMessage);
                    commandAsyncEvent.Complete(reply);
                }
            }
        }

        public async Task<CommandReply> SendCommand(BaseCommand command, IChannelHandlerContext context) {
            CommandAsyncEvent asyncEvent = new CommandAsyncEvent(command);
            _commandAsyncEvents.Enqueue(asyncEvent);
            await context.WriteAndFlushAsync(command);
            return await asyncEvent.Task;
        }

        protected async Task Authenticate(IChannelHandlerContext context) {
            AuthCommand command = new AuthCommand(_password);
            CommandReply reply = await SendCommand(command, context);
            _authenticated = reply.IsOk;
        }

        public bool IsReady() {
            return _authenticated;
        }
    }
nayato commented 8 years ago

_authenticated is just a field on an object. There is no magic in DotNetty. Field will hold true when it is set to true. From your example it isn't clear how it is being accessed.

Tochemey commented 8 years ago

I figured it out how to access it by using the following sample code:

 var handler = (EslClientHandler) _channel.Pipeline.Last();
 Authenticated = handler.Authenticated;