예제 #1
0
        private async Task HandleConnection()
        {
            // establish connection
            using (var client = new TcpClient())
            {
                await client.ConnectAsync(host, port).ConfigureAwait(false);

                client.NoDelay = true;

                try
                {
                    this.connection = new Connection(client);

                    // write/read header handshake
                    await WriteHeader().ConfigureAwait(false);

                    var headerFields = await connection.ReadHeader(cancel).ConfigureAwait(false);

                    SetHeader(new Header(headerFields));

                    // connection established
                    this.connected = true;

                    while (!cancel.IsCancellationRequested)
                    {
                        // read message length
                        int length = await connection.ReadInt32(cancel).ConfigureAwait(false);

                        if (length > Connection.MESSAGE_SIZE_LIMIT)
                        {
                            var message = $"Message received in TransportPublisherLink exceeds length limit of {Connection.MESSAGE_SIZE_LIMIT}. Dropping connection";
                            throw new RosException(message);
                        }

                        // read message
                        var messageBuffer = await connection.ReadBlock(length, cancel).ConfigureAwait(false);

                        // deserialize message
                        RosMessage msg = RosMessage.Generate(Parent.DataType);
                        msg.Serialized        = messageBuffer;
                        msg.connection_header = this.Header.Values;
                        HandleMessage(msg);

                        // reset retry delay after first successfully processed message
                        retryDelay = BASE_RETRY_DELAY;
                    }

                    client.Close();
                }
                finally
                {
                    this.connected  = false;
                    this.connection = null;
                }
            }
        }
        public virtual MReq deserialize <MReq, MRes>(ServiceCallbackHelperParams <MReq, MRes> parms) where MReq : RosMessage where MRes : RosMessage
        {
            RosMessage msg = RosMessage.Generate(type);

            msg.connection_header = new Dictionary <string, string>(parms.connection_header);
            MReq t = (MReq)msg;

            t.Deserialize(parms.response.Serialized);
            return(t);
        }
예제 #3
0
        public bool call(RosMessage req, ref RosMessage resp)
        {
            if (resp == null)
            {
                //instantiate null response IN CASE this call succeeds
                resp = RosMessage.Generate(req.MessageType.Replace("Request", "Response"));
            }

            CallInfo info = new CallInfo {
                req = req, resp = resp, success = false, finished = false
            };

            bool immediate = false;

            lock ( call_queue_mutex )
            {
                if (connection.dropped)
                {
                    return(false);
                }

                if (call_queue.Count == 0 && header_written && header_read)
                {
                    immediate = true;
                }

                call_queue.Enqueue(info);
            }

            if (immediate)
            {
                processNextCall();
            }

            while (!info.finished)
            {
                ROS.Debug()($"[{ThisNode.Name}] info.finished_condition.WaitOne();");
                info.finished_condition.WaitOne();
            }

            if (info.success)
            {
                // response is only sent on success => don't try to deserialize on failure.
                resp.Deserialize(resp.Serialized);
            }

            if (!string.IsNullOrEmpty(info.exception))
            {
                ROS.Error()($"[{ThisNode.Name}] Service call failed: service [{name}] responded with an error: {info.exception}");
            }
            return(info.success);
        }
예제 #4
0
        public static RosService Generate(string rosServiceType)
        {
            var service = ServiceTypeRegistry.Default.CreateService(rosServiceType);

            if (service == null)
            {
                throw new ArgumentException($"Could not find a RosService class for {rosServiceType}.", nameof(rosServiceType));
            }

            service.RequestMessage  = RosMessage.Generate(service.ServiceType + "__Request");
            service.ResponseMessage = RosMessage.Generate(service.ServiceType + "__Response");

            return(service);
        }
예제 #5
0
        public async Task <(bool, RosMessage)> Call(RosMessage request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            RosMessage response = RosMessage.Generate(request.MessageType.Replace("Request", "Response"));

            if (response == null)
            {
                throw new Exception("Response message generation failed.");
            }

            var queue = callQueue;

            try
            {
                var call = new CallInfo {
                    Request = request, Response = response
                };
                await queue.OnNext(call, cancel).ConfigureAwait(false);

                bool success = await call.AsyncResult.ConfigureAwait(false);

                if (success)
                {
                    // response is only sent on success
                    response.Deserialize(response.Serialized);
                }

                return(success, response);
            }
            catch (Exception e)
            {
                string message = $"Service call failed: service [{name}] responded with an error: {e.Message}";
                ROS.Error()(message);
                return(false, null);
            }
            finally
            {
                if (!persistent)
                {
                    queue.OnCompleted();
                }
            }
        }
예제 #6
0
        public async Task <Subscriber> SubscribeAsync(string topic, string messageType, int queueSize, CallbackInterface cb, bool allowConcurrentCallbacks = false)
        {
            if (callbackQueue == null)
            {
                callbackQueue = ROS.GlobalCallbackQueue;
            }

            var message = RosMessage.Generate(messageType);
            var ops     = new SubscribeOptions(topic, message.MessageType, message.MD5Sum(), queueSize, new SubscriptionCallbackHelper <RosMessage>(message.MessageType, cb.SendEvent))
            {
                callback_queue             = callbackQueue,
                allow_concurrent_callbacks = allowConcurrentCallbacks
            };

            ops.callback_queue.AddCallback(cb);
            return(await SubscribeAsync(ops));
        }
예제 #7
0
        private bool onMessage(Connection conn, byte[] buffer, int size, bool success)
        {
            if (!success || conn == null || conn != connection)
            {
                return(false);
            }

            if (success)
            {
                RosMessage msg = RosMessage.Generate(parent.msgtype);
                msg.Serialized        = buffer;
                msg.connection_header = getHeader().Values;
                handleMessage(msg, true, false);
            }
            if (success || !connection.transport.getRequiresHeader())
            {
                connection.read(4, onMessageLength);
            }
            return(true);
        }