4

I am using SignalR Java Client in an Android project to connect to the server (just a console app written in C#) which runs on my localhost. The following is my code on the Android side, inside the onCreate method of the main activity. The application runs on the emulator, so I changed the localhost part of the URL to "10.0.2.2".

try {

    AndroidPlatformComponent com = new AndroidPlatformComponent();
    Platform.loadPlatformComponent(com);

    String url = "http://10.0.2.2:8080/signalr";
    HubConnection connection = new HubConnection(url);
    HubProxy hubProxy = connection.createHubProxy("MyHub");

    connection.start().get();

    hubProxy.on("Send", new SubscriptionHandler2<String, String>() {
        @Override
        public void run(String e1, String e2) {
            Log.d("Server", e1.toString() + " -> " + e2.toString());
        }
    }, String.class, String.class);


}catch (Exception ex){
    ex.printStackTrace();
}

And everytime I'm getting the following error on the line connection.start().get();:

10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: java.util.concurrent.ExecutionException: microsoft.aspnet.signalr.client.transport.NegotiationException: There was a problem in the negotiation with the server
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at microsoft.aspnet.signalr.client.SignalRFuture.get(SignalRFuture.java:112)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at microsoft.aspnet.signalr.client.SignalRFuture.get(SignalRFuture.java:102)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at com.izmyr.projectx.main.MainActivity$2.onClick(MainActivity.java:85)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at android.view.View.performClick(View.java:4084)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at android.view.View$PerformClick.run(View.java:16966)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at android.os.Handler.handleCallback(Handler.java:615)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:92)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at android.os.Looper.loop(Looper.java:137)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:4745)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at dalvik.system.NativeStart.main(Native Method)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: Caused by: microsoft.aspnet.signalr.client.transport.NegotiationException: There was a problem in the negotiation with the server
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at microsoft.aspnet.signalr.client.transport.HttpClientTransport$1.onResponse(HttpClientTransport.java:86)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at microsoft.aspnet.signalr.client.http.java.NetworkRunnable.run(NetworkRunnable.java:82)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at java.lang.Thread.run(Thread.java:856)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: Caused by: microsoft.aspnet.signalr.client.http.InvalidHttpStatusCodeException: Invalid status code: 400
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: Response: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: <HTML><HEAD><TITLE>Bad Request</TITLE>
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: <BODY><h2>Bad Request - Invalid Hostname</h2>
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: <hr><p>HTTP Error 400. The request hostname is invalid.</p>
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: </BODY></HTML>
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err: Headers: [null: HTTP/1.1 400 Bad Request; ]; [Date: Wed, 14 Oct 2015 20:01:57 GMT; ]; [Content-Length: 334; ]; [X-Android-Received-Millis: 1444852816135; ]; [Connection: close; ]; [Content-Type: text/html; charset=us-ascii; ]; [Server: Microsoft-HTTPAPI/2.0; ]; [X-Android-Sent-Millis: 1444852816126; ]; 
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at microsoft.aspnet.signalr.client.transport.HttpClientTransport.throwOnInvalidStatusCode(HttpClientTransport.java:206)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     at microsoft.aspnet.signalr.client.transport.HttpClientTransport$1.onResponse(HttpClientTransport.java:76)
10-14 20:00:16.135 27165-27165/com.izmyr.projectx W/System.err:     ... 2 more

I tried to take the code from onCreate and put it into an AsyncTask, but it didn't work either.

I need any kind of suggestion/solution as soon as possible.

Edit: The following is my simple server side code:

using System;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Hosting;
using Owin;
using Microsoft.Owin.Cors;

namespace ConsoleApplication1
{
    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);

                var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
                var key = Console.ReadLine();
                while (key != "quit")
                {
                    context.Clients.All.Send("Server", key);
                    key = Console.ReadLine();
                }
            }
        }
    }
    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();
        }
    }
    public class MyHub : Hub
    {
        public void Receive(string name, string message)
        {
            Console.WriteLine(name + " " + message);
        }

        public void Send(string name, string message)
        {
            Clients.All.addMessage(name, message);
        }
    }
}
Ugurcan Yildirim
  • 5,973
  • 3
  • 42
  • 73
  • Try using SubscriptionHandler1 instead of SubscriptionHandler2. Moreover, make sure your Hub name is same as server side. If possible, post your server app's code. And read my answer at the following http://stackoverflow.com/questions/32573823/how-to-use-signalr-in-android/32574829#32574829 – BNK Oct 14 '15 at 22:23
  • And try using "ClientTransport clientTransport..." as in my link above – BNK Oct 14 '15 at 22:28
  • I added my server side code. There can't be problem with the SubscriptionHandler since my code cannot even come to that line. It always throws exception at connection.start().get();. Using ClientTransport did not change the situation either. – Ugurcan Yildirim Oct 14 '15 at 22:42
  • Have you checked access from your emulator's web browswer to http://10.0.2.2:8080/signalr yet? – BNK Oct 14 '15 at 23:48
  • I also have a similar error "java.util.concurrent.ExecutionException: microsoft.aspnet.signalr.client.transport.NegotiationException: There was a problem in the negotiation with the server". I am running the app on a real device on wifi I have uploaded a demo of signalR on a remote server.. I am using android studio to run the project.. can someone guide me ? – Umar Farooque Nov 07 '16 at 06:09

3 Answers3

0

From your logcat "...Caused by: microsoft.aspnet.signalr.client.http.InvalidHttpStatusCodeException: Invalid status code: 400..." and "...HTTP Error 400. The request hostname is invalid...".

So check your server app first. From your PC/laptop's web browser, access http://ip:8080/signalr (with ip is the IP address of your PC) instead of http://localhost:8080/signalr and see the result.

Then, from your android client, replace 10.0.2.2 by that IP.

BNK
  • 23,994
  • 8
  • 77
  • 87
  • The result is "Bad Request - Invalid Hostname / HTTP Error 400. The request hostname is invalid.". What could be the problem? – Ugurcan Yildirim Oct 15 '15 at 06:45
  • If you use IIS Express, read http://stackoverflow.com/questions/14725455/connecting-to-visual-studio-debugging-iis-express-server-over-the-lan. Moreover, search many other available topics in StackOverflow – BNK Oct 15 '15 at 08:32
0

Going to clarify few things. From the accepted answer I got the idea.

  • Step 1: I have done change in applicationhost.config file which is located on username\Documents\IISExpress\config location. For older

  • Step 2: Find like this block (according to your application):

<site name="SignalRChat" id="11"> <application path="/" applicationPool="Clr4IntegratedAppPool"> <virtualDirectory path="/" physicalPath="D:\Local\Experiment\SignalRAndroid\SignalRAndroid-master\Src\SignalR Server\SignalRChat" /> </application> <bindings> <binding protocol="http" bindingInformation="*:52527:localhost" /> <binding protocol="http" bindingInformation="*:52527:*" /> </bindings> </site> - Step 3: Add following line in binding tag. <binding protocol="http" bindingInformation="*:52527:*" />

It will look like following

<site name="SignalRChat" id="11">
            <application path="/" applicationPool="Clr4IntegratedAppPool">
                <virtualDirectory path="/" physicalPath="D:\Local\Experiment\SignalRAndroid\SignalRAndroid-master\Src\SignalR Server\SignalRChat" />
            </application>
            <bindings>
                <binding protocol="http" bindingInformation="*:52527:localhost" />
                <binding protocol="http" bindingInformation="*:52527:*" />
            </bindings>
        </site>

1.Save the applicationhost.config file.

2.Run Visual Studio in Administrator mode. (Must)

3.Change the port accordingly.

bluetoothfx
  • 643
  • 9
  • 23
-1

I solved the problem by replacing the line string url = "http://localhost:8080"; with string url = "http://*:8080"; in the server side code and running it as administrator.

Ugurcan Yildirim
  • 5,973
  • 3
  • 42
  • 73