Skip to content

Websocket crashing when not finding IP #490

@tbobik-meta

Description

@tbobik-meta
  • [X ] I am at the right place and my issue is directly related to ROS#. General technical questions I would post e.g. at ROS Answers or Stack Overflow. For library-specific questions I would look for help in the corresponding library forums.
  • [ X] I have thoroughly read the Contributing Guideline and writing this issue is the right thing to do in my case.

  • [X ] I am using the latest ROS# version available here on the master branch.

  • [X ] I am adding all required information, code and data files, screenshots and log files so that you can reproduce the problem.

  • My OS is: Ubuntu

  • My Unity Version is: N/A

  • My ROS Distribution is: Humble

  • My Build Target Platform is: Linux

Here is my bug description:
I am attempting to start an application where the robot might not be connected to the network. When I try to initialize the Websocket, I can't catch the error it throws when attempting to connect and failing. The app always crashes, and in some cases without error.

This seems to be similar to the bug reported in issue #208 and in theory was said to be fixed, but looking at the protocol file, it seems like the fix was reverted because it was causing warnings in Unity.

Perform the following steps reproduce the bug:

  1. Disconnect the robot from the network
  2. Start the given program

Observed results:
The program will crash, and the error was not caught.

Expected results:
The error getting caught, or having the ability to deal with the error.

Relevant Code:
Here is a simple reproduction using a basic dotnet app

using System;
using System.Threading;
using RosSharp.RosBridgeClient;
using RosSharp.RosBridgeClient.Protocols;

namespace RosSharpConsole
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting ROS Sharp WebSocket test...");

            string uri = "ws://192.168.3.3:9090"; // Random IP that I know isn't on the network
            Console.WriteLine($"Attempting to connect to: {uri}");

            try
            {
                var wsProtocol = new WebSocketNetProtocol(uri);
                wsProtocol.Connect();

                Console.WriteLine("WebSocket object created successfully using RosSharp implementation");

                Thread.Sleep(10000);
                Console.WriteLine("Closing WebSocket");
                wsProtocol.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error creating or using WebSocket");
            }

            Console.WriteLine("ROS Sharp WebSocket test completed.");
        }
    }
}

Here is the stack trace I get:

Unhandled exception. System.Net.WebSockets.WebSocketException (0x80004005): Unable to connect to the remote server
 ---> System.Net.Http.HttpRequestException: Host is down (192.168.3.3:9090)
 ---> System.Net.Sockets.SocketException (64): Host is down
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.CreateException(SocketError error, Boolean forAsyncThrow)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ConnectAsync(Socket socket)
   at System.Net.Sockets.Socket.ConnectAsync(EndPoint remoteEP, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object s)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread threadPoolThread)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecuteFromThreadPool(Thread threadPoolThread)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
   at System.Threading.Thread.StartCallback()
--- End of stack trace from previous location ---
   at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.WebSocketHandle.ConnectAsync(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken, ClientWebSocketOptions options)
   at System.Net.WebSockets.ClientWebSocket.ConnectAsyncCore(Uri uri, HttpMessageInvoker invoker, CancellationToken cancellationToken)
   at RosSharp.RosBridgeClient.Protocols.WebSocketNetProtocol.ConnectAsync()
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
   at System.Threading.Thread.StartCallback()

Currently, I've solved this by pinging the IP of the robot, and only connecting when I get a successful ping, but that feels a bit clunky.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions