Exemplo n.º 1
0
        /// <summary>
        /// 发送消息。
        /// </summary>
        /// <param name="message">远程调用消息模型。</param>
        /// <returns>远程调用消息的传输消息。</returns>
        public async Task <TransportMessage> SendAsync(RemoteInvokeMessage message)
        {
            try
            {
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.Debug("准备发送消息。");
                }

                var transportMessage = TransportMessage.CreateInvokeMessage(message);

                await _messageSender.SendAndFlushAsync(transportMessage);

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.Debug("消息发送成功。");
                }

                return(transportMessage);
            }
            catch (Exception exception)
            {
                if (_logger.IsEnabled(LogLevel.Fatal))
                {
                    _logger.Fatal("消息发送失败。", exception);
                }
                throw;
            }
        }
Exemplo n.º 2
0
        public async Task <RemoteInvokeResultMessage> SendAsync(CancellationToken cancellationToken)
        {
            try
            {
                var def              = new Dictionary <string, object>();
                var command          = _app.Model;
                var transportMessage = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage
                {
                    DecodeJOject = true,
                    Parameters   = string.IsNullOrEmpty(command.Data) ? def : JsonConvert.DeserializeObject <IDictionary <string, object> >(command.Data),
                    ServiceId    = command.ServiceId,
                    ServiceKey   = command.ServiceKey,
                    Attachments  = string.IsNullOrEmpty(command.Attachments) ? def : JsonConvert.DeserializeObject <IDictionary <string, object> >(command.Attachments)
                });

                var callbackTask = RegisterResultCallbackAsync(transportMessage.Id);

                try
                {
                    await _messageSender.SendAndFlushAsync(transportMessage);
                }
                catch (Exception exception)
                {
                    throw;
                }

                return(await callbackTask);
            }
            catch
            {
                throw;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message">远程调用消息模型</param>
        /// <returns>远程调用消息的传输消息</returns>
        public async Task <RemoteInvokeResultMessage> SendAsync(RemoteInvokeMessage message)
        {
            try
            {
                _logger.LogInformation("准备发送消息。");

                var transportMessage = TransportMessage.CreateInvokeMessage(message);

                //注册结果回调
                var callbackTask = RegisterResultCallbackAsync(transportMessage.Id);

                try
                {
                    //发送
                    await _messageSender.SendAndFlushAsync(transportMessage);
                }
                catch (Exception exception)
                {
                    throw new RpcCommunicationException("与服务端通讯时发生了异常", exception);
                }


                _logger.LogInformation("消息发送成功。");

                return(await callbackTask);
            }
            catch (Exception exception)
            {
                if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError("消息发送失败。", exception);
                }
                throw;
            }
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message">远程调用消息模型</param>
        /// <returns>远程调用消息的传输消息</returns>
        public async Task <RemoteInvokeResultMessage> SendAsync(RemoteInvokeMessage message)
        {
            try
            {
                _logger.LogInformation("");
                Console.WriteLine("准备发送消息");

                var transportMessage = TransportMessage.CreateInvokeMessage(message);

                //注册结果回调
                var callbackTask = RegisterResultCallbackAsync(transportMessage.Id);

                try
                {
                    //发送
                    await _messageSender.SendAndFlushAsync(transportMessage);
                }
                catch (Exception exception)
                {
                    throw new RpcCommunicationException("与服务端通讯时发生了异常", exception);
                }

                Console.WriteLine("消息发送成功");

                return(await callbackTask);
            }
            catch (Exception exception)
            {
                Console.WriteLine("消息发送失败" + exception);
                throw;
            }
        }
Exemplo n.º 5
0
        public async Task <RemoteInvokeResultMessage> InvokeAsync(RemoteInvokeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (context.ServiceId == null)
            {
                throw new ArgumentNullException("serviceId");
            }

            RemoteInvokeMessage message = new RemoteInvokeMessage()
            {
                ServiceId  = context.ServiceId,
                Parameters = context.Parameters
            };
            var transportMessage = TransportMessage.CreateInvokeMessage(message);


            var retryPolicy = Policy.Handle <RpcConnectedException>()
                              .Or <RpcRemoteException>()
                              .WaitAndRetryAsync(5, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt))
                                                 , async(ex, time, i, ctx) =>
            {
                var address = ctx["address"] as AddressModel;
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"第{i}次重试,重试时间间隔{time.Seconds},发生时间:{DateTime.Now},地址:{address.ToString()}");
                }
                await _healthCheckService.MarkFailure(address);
            });


            #region MyRegion
            //var fallBackPolicy = Policy<TransportMessage>.Handle<Exception>().Fallback(new TransportMessage());
            //var mixPolicy = Policy.Wrap(fallBackPolicy, retryPolicy);
            //var breakerPolicy=Policy.Handle<RpcConnectedException>()
            //                    .CircuitBreakerAsync(5,TimeSpan.FromSeconds(10),)
            #endregion

            try
            {
                var policyContext = new Context();
                return(await retryPolicy.ExecuteAsync <RemoteInvokeResultMessage>(ctx =>
                {
                    return RetryExectueAsync(ctx, _addressResolver, context.ServiceId, transportMessage);
                }, policyContext));
            }
            catch (Exception e)
            {
                //await _healthCheckService.MarkFailure(address);
                _logger.LogError("发送远程消息错误", e);
                throw e;
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Disconnects the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="packet">The packet.</param>
        public async Task Disconnect(IChannelHandlerContext context, DisconnectPacket packet)
        {
            var deviceId = await _channelService.GetDeviceId(context.Channel);

            var message = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage
            {
                ServiceId = "Disconnect", Parameters = new Dictionary <string, object> {
                    { "packet", packet }
                }
            });

            WirteDiagnosticBefore(message, context.Channel.RemoteAddress.ToString(), deviceId, packet.PacketType);
            await _channelService.Close(deviceId, true);

            WirteDiagnosticAfter(message);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Unsubscribes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="packet">The packet.</param>
        public async Task Unsubscribe(IChannelHandlerContext context, UnsubscribePacket packet)
        {
            var topics   = packet.TopicFilters.ToArray();
            var deviceId = await _channelService.GetDeviceId(context.Channel);

            var message = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage
            {
                ServiceId = "Unsubscribe", Parameters = new Dictionary <string, object> {
                    { "packet", packet }
                }
            });

            WirteDiagnosticBefore(message, context.Channel.RemoteAddress.ToString(), deviceId, packet.PacketType);
            await _channelService.UnSubscribe(deviceId, topics);

            await UnsubAck(context, UnsubAckPacket.InResponseTo(packet));

            WirteDiagnosticAfter(message);
        }
