Ejemplo n.º 1
0
        /// <summary>
        /// Invoked when a publish packet is received.
        /// </summary>
        /// <param name="client">The client sending the packet.</param>
        /// <param name="packet">The packet received from the client.</param>
        public static ProcessingState OnPublish(IClient client, MqttPublishPacket packet)
        {
            // Publish through emitter
            HandlePublish.Process(client, packet.Channel, packet.Message);

            // Send the ack and stop the processing
            if (client.Context.QoS > QoS.AtMostOnce)
            {
                client.SendMqttPuback(packet.MessageId);
            }

            return(ProcessingState.Stop);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sends a response to the client.
        /// </summary>
        /// <param name="client">The client to reply to.</param>
        /// <param name="response">The emitte response to send.</param>
        private static void SendResponse(IClient client, string channel, EmitterResponse response)
        {
            // Serialize the response
            var serialized = JsonConvert.SerializeObject(response, Formatting.Indented);

            if (serialized == null)
            {
                return;
            }

            // Send the message out
            var msg = MqttPublishPacket.Acquire();

            msg.Channel = channel;
            msg.Message = serialized.AsUTF8().AsSegment();
            client.Send(msg);
        }
Ejemplo n.º 3
0
        private static MqttPacket Acquire(MqttPacketType type, IClient client)
        {
            switch (type)
            {
            case MqttPacketType.Connect: return(MqttConnectPacket.Acquire());

            case MqttPacketType.Subscribe: return(MqttSubscribePacket.Acquire());

            case MqttPacketType.Unsubscribe: return(MqttUnsubscribePacket.Acquire());

            case MqttPacketType.PingReq: return(MqttPingReqPacket.Acquire());

            case MqttPacketType.Disconnect: return(MqttDisconnectPacket.Acquire());

            case MqttPacketType.Publish: return(MqttPublishPacket.Acquire());

            case MqttPacketType.PubAck: return(MqttPubackPacket.Acquire());

            default:
                Service.Logger.Log("Unknown MQTT Type: " + type);
                return(null);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Occurs when the remote client attempts to subscribe to a hub.
        /// </summary>
        /// <param name="client">The remote client.</param>
        /// <param name="channel">The full channel string.</param>
        public static EmitterEventCode Process(IClient client, string channel)
        {
            try
            {
                // Parse the channel
                EmitterChannel info;
                if (!EmitterChannel.TryParse(channel, true, out info))
                {
                    return(EmitterEventCode.BadRequest);
                }

                // Simple ACK for api subscribe. We don't really need to subscribe as
                // this uses request/response topology and hence the response is sent
                // through the same TCP connection.
                if (info.Key == "emitter")
                {
                    return(EmitterEventCode.Success);
                }

                // Attempt to parse the key
                SecurityKey key;
                if (!SecurityKey.TryParse(info.Key, out key))
                {
                    return(EmitterEventCode.BadRequest);
                }

                // Has the key expired?
                if (key.IsExpired)
                {
                    return(EmitterEventCode.Unauthorized);
                }

                // Have we already subscribed?
                //if (client[channel] != null)
                //    return EmitterEventCode.Success;

                // Attempt to fetch the contract using the key. Underneath, it's cached.
                var contract = Services.Contract.GetByKey(key.Contract) as EmitterContract;
                if (contract == null)
                {
                    return(EmitterEventCode.NotFound);
                }

                // Check if the payment state is valid
                if (contract.Status == EmitterContractStatus.Refused)
                {
                    return(EmitterEventCode.PaymentRequired);
                }

                // Validate the contract
                if (!contract.Validate(ref key))
                {
                    return(EmitterEventCode.Unauthorized);
                }

                // Check if the key has the permission to read here
                if (!key.HasPermission(SecurityAccess.Read))
                {
                    return(EmitterEventCode.Unauthorized);
                }

                // Check if the key has the permission for the required channel
                if (key.Target != 0 && info.Target != key.Target)
                {
                    return(EmitterEventCode.Unauthorized);
                }

                // Subscribe to the channel
                var subs = Dispatcher.Subscribe(client, key.Contract, info.Channel, SubscriptionInterest.Messages);

                // Check if the history was also requested and we have the permission to do so
                var last = 0;
                if (!info.RequestedLast(out last) || !key.HasPermission(SecurityAccess.Load))
                {
                    return(EmitterEventCode.Success);
                }

                // Get the ssid
                var ssid = EmitterChannel.Ssid(key.Contract, info.Channel);

                // Stream the history
                Services.Storage
                .GetLastAsync(key.Contract, ssid, last)
                .ContinueWith(async(t) =>
                {
                    // Now send each message in order
                    var stream = t.Result;
                    while (stream.HasNext)
                    {
                        // Get the message asyncronously
                        var item = await stream.GetNext();
                        if (item.Count == 0)
                        {
                            continue;
                        }

                        // Increment the counter
                        Service.MessageSent?.Invoke(contract, channel, item.Count);

                        // Send the message out
                        var msg     = MqttPublishPacket.Acquire();
                        msg.Channel = info.Channel;
                        msg.Message = item;
                        client.Send(msg);
                    }
                });

                // We have successfully subscribed
                return(EmitterEventCode.Success);
            }
            catch (NotImplementedException)
            {
                // We've got a not implemented exception
                return(EmitterEventCode.NotImplemented);
            }
            catch (Exception ex)
            {
                // We need to log it
                Service.Logger.Log(ex);

                // We've got a an internal error
                return(EmitterEventCode.ServerError);
            }
        }
Ejemplo n.º 5
0
 public static void SendMqttPublish(this IClient client, string channel, ArraySegment <byte> message)
 {
     client.Send(
         MqttPublishPacket.Acquire(channel, message)
         );
 }