public async Task SendMessage(VehiclePositionEvent message)
        {
            var messageJson = JsonConvert.SerializeObject(message);

            var pubsubMessage = new PubsubMessage()
            {
                Data = ByteString.CopyFromUtf8(messageJson)
            };

            await _client.PublishAsync(pubsubMessage);
        }
        public async Task SendVPMessage(VehiclePositionEvent message)
        {
            var messageJson = JsonConvert.SerializeObject(message);

            using EventDataBatch eventBatch = await _positioningClient.CreateBatchAsync();

            eventBatch.TryAdd(new EventData(Encoding.UTF8.GetBytes(messageJson)));

            Console.WriteLine($"Sending VP message {messageJson}");

            await _positioningClient.SendAsync(eventBatch);
        }
        public async void InitializeConnection(StreamConnectionSettings settings,
                                               Func <VehicleArriveEvent, Task> arsMessageReceivedCallback, Func <VehiclePositionEvent, Task> vpMessageReceivedCallback)
        {
            var options = new MqttClientOptionsBuilder()
                          .WithWebSocketServer(settings.ServerAddress)
                          .WithTls()
                          .Build();

            _client.UseConnectedHandler(async e =>
            {
                Console.WriteLine("### CONNECTED WITH SERVER ###");
                await _client.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(settings.ChannelName).Build());
                Console.WriteLine("### SUBSCRIBED ###");
            });

            _client.UseApplicationMessageReceivedHandler(async eventArgs =>
            {
                var stringMessage = System.Text.Encoding.UTF8.GetString(eventArgs.ApplicationMessage.Payload);
                var vpEvent       = JsonConvert.DeserializeObject <VPEvent>(stringMessage);
                if (vpEvent.Event != null)
                {
                    Console.WriteLine($"VP event received: {eventArgs.ApplicationMessage.Topic}");
                    var message = new VehiclePositionEvent(vpEvent.Event);
                    await vpMessageReceivedCallback(message);
                    return;
                }
                var arsEvent = JsonConvert.DeserializeObject <ARSEvent>(stringMessage);
                if (arsEvent.Event != null)
                {
                    Console.WriteLine($"ARS event received: {eventArgs.ApplicationMessage.Topic}");
                    var direction = GetDirectionFromTopic(eventArgs.ApplicationMessage.Topic);
                    var nextStop  = GetNextStopFromTopic(eventArgs.ApplicationMessage.Topic);
                    var message   = new VehicleArriveEvent(arsEvent.Event, nextStop, direction);
                    await arsMessageReceivedCallback(message);
                    return;
                }
            });

            await _client.ConnectAsync(options, CancellationToken.None);
        }
        protected override async Task Work(CancellationToken cancellationToken)
        {
            if (rabbitConnectionFactory == null)
            {
                throw new InvalidOperationException("Worker not configured.");
            }

            logger.LogInformation($"Connecting to RabbitMQ: {rabbitConnectionFactory.Uri}");
            rabbitConnection = rabbitConnectionFactory.CreateConnection(nameof(RpsUdpToJsonWorker));
            rabbitChannel    = rabbitConnection.CreateModel();

            var arguments = new Dictionary <string, object>
            {
                { "x-message-ttl", 3 * 60 * 60 * 1000 } // 3 hours
            };

            rabbitChannel.ExchangeDeclare(jsonExchange, "fanout", durable: true, autoDelete: false);
            rabbitChannel.QueueDeclare(workQueue, durable: true, exclusive: false, autoDelete: false, arguments);
            rabbitChannel.QueueBind(workQueue, udpExchange, string.Empty);

            var serverCancel = new CancellationTokenSource();

            consumer           = new EventingBasicConsumer(rabbitChannel);
            consumer.Received += (model, ea) =>
            {
                if (ea.Body.IsEmpty)
                {
                    logger.LogTrace("Recived empty position message");
                    return;
                }

                var bytes = ea.Body.ToArray();

                switch (bytes[0])
                {
                case 2:
                    if (udpConverter.TryParseVehiclePosition(bytes, out var vehiclePositon))
                    {
                        if (vehicleJourneyAssignmentCache.TryGet(vehiclePositon.VehicleRef, out VehicleJourneyAssignment journeyAssignment) && journeyAssignment.InvalidFromUtc == null)
                        {
                            vehiclePositon.JourneyRef = journeyAssignment.JourneyRef;
                        }

                        var vehiclePositonEvent = new VehiclePositionEvent()
                        {
                            VehiclePosition = vehiclePositon
                        };
                        var routingKey = $"{vehiclePositonEvent.EventType}.{vehiclePositon.VehicleRef}";

                        rabbitChannel.BasicPublish(jsonExchange, routingKey, body: Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(vehiclePositonEvent)));
                        ResetWatchdog();
                    }
                    break;

                case 255:
                    /* Time Message used for SLA - Ignore. */
                    break;

                default:
                    logger.LogTrace($"Unknown message type: {bytes[0]}.");
                    break;
                }
            };

            logger.LogInformation($"Beginning to consume {workQueue}...");
            consumer.Shutdown += (model, ea) =>
            {
                serverCancel.Cancel();
            };
            rabbitChannel.BasicConsume(queue: workQueue,
                                       autoAck: true,
                                       consumer: consumer);

            await cancellationToken.WaitHandle.WaitOneAsync(serverCancel.Token);
        }
 public Task SendVPMessage(VehiclePositionEvent message)
 {
     throw new NotImplementedException();
 }