Exemplo n.º 8
0
        public async Task <RemoteInvokeResultMessage> SendAsync(RemoteInvokeMessage message,
                                                                CancellationToken cancellationToken)
        {
            try
            {
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug("准备发送消息。");
                }

                var transportMessage = TransportMessage.CreateInvokeMessage(message);
                WirteDiagnosticBefore(transportMessage);
                // 注册结果回调
                var callbackTask = RegisterResultCallbackAsync(transportMessage.Id, cancellationToken);

                try
                {
                    // 发送
                    await _messageSender.SendAndFlushAsync(transportMessage);
                }
                catch (Exception exception)
                {
                    throw new CommunicationException("与服务端通讯时发生了异常。", exception);
                }

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug("消息发送成功。");
                }

                return(await callbackTask);
            }
            catch (Exception exception)
            {
                if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError(exception, "消息发送失败。");
                }

                throw;
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Subscribes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="packet">The packet.</param>
        public async Task Subscribe(IChannelHandlerContext context, SubscribePacket packet)
        {
            if (packet != null)
            {
                var deviceId = await _channelService.GetDeviceId(context.Channel);

                var topics  = packet.Requests.Select(p => p.TopicFilter).ToArray();
                var message = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage
                {
                    ServiceId = "Subscribe", Parameters = new Dictionary <string, object> {
                        { "packet", packet }
                    }
                });
                WirteDiagnosticBefore(message, context.Channel.RemoteAddress.ToString(), deviceId, packet.PacketType);
                await _channelService.Suscribe(deviceId, topics);
                await SubAck(context, SubAckPacket.InResponseTo(packet, QualityOfService.ExactlyOnce));

                WirteDiagnosticAfter(message);
            }
        }
        public async Task <RemoteInvokeResultMessage> InvokeAsync(RemoteInvokeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (context.ServiceId == null)
            {
                throw new ArgumentNullException("serviceId");
            }

            RemoteInvokeMessage message = new RemoteInvokeMessage()
            {
                ServiceId  = context.ServiceId,
                Parameters = context.Parameters
            };
            var transportMessage = TransportMessage.CreateInvokeMessage(message);

            //todo: 添加断路器(polly)

            var address = await _addressResolver.ResolverAsync(context.ServiceId);

            var client = _clientFactory.CreateClientAsync(address.CreateEndPoint());

            try
            {
                return(await client.SendAsync(transportMessage));
            }
            catch (Exception e)
            {
                await _healthCheckService.MarkFailure(address);

                _logger.LogError("发送远程消息错误", e);
                throw e;
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Logins the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="packet">The packet.</param>
        public async Task Login(IChannelHandlerContext context, ConnectPacket packet)
        {
            var deviceId = packet.ClientId;
            var message  = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage
            {
                ServiceId = "Connect", Parameters = new Dictionary <string, object> {
                    { "packet", packet }
                }
            });

            WirteDiagnosticBefore(message, context.Channel.RemoteAddress.ToString(), deviceId, packet.PacketType);
            if (string.IsNullOrEmpty(deviceId))
            {
                await ConnAck(context, new ConnAckPacket
                {
                    ReturnCode = ConnectReturnCode.RefusedIdentifierRejected
                });

                return;
            }

            var mqttBehavior = _mqttBehaviorProvider.GetMqttBehavior();

            if (mqttBehavior != null)
            {
                if (packet.HasPassword && packet.HasUsername &&
                    await mqttBehavior.Authorized(packet.Username, packet.Password))
                {
                    var mqttChannel = _channelService.GetMqttChannel(deviceId);
                    if (mqttChannel == null || !await mqttChannel.IsOnine())
                    {
                        byte[] bytes = null;
                        if (packet.WillMessage != null)
                        {
                            bytes = new byte[packet.WillMessage.ReadableBytes];
                            packet.WillMessage.ReadBytes(bytes);
                        }

                        await _channelService.Login(context.Channel, deviceId, new ConnectMessage
                        {
                            CleanSession       = packet.CleanSession,
                            ClientId           = packet.ClientId,
                            Duplicate          = packet.Duplicate,
                            HasPassword        = packet.HasPassword,
                            HasUsername        = packet.HasUsername,
                            HasWill            = packet.HasWill,
                            KeepAliveInSeconds = packet.KeepAliveInSeconds,
                            Password           = packet.Password,
                            ProtocolLevel      = packet.ProtocolLevel,
                            ProtocolName       = packet.ProtocolName,
                            Qos                  = (int)packet.QualityOfService,
                            RetainRequested      = packet.RetainRequested,
                            Username             = packet.Username,
                            WillMessage          = bytes,
                            WillQualityOfService = (int)packet.WillQualityOfService,
                            WillRetain           = packet.WillRetain,
                            WillTopic            = packet.WillTopicName
                        });
                    }
                }
                else
                {
                    await ConnAck(context, new ConnAckPacket
                    {
                        ReturnCode = ConnectReturnCode.RefusedBadUsernameOrPassword
                    });
                }
            }
            else
            {
                await ConnAck(context, new ConnAckPacket
                {
                    ReturnCode = ConnectReturnCode.RefusedServerUnavailable
                });
            }

            WirteDiagnosticAfter(message);
        }