Ejemplo n.º 1
0
        /// <summary>
        /// Queries <see cref="AppProtocolVersion"/> of given <see cref="BoundPeer"/>.
        /// </summary>
        /// <param name="peer">The <see cref="BoundPeer"/> to query
        /// <see cref="AppProtocolVersion"/>.</param>
        /// <param name="timeout">Timeout value for request.</param>
        /// <returns><see cref="AppProtocolVersion"/> of given peer. </returns>
        public static AppProtocolVersion QueryAppProtocolVersion(
            this BoundPeer peer,
            TimeSpan?timeout = null
            )
        {
            using var dealerSocket = new DealerSocket(ToNetMQAddress(peer));
            var          key  = new PrivateKey();
            var          ping = new Ping();
            var          netMQMessageCodec = new NetMQMessageCodec();
            NetMQMessage request           = netMQMessageCodec.Encode(
                ping,
                key,
                new Peer(key.PublicKey),
                DateTimeOffset.UtcNow,
                default
                );

            TimeSpan timeoutNotNull = timeout ?? TimeSpan.FromSeconds(5);

            if (dealerSocket.TrySendMultipartMessage(timeoutNotNull, request))
            {
                var response = new NetMQMessage();
                if (dealerSocket.TryReceiveMultipartMessage(timeoutNotNull, ref response))
                {
                    return(AppProtocolVersion.FromToken(response.First.ConvertToString()));
                }
            }

            throw new TimeoutException(
                      $"Peer[{peer}] didn't respond within the specified time[{timeout}]."
                      );
        }
Ejemplo n.º 2
0
            private async Task Handler()
            {
                while (this.IsRunning)
                {
                    try
                    {
                        using (var socket = new DealerSocket())
                            using (this.BackendBuffer = new NetMQQueue <TransportMessage>())
                                using (var poller = new NetMQPoller()
                                {
                                    socket, this.BackendBuffer
                                })
                                    using (var monitor = new NetMQ.Monitoring.NetMQMonitor(socket, $"inproc://monitor.forwarderdevice.backend.{Guid.NewGuid().ToString()}", SocketEvents.Connected | SocketEvents.Disconnected))
                                    {
                                        socket.Options.Identity = System.Text.Encoding.ASCII.GetBytes(Guid.NewGuid().ToString().Replace("-", "").ToLowerInvariant());

                                        socket.ReceiveReady += (sender, e) =>
                                        {
                                            try
                                            {
                                                var netmqMessage = new NetMQMessage();
                                                if (e.Socket.TryReceiveMultipartMessage(ref netmqMessage))
                                                {
                                                    var message = netmqMessage.ToMessage();

                                                    this.ForwarderDevice.OnBackendReceived(message);

                                                    this.ForwarderDevice.frontendBuffer.Enqueue(message);
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace);
                                            }
                                        };

                                        this.BackendBuffer.ReceiveReady += (sender, e) =>
                                        {
                                            try
                                            {
                                                while (this.BackendBuffer.TryDequeue(out TransportMessage message, TimeSpan.Zero))
                                                {
                                                    this.ForwarderDevice.OnFrontendForwarded(message);

                                                    this.ForwarderDevice.OnDiagnosticMessage("Forwarding message to " + this.Endpoint.ToConnectionString());
                                                    if (!socket.TrySendMultipartMessage(TimeSpan.FromSeconds(1), message.ToNetMQMessage()))
                                                    {
                                                        this.ForwarderDevice.OnDiagnosticMessage("Failed to send message");
                                                    }
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace);
                                            }
                                        };

                                        monitor.Connected += (sender, e) =>
                                        {
                                            this.ForwarderDevice.OnDiagnosticMessage($"Dealer socket conntected to {this.Endpoint.ToConnectionString()}");
                                            this.IsConnected = true;
                                        };
                                        monitor.Disconnected += (sender, e) =>
                                        {
                                            this.ForwarderDevice.OnDiagnosticMessage($"Dealer socket disconntected from {this.Endpoint.ToConnectionString()}");
                                            this.IsConnected = false;
                                        };

                                        this.ForwarderDevice.OnDiagnosticMessage($"Attempting to connect to {this.Endpoint.ToConnectionString()}");
                                        monitor.StartAsync();
                                        monitor.AttachToPoller(poller);

                                        var pollerTask = new Task(poller.Run);
                                        pollerTask.ContinueWith((Task task) =>
                                        {
                                            var ex = task.Exception;

                                            this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace);
                                            this.IsConnected = false;
                                        }, TaskContinuationOptions.OnlyOnFaulted);
                                        pollerTask.Start();

                                        socket.Connect(this.Endpoint.ToConnectionString());

                                        var start = DateTime.Now;
                                        while (!this.IsConnected)
                                        {
                                            if ((DateTime.Now - start).TotalMilliseconds > 5000)
                                            {
                                                throw new Exception($"Connection timeout [{this.ServiceName}]");
                                            }

                                            await Task.Delay(1000);
                                        }

                                        while (this.IsConnected && this.IsRunning)
                                        {
                                            await Task.Delay(1000);
                                        }

                                        this.ForwarderDevice.OnDiagnosticMessage("Closing dealer socket...");
                                        poller.StopAsync();
                                        socket.Disconnect(this.Endpoint.ToConnectionString());
                                        monitor.DetachFromPoller();
                                        monitor.Stop();

                                        this.IsConnected = false;
                                    }

                        if (this.IsRunning)
                        {
                            await Task.Delay(1000);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.ForwarderDevice.OnDiagnosticMessage(ex.Message + ": " + ex.StackTrace);
                    }
                }
            }
