Пример #1
0
 /// <summary>
 /// Processes the packet within the context. Returns true whether the packet was processed or throttled.
 /// </summary>
 /// <param name="channel">The through which the packet is coming/going out.</param>
 /// <param name="context">The packet context for this operation.</param>
 /// <returns>True whether the packet was processed or throttled, false otherwise.</returns>
 public static ProcessingState Process(Emitter.Connection channel, ProcessingContext context)
 {
     return(ProcessingState.Failure);
 }
Пример #2
0
        /// <summary>
        /// Processes the packet within the context. Returns true whether the packet was processed or throttled.
        /// </summary>
        /// <param name="channel">The through which the packet is coming/going out.</param>
        /// <param name="context">The packet context for this operation.</param>
        /// <returns>True whether the packet was processed or throttled, false otherwise.</returns>
        public static ProcessingState Process(Connection channel, ProcessingContext context)
        {
            // Get the buffer
            var buffer = context.Buffer;

            // Extract the message type first
            var pBuffer = buffer.AsBytePointer();

            if (!ValidMqtt(pBuffer))
            {
                return(ProcessingState.Failure);
            }

            // Do we have a full header?
            if (buffer.Length < MqttPacket.HeaderSize)
            {
                return(ProcessingState.InsufficientData);
            }

            // Get the length of the packet
            int headerSize;
            var length = PeekLength(pBuffer + 1, buffer.Length, out headerSize);

            if (length > MqttPacket.MaxPayloadSize)
            {
                return(ProcessingState.Failure);
            }

            // Do we have enough data?
            if (length == -1 || (headerSize + length) > buffer.Length)
            {
                return(ProcessingState.InsufficientData);
            }

            // There might be several packets in the same segment. We need to specify
            // that one is decoded and forward only that one to the next decoder.
            // However, we must not discard the segment completely as we might loose data!
            context.Throttle(headerSize + length);

            // Acquire the appropriate packet
            var msgType = (MqttPacketType)((*pBuffer & MqttPacket.MSG_TYPE_MASK) >> MqttPacket.MSG_TYPE_OFFSET);
            var packet  = Acquire(msgType, channel.Client);

            if (packet == null)
            {
                return(ProcessingState.Stop);
            }

            // If we don't have enough data...
            //if (length > buffer.Length)
            //    return ProcessingState.InsufficientData;

            // If we have protocol version set, add it to the packet
            var mqttCtx = channel.Client.Context;

            if (mqttCtx != null)
            {
                packet.ProtocolVersion = mqttCtx.Version;
                packet.IsEmitter       = mqttCtx.IsEmitter;
            }

            try
            {
                // Read the packet
                packet.TryRead(context.Buffer, headerSize, length);

                // Call the appropriate handler
                switch (msgType)
                {
                case MqttPacketType.Connect:
                    return(MqttHandler.OnConnect(channel.Client, packet as MqttConnectPacket));

                case MqttPacketType.Subscribe:
                    return(MqttHandler.OnSubscribe(channel.Client, packet as MqttSubscribePacket));

                case MqttPacketType.Unsubscribe:
                    return(MqttHandler.OnUnsubscribe(channel.Client, packet as MqttUnsubscribePacket));

                case MqttPacketType.PingReq:
                    return(MqttHandler.OnPing(channel.Client, packet as MqttPingReqPacket));

                case MqttPacketType.Disconnect:
                    return(MqttHandler.OnDisconnect(channel.Client, packet as MqttDisconnectPacket));

                case MqttPacketType.Publish:
                    return(MqttHandler.OnPublish(channel.Client, packet as MqttPublishPacket));

                case MqttPacketType.PubAck:
                    return(MqttHandler.OnPublishAck(channel.Client, packet as MqttPubackPacket));

                default: break;
                }
            }
            catch (Exception ex)
            {
                // Log the exception
                Service.Logger.Log(ex);
            }
            finally
            {
                // Release the packet now
                if (packet.Lifetime == PacketLifetime.Automatic)
                {
                    packet.TryRelease();
                }
            }

            // We're really done handling this, do not queue additional processors
            return(ProcessingState.Stop);
        }