Search code examples
androidsignalrazure-mobile-servicessignalr-hubsignalr.client

Setting up Signal R in Android: Crash/Hung Issue


I followed THIS tutorial to set up a .NET Backend for my Android app to implement Signal R. I set up a SignalR Self-Hosted backend.

Here's my Backend Code in a Console Project:

namespace SignalRSelfHost
{
    class Program
    {
        static void Main(string[] args)
        {
            // This will *ONLY* bind to localhost, if you want to bind to all addresses
            // use http://*:8080 to bind to all addresses. 
            // See http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx 
            // for more information.
            string url = "http://localhost:8080";
            using (WebApp.Start(url))
            {
                Console.WriteLine("Server running on {0}", url);
                Console.ReadLine();
            }
        }
    }
    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();
        }
    }
    public class MessageHub : Hub
    {
        public static event Action<string, string> MessageReceived = delegate { };

        public void SendMessage(string name, string message)
        {
            MessageReceived(name, message);
        }

    }

    public class CustomType
    {
        public string Name;
        public int Id;
    }
}

My Android Code:

    Handler handler;
    TextView statusField;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        handler = new Handler();
        statusField = (TextView) findViewById(R.id.statusField);

        Platform.loadPlatformComponent(new AndroidPlatformComponent());
        // Change to the IP address and matching port of your SignalR server.
        String host = "http://192.168.1.5:8080/";
        HubConnection connection = new HubConnection( host );
        HubProxy hub = connection.createHubProxy( "MessageHub" );
        ClientTransport transport = new ServerSentEventsTransport(connection.getLogger());

        SignalRFuture<Void> awaitConnection = connection.start(transport);
        try {
            awaitConnection.get();
        }
        catch (InterruptedException e) {
            Log.d("CHECK", e.toString());
            e.printStackTrace();
        } catch (ExecutionException e) {
            Log.d("CHECK", e.toString());
            e.printStackTrace();
        }

        hub.subscribe(this);

        try {
            hub.invoke( "SendMessage", "Client", "Hello world!" ).get();
            hub.invoke( "SendCustomType",
                    new CustomType() {{ Name = "Universe"; Id = 42; }} ).get();
        } catch (InterruptedException e) {
            // Handle ...
        } catch (ExecutionException e) {
            // Handle ...
        }

    }

    public void UpdateStatus(String status) {
        final String fStatus = status;
        handler.post(new Runnable() {
            @Override
            public void run() {
                statusField.setText(fStatus);
            }
        });
    }

    public class CustomType
    {
        public String Name;
        public int Id;
    }

However, I end up with a screen that hangs and it displays nothing and the app stops responding. The android logger displays the following error:

java.util.concurrent.ExecutionException: java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 80) after 15000ms: isConnected failed: ECONNREFUSED (Connection refused)

Is my code correct and have I followed the guide properly? It's a very straight forward guide but this issue comes up. Can someone help out?

EDIT:

This is a very similar Question, in fact it describes the same issue. However it didn't do me any good. If you notice my android code, I've already made those changes proposed in that question. Still didn't rectify the issue.

Stacktrace

 java.util.concurrent.ExecutionException: java.net.SocketTimeoutException: failed to connect to / 192.168.1.5(port 8080) after 15000ms
 at microsoft.aspnet.signalr.client.SignalRFuture.get(SignalRFuture.java: 112)
 at microsoft.aspnet.signalr.client.SignalRFuture.get(SignalRFuture.java: 102)
 at com.example.dinuka.signalrtest.Main2Activity.onCreate(Main2Activity.java: 40)
 at android.app.Activity.performCreate(Activity.java: 6289)
 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java: 1119)
 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 2655)
 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 2767)
 at android.app.ActivityThread.access$900(ActivityThread.java: 177)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java: 1449)
 at android.os.Handler.dispatchMessage(Handler.java: 102)
 at android.os.Looper.loop(Looper.java: 145)
 at android.app.ActivityThread.main(ActivityThread.java: 5951)
 at java.lang.reflect.Method.invoke(Native Method)
 at java.lang.reflect.Method.invoke(Method.java: 372)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java: 1400)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 1195)
 Caused by: java.net.SocketTimeoutException: failed to connect to / 192.168.1.5(port 8080) after 15000ms
 at libcore.io.IoBridge.connectErrno(IoBridge.java: 169)
 at libcore.io.IoBridge.connect(IoBridge.java: 122)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java: 183)
 at java.net.PlainSocketImpl.connect(PlainSocketImpl.java: 456)
 at java.net.Socket.connect(Socket.java: 882)
 at com.android.okhttp.internal.Platform.connectSocket(Platform.java: 139)
 at com.android.okhttp.Connection.connect(Connection.java: 1194)
 at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java: 392)
 at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java: 295)
 at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java: 373)
 at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java: 323)
 at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java: 491)
 at microsoft.aspnet.signalr.client.http.java.NetworkRunnable.run(NetworkRunnable.java: 72)
 at java.lang.Thread.run(Thread.java: 818)

Solution

  • I had similar issue a few days ago and this Github issue helped: https://github.com/SignalR/java-client/issues/63

    Basically what I did was modify the WebsocketTransport.java in the signalr-client-sdk project. Replace:

    uri = new URI(url);
    

    with

    uri = new URI(url.replace("http://", "ws://"));
    

    around line 86 in the source code.

    I can now connect and send message and recieve raw data but cannot subscribe to events...

    Hope this helps you get passed your problem.