Example #1
0
        public override void ChannelInactive(IChannelHandlerContext ctx)
        {
            ThreadLocalObjectList output = ThreadLocalObjectList.Take();

            try
            {
                if (this.cumulation != null)
                {
                    this.CallDecode(ctx, this.cumulation, output);
                    this.DecodeLast(ctx, this.cumulation, output);
                }
                else
                {
                    this.DecodeLast(ctx, Unpooled.Empty, output);
                }
            }
            catch (DecoderException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new DecoderException(e);
            }
            finally
            {
                try
                {
                    if (this.cumulation != null)
                    {
                        this.cumulation.Release();
                        this.cumulation = null;
                    }
                    int size = output.Count;
                    for (int i = 0; i < size; i++)
                    {
                        ctx.FireChannelRead(output[i]);
                    }
                    if (size > 0)
                    {
                        // Something was read, call fireChannelReadComplete()
                        ctx.FireChannelReadComplete();
                    }
                    ctx.FireChannelInactive();
                }
                finally
                {
                    // recycle in all cases
                    output.Return();
                }
            }
        }
Example #2
0
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            var data = message as IByteBuffer;

            if (data != null)
            {
                ThreadLocalObjectList output = ThreadLocalObjectList.Take();
                try
                {
                    this.first = this.cumulation == null;
                    if (this.first)
                    {
                        this.cumulation = data;
                    }
                    else
                    {
                        this.cumulation = this.cumulator(context.Allocator, this.cumulation, data);
                    }
                    this.CallDecode(context, this.cumulation, output);
                }
                catch (DecoderException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DecoderException(ex);
                }
                finally
                {
                    if (this.cumulation != null && !this.cumulation.IsReadable())
                    {
                        this.cumulation.Release();
                        this.cumulation = null;
                    }
                    int size = output.Count;
                    this.decodeWasNull = size == 0;

                    for (int i = 0; i < size; i++)
                    {
                        context.FireChannelRead(output[i]);
                    }
                    output.Return();
                }
            }
            else
            {
                context.FireChannelRead(message);
            }
        }
Example #3
0
        static void EncodeSubscribeMessage(IByteBufferAllocator bufferAllocator, SubscribePacket packet, List <object> output)
        {
            const int VariableHeaderSize = PacketIdLength;
            int       payloadBufferSize  = 0;

            ThreadLocalObjectList encodedTopicFilters = ThreadLocalObjectList.Take();

            try
            {
                foreach (SubscriptionRequest topic in packet.Requests)
                {
                    byte[] topicFilterBytes = EncodeStringInUtf8(topic.TopicFilter);
                    payloadBufferSize += StringSizeLength + topicFilterBytes.Length + 1; // length, value, QoS
                    encodedTopicFilters.Add(topicFilterBytes);
                }

                int variablePartSize      = VariableHeaderSize + payloadBufferSize;
                int fixedHeaderBufferSize = 1 + MaxVariableLength;

                IByteBuffer buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize);
                buf.WriteByte(CalculateFirstByteOfFixedHeader(packet));
                WriteVariableLengthInt(buf, variablePartSize);

                // Variable Header
                buf.WriteShort(packet.PacketId); // todo: review: validate?

                // Payload
                for (int i = 0; i < encodedTopicFilters.Count; i++)
                {
                    var topicFilterBytes = (byte[])encodedTopicFilters[i];
                    buf.WriteShort(topicFilterBytes.Length);
                    buf.WriteBytes(topicFilterBytes, 0, topicFilterBytes.Length);
                    buf.WriteByte((int)packet.Requests[i].QualityOfService);
                }

                output.Add(buf);
            }
            finally
            {
                encodedTopicFilters.Return();
            }
        }
Example #4
0
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            ThreadLocalObjectList output = ThreadLocalObjectList.Take();

            try
            {
                if (this.AcceptInboundMessage(message))
                {
                    T cast = (T)message;
                    try
                    {
                        this.Decode(context, cast, output);
                    }
                    finally
                    {
                        ReferenceCountUtil.Release(cast);
                    }
                }
                else
                {
                    output.Add(message);
                }
            }
            catch (DecoderException e)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new DecoderException(e);
            }
            finally
            {
                int size = output.Count;
                for (int i = 0; i < size; i++)
                {
                    context.FireChannelRead(output[i]);
                }
                output.Return();
            }
            base.ChannelRead(context, message);
        }
Example #5
0
        public override Task WriteAsync(IChannelHandlerContext ctx, object msg)
        {
            Task result;
            ThreadLocalObjectList output = null;

            try
            {
                if (this.AcceptOutboundMessage(msg))
                {
                    output = ThreadLocalObjectList.Take();
                    var cast = (T)msg;
                    try
                    {
                        this.Encode(ctx, cast, output);
                    }
                    finally
                    {
                        ReferenceCountUtil.Release(cast);
                    }

                    if (output.Count == 0)
                    {
                        output.Return();
                        output = null;

                        throw new EncoderException(this.GetType().Name + " must produce at least one message.");
                    }
                }
                else
                {
                    return(ctx.WriteAsync(msg));
                }
            }
            catch (EncoderException e)
            {
                return(TaskEx.FromException(e));
            }
            catch (Exception ex)
            {
                return(TaskEx.FromException(new EncoderException(ex))); // todo: we don't have a stack on EncoderException but it's present on inner exception.
            }
            finally
            {
                if (output != null)
                {
                    int lastItemIndex = output.Count - 1;
                    if (lastItemIndex == 0)
                    {
                        result = ctx.WriteAsync(output[0]);
                    }
                    else if (lastItemIndex > 0)
                    {
                        for (int i = 0; i < lastItemIndex; i++)
                        {
                            // we don't care about output from these messages as failure while sending one of these messages will fail all messages up to the last message - which will be observed by the caller in Task result.
                            ctx.WriteAsync(output[i]); // todo: optimize: once IChannelHandlerContext allows, pass "not interested in task" flag
                        }
                        result = ctx.WriteAsync(output[lastItemIndex]);
                    }
                    else
                    {
                        // 0 items in output - must never get here
                        result = null;
                    }
                    output.Return();
                }
                else
                {
                    // output was reset during exception handling - must never get here
                    result = null;
                }
            }
            return(result);
        }