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."); } } }
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."); } }