Beispiel #1
0
        private void PendingConnectionDone(PendingConnection conn, Task <XmlRpcCallResult> callTask)
        {
            lock (pendingConnections)
            {
                pendingConnections.Remove(conn);
            }

            using (logger.BeginScope(nameof(PendingConnectionDone)))
            {
                if (callTask.IsFaulted)
                {
                    logger.LogWarning($"Negotiating for {Name} has failed (Error: {callTask.Exception.Message}).");
                    return;
                }

                if (!callTask.Result.Success)
                {
                    logger.LogWarning($"Negotiating for {Name} has failed. XML-RCP call failed.");
                    return;
                }

                var resultValue = callTask.Result.Value;

                lock (gate)
                {
                    if (IsDisposed)
                    {
                        return;
                    }
                }

                var proto = new XmlRpcValue();
                if (!XmlRpcManager.Instance.ValidateXmlRpcResponse("requestTopic", resultValue, proto))
                {
                    logger.LogWarning($"Negotiating for {Name} has failed.");
                    return;
                }

                string peerHost  = conn.Client.Host;
                int    peerPort  = conn.Client.Port;
                string xmlrpcUri = "http://" + peerHost + ":" + peerPort + "/";
                if (proto.Count == 0)
                {
                    logger.LogDebug(
                        $"Could not agree on any common protocols with [{xmlrpcUri}] for topic [{Name}]"
                        );
                    return;
                }
                if (proto.Type != XmlRpcType.Array)
                {
                    logger.LogWarning($"Available protocol info returned from {xmlrpcUri} is not a list.");
                    return;
                }

                string protoName = proto[0].GetString();
                if (protoName == "UDPROS")
                {
                    logger.LogError("UDP is currently not supported. Use TCPROS instead.");
                }
                else if (protoName == "TCPROS")
                {
                    if (proto.Count != 3 || proto[1].Type != XmlRpcType.String || proto[2].Type != XmlRpcType.Int)
                    {
                        logger.LogWarning("TcpRos Publisher should implement string, int as parameter");
                        return;
                    }

                    string pubHost = proto[1].GetString();
                    int    pubPort = proto[2].GetInt();
                    logger.LogDebug($"Connecting via tcpros to topic [{Name}] at host [{pubHost}:{pubPort}]");

                    try
                    {
                        var pubLink = new TransportPublisherLink(this, xmlrpcUri);
                        lock (gate)
                        {
                            pubLink.Initialize(pubHost, pubPort);
                            AddPublisherLink(pubLink);
                        }

                        logger.LogDebug($"Connected to publisher of topic [{Name}] at  [{pubHost}:{pubPort}]");
                    }
                    catch
                    {
                        logger.LogError($"Failed to connect to publisher of topic [{Name}] at [{pubHost}:{pubPort}]");
                    }
                }
                else
                {
                    logger.LogError("The XmlRpc Server does not provide a supported protocol.");
                }
            }
        }
Beispiel #2
0
        private void PendingConnectionDone(PendingConnection conn, Task <XmlRpcCallResult> callTask)
        {
            lock ( pendingConnections )
            {
                pendingConnections.Remove(conn);
            }

            if (callTask.IsFaulted)
            {
                List <string> errorMessages = new List <string>();

                foreach (Exception exception in callTask.Exception.InnerExceptions)
                {
                    errorMessages.Add(BuildExceptionMessages(exception));
                }

                ROS.Warn()($"[{ThisNode.Name}] Negotiating for {name} has failed (Error: {string.Join( ", ", errorMessages.ToArray() )}).");
                return;
            }

            if (!callTask.Result.Success)
            {
                ROS.Warn()($"[{ThisNode.Name}] Negotiating for {name} has failed. XML-RPC call failed.");
                return;
            }

            var resultValue = callTask.Result.Value;

            lock ( shutdown_mutex )
            {
                if (shutting_down || _dropped)
                {
                    return;
                }
            }

            var proto = new XmlRpcValue();

            if (!XmlRpcManager.Instance.ValidateXmlRpcResponse("requestTopic", resultValue, proto))
            {
                ROS.Warn()($"[{ThisNode.Name}] Negotiating for {name} has failed.");
                return;
            }

            string peerHost  = conn.Client.Host;
            int    peerPort  = conn.Client.Port;
            string xmlrpcUri = $"http://{peerHost}:{peerPort}/";

            if (proto.Count == 0)
            {
                ROS.Debug()($"[{ThisNode.Name}] Could not agree on any common protocols with [{xmlrpcUri}] for topic [{name}]");
                return;
            }
            if (proto.Type != XmlRpcType.Array)
            {
                ROS.Warn()($"[{ThisNode.Name}] Available protocol info returned from {xmlrpcUri} is not a list.");
                return;
            }

            string protoName = proto[0].GetString();

            if (protoName == "UDPROS")
            {
                ROS.Error()($"[{ThisNode.Name}] UDP is currently not supported. Use TCPROS instead.");
            }
            else if (protoName == "TCPROS")
            {
                if (proto.Count != 3 || proto[1].Type != XmlRpcType.String || proto[2].Type != XmlRpcType.Int)
                {
                    ROS.Warn()($"[{ThisNode.Name}] TcpRos Publisher should implement string, int as parameter");
                    return;
                }

                string pubHost = proto[1].GetString();
                int    pubPort = proto[2].GetInt();
                ROS.Debug()($"[{ThisNode.Name}] Connecting via tcpros to topic [{name}] at host [{pubHost}:{pubPort}]");

                var transport = new TcpTransport(PollManager.Instance.poll_set)
                {
                    _topic = name
                };
                if (transport.connect(pubHost, pubPort))
                {
                    var connection = new Connection();
                    var pubLink    = new TransportPublisherLink(this, xmlrpcUri);

                    connection.initialize(transport, false, null);
                    pubLink.initialize(connection);

                    ConnectionManager.Instance.AddConnection(connection);

                    lock ( publisher_links_mutex )
                    {
                        addPublisherLink(pubLink);
                    }

                    ROS.Debug()($"[{ThisNode.Name}] Connected to publisher of topic [{name}] at  [{pubHost}:{pubPort}]");
                }
                else
                {
                    ROS.Error()($"[{ThisNode.Name}] Failed to connect to publisher of topic [{name}] at [{pubHost}:{pubPort}]");
                }
            }
            else
            {
                ROS.Error()($"[{ThisNode.Name}] The XmlRpc Server does not provide a supported protocol.");
            }
        }