Exemplo n.º 1
0
        private async Task ReceiveHubMessagesAsync()
        {
            using (Message receivedMessage = await DeviceClient.ReceiveAsync(TimeSpan.FromSeconds(30)).ConfigureAwait(false))
            {
                if (receivedMessage == null)
                {
                    Console.WriteLine("\t{0}> Timed out", DateTime.Now.ToLocalTime());
                    return;
                }

                var message = new MqttApplicationMessageBuilder()
                              .WithPayload(receivedMessage.GetBytes());
                string payload = Encoding.ASCII.GetString(receivedMessage.GetBytes());
                Console.WriteLine("\t{0}> Received message: {1}", DateTime.Now.ToLocalTime(), payload);
                if (receivedMessage.Properties.ContainsKey("topic"))
                {
                    message.WithTopic(receivedMessage.Properties["topic"]);
                }
                var keyExclude = new string[] { "topic", "clientId" };
                foreach (var prop in receivedMessage.Properties.Where(k => !keyExclude.Contains(k.Key)))
                {
                    message.WithUserProperty(prop.Key, prop.Value);
                }
                await LocalClient.PublishAsync(message.Build(), CancellationToken.None);

                await DeviceClient.CompleteAsync(receivedMessage).ConfigureAwait(false);
            }
        }
Exemplo n.º 2
0
        public async Task PublishAsync(string topic, byte[] payload, Dictionary <string, string> properties, Qos qos, CancellationToken cancellationToken)
        {
            var mqttMessageBuilder = new MqttApplicationMessageBuilder()
                                     .WithTopic(topic)
                                     .WithPayload(payload)
                                     .WithQualityOfServiceLevel(MapQos(qos));

            if (properties != null)
            {
                foreach (var entry in properties)
                {
                    mqttMessageBuilder.WithUserProperty(entry.Key, entry.Value);
                }
            }

            MqttClientPublishResult publishResult;

            try
            {
                publishResult = await client.PublishAsync(mqttMessageBuilder.Build(), cancellationToken);
            }
            catch (Exception e)
            {
                throw new MqttException(cause: e);
            }

            ValidatePublishResult(publishResult);
        }
Exemplo n.º 3
0
        private async Task HandleApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs eventArgs)
        {
            if (!eventArgs.ApplicationMessage.Topic.Contains(GetRequestTopic(null, null)))
            {
                return;
            }

            var message    = eventArgs.ApplicationMessage;
            var methodName = message.GetUserProperty("Method");
            var id         = message.GetUserProperty("Id");
            var timeout    = message.GetUserProperty <int?>("Timeout");
            var broadcast  = message.GetUserProperty <bool?>("Broadcast") ?? false;
            var noResponse = message.GetUserProperty <bool?>("NoResponse") ?? false;
            var clientId   = GetSource(message.Topic);

            using var serviceScope = _serviceProvider.CreateScope();
            using var cts          = timeout.HasValue ? new CancellationTokenSource(timeout.Value * 1000) : new CancellationTokenSource();
            var responseBuilder = new MqttApplicationMessageBuilder()
                                  .WithContentType(DefaultSerializer.ContentType)
                                  .WithTopic(GetResponseTopic(GetSource(message.Topic)))
                                  .WithAtLeastOnceQoS();

            if (broadcast)
            {
                responseBuilder.WithUserProperty("Broadcast", true.ToString());
            }
            if (timeout > 0)
            {
                responseBuilder.WithMessageExpiryInterval((uint)timeout.Value);
            }

            try
            {
                if (!RpcMethodResolver.Methods.TryGetValue(methodName, out var method))
                {
                    if (string.IsNullOrEmpty(id) || noResponse)
                    {
                        return;
                    }
                    throw new EntryPointNotFoundException($"Method '{methodName}' not found.");
                }

                var parameters = method.GetParameters();

                object[] args;
                switch (parameters.Length)
                {
                case 0:
                    args = null;
                    break;

                case 1:
                    var parameterInfo = parameters.First();
                    args = parameterInfo.ParameterType == typeof(byte[])
                            ? new[] { (object)message.Payload }
                            : new[] { DefaultSerializer.Deserialize(message.Payload, parameterInfo.ParameterType) };
                    break;

                default:
                    _logger.Error(new NotImplementedException(), "Multiple parameters resolving has not been supported yet, please use a key-value object.");
                    return;
                }

                var rpcService = (IRpcService)serviceScope.ServiceProvider.GetService(method.DeclaringType);

                rpcService.CurrentContext = new RpcContext
                {
                    Topic          = message.Topic,
                    RemoteClientId = clientId
                };

                var task = Task.Run(async() =>
                {
                    var returnValue = method.Invoke(rpcService, args);
                    if (returnValue is Task t)
                    {
                        await t.ConfigureAwait(false);
                        if (t.GetType().IsGenericType)
                        {
                            var resultProperty = t.GetType().GetProperty("Result");
                            Debug.Assert(resultProperty != null);
                            returnValue = resultProperty.GetValue(t);
                        }
                    }

                    return(returnValue);
                }, cts.Token);

                if (!string.IsNullOrEmpty(id))
                {
                    if (!_waitingCalls.TryAdd(id, new CancellableTask(task, cts)))
                    {
                        throw new InvalidOperationException();
                    }
                }
                else
                {
                    _noIdCalls.TryAdd(cts, task);
                }

                var result = await task.ConfigureAwait(false);

                responseBuilder.WithUserProperty("Success", true.ToString());

                if (!noResponse)
                {
                    responseBuilder.WithUserProperty("Id", id)
                    .WithPayload(DefaultSerializer.Serialize(result));
                }
            }
            catch (Exception ex)
            {
                responseBuilder.WithUserProperty("Success", false.ToString())
                .WithUserProperty("ErrorCode", ex.HResult.ToString())
                .WithUserProperty("ErrorMessage", ex.Message);
            }
            finally
            {
                if (!string.IsNullOrEmpty(id))
                {
                    _waitingCalls.TryRemove(id, out _);
                }
                else
                {
                    _noIdCalls.TryRemove(cts, out _);
                }

                if (!noResponse)
                {
                    await _mqttClient.PublishAsync(responseBuilder.Build()).ConfigureAwait(false);
                }
            }
        }