Ejemplo n.º 3
0
        public async Task <bool> RunSimulationAsync(Options options, TextWriter logger, CancellationToken token = default)
        {
            Logger = logger;
            try {
                Id = options.Id;

                _socket = new DealerSocket();
                _socket.Options.Linger   = TimeSpan.FromSeconds(30);
                _socket.Options.Identity = Encoding.ASCII.GetBytes(Id);
                if (options.Connect)
                {
                    _socket.Connect(options.URL);
                }
                else
                {
                    _socket.Bind(options.URL);
                }

                using (Outgoing = new NetMQQueue <NetMQMessage>()) {
                    using var poller = new NetMQPoller()
                          {
                              _socket, Outgoing
                          };
                    _socket.ReceiveReady += (sender, e) => {
                        var msg = _socket.ReceiveMultipartMessage();
                        if (msg.FrameCount < 3)
                        {
                            logger.WriteLine($"Received message with only {msg.FrameCount} frames.");
                            return;
                        }
                        var type = msg[1].ConvertToString();
                        logger.WriteLine($"Received {type} message.");
                        switch (type)
                        {
                        case "crane":
                            OnCraneMessageReceived(msg[2].Buffer);
                            break;

                        case "sim":
                            OnSimMessageReceived(msg[2].Buffer);
                            break;

                        default: //Console.WriteLine($"Received message with unmapped type {type}");
                            break;
                        }
                    };
                    Outgoing.ReceiveReady += (sender, e) => {
                        var msg = Outgoing.Dequeue();
                        if (_socket.TrySendMultipartMessage(TimeSpan.FromMinutes(1), msg)) // Note that for policyruns (virtual time) a lot of events are generated
                        {
                            logger.WriteLine($"Sent {msg[1].ConvertToString()} message.");
                        }
                        //else logger.WriteLine($"Discarded outgoing {msg[1].ConvertToString()} message.");
                    };

                    if (!options.RunSync || options.Connect)
                    {
                        poller.RunAsync();
                    }

                    if (!string.IsNullOrEmpty(options.SettingsPath))
                    {
                        if (options.SettingsPath.Equals("Default", StringComparison.OrdinalIgnoreCase))
                        {
                            logger.WriteLine("Using default settings");
                            _settingsReceived.SetResult(GetDefaultSettings());
                        }
                        else
                        {
                            logger.WriteLine($"Reading settings from {options.SettingsPath}");
                            _settingsReceived.SetResult(File.ReadAllBytes(options.SettingsPath));
                        }
                    }
                    var result = false;
                    try {
                        if (!options.RunSync)
                        {
                            result = await RunSimulationAsync(await _settingsReceived.Task, options.PolicyRun);

                            // wait until the outgoing queue is cleared
                            var remaining = Outgoing.Count;
                            while (remaining > 0)
                            {
                                await Task.Delay(1000, token);

                                if (Outgoing.Count == remaining)
                                {
                                    break;              // assume nobody is listening for world states
                                }
                                remaining = Outgoing.Count;
                            }
                        }
                        else
                        {
                            result = RunSimulation(await _settingsReceived.Task, options.SyncURL, options.Id);
                        }
                    } finally {
                        poller.Stop();
                    }
                    return(result);
                }
            } finally {
                DisposeSocket();
            }
        }