Roman Suska
Roman Suska

Reputation: 547

SignalR - unable to call server method from external JavaScript client

I am learning SignalR. Using a tutorial I managed to create a very simple ASP.NET MVC based SignalR Server. This is the code of the hub:

[HubName("echo")]
public class EchoHub : Hub
{
    public void Say(string message)
    {
        Trace.WriteLine(message);
    }
}

This is my Startup file:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Map("/signalr", map =>
        {
            map.UseCors(CorsOptions.AllowAll);
            var hubConfiguration = new HubConfiguration
            {
                EnableJSONP = true
            };
            map.RunSignalR(hubConfiguration);
        });
    }
}

Next I created a HTML/JavaScript based client, that was in the same project as the server code. This client works correctly, when I debug the application, the Output window displays my message. This the code of the first client:

<script src="../Scripts/jquery-1.10.2.min.js"></script>
<script src="../Scripts/jquery.signalR-2.1.2.min.js"></script>
<script src="/signalr/hubs"></script>
<script>
        $(function() {
            var hubProxy = $.connection.echo;
            $.connection.hub.logging = true;

            $.connection.hub
                .start()
                .done(function () {
                    hubProxy.server.say('Hello SignalR');
                });
        })
</script>

The last thing I wanted to do is to create an client in separate project. I changed a little bit the code, mostly by adding the url's of the server. But this client don't work properly. This is the code of the client:

<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="http://localhost:51644/signalr/hubs"></script>
<script>
    $(function() {
        $.connection.hub.url = 'http://localhost:51644/signalr';
        var hubProxy = $.connection.echo;
        $.connection.hub.logging = true;

        $.connection.hub
            .start()
            .done(function () {
                hubProxy.server.say('Hello SignalR');
            });
    })
 </script>

The JavaScript don't even enters the function in the done method after starting the connection. But in console on Chrome there are no errors or exceptions being thrown.

So the question is what am I doing wrong in the second client?

EDIT: I enabled and checked the SignalR client logs in Chrome console. The second client is stoping by step "SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.4&connectionData=%5B%5D'." No errors are returned, everything seems alright, but the client cannot go past this step.

EDIT2: According to the comment from JF Beaulieu the negotiate return 200 status code, but nothing else. After the negotiate there should be next steps, like invoking Say, but in the external client hangs on the negotiate. I paste here console outputs from the build in and external JavaScript client.

Build in client output:

enter image description here

External client output:

enter image description here

The second screenshot shows, that the client stops executing on the negotiate step.

I've also tried the solution of Mareq, but adding the jsonp attribute didn't help.

EDIT3: I add here a link to my Github repo with this project, the server is in the AspNetServer project and client in JavaScriptClient project, hope that helps: https://github.com/RomanSuska/SignalRSandbox

Upvotes: 0

Views: 3594

Answers (3)

ZeferiniX
ZeferiniX

Reputation: 500

My case was due to my Hub having a constructor because I was trying to do Dependency Injection with Unity. After I removed the constructor, everything worked.

Upvotes: 1

Roman Suska
Roman Suska

Reputation: 547

I finally found the solution of my problem and it's stupid simple. The problem was with the SignalR JavaScript file version, on the server I used version 2.1.2 of SignalR and on the client I used 2.2.0. When I switched the version of the client to 2.1.2 everything started to work.

Upvotes: 2

nitrosolutions
nitrosolutions

Reputation: 1

Add this argument to start:

$.connection.hub.start({ jsonp: true });

EDIT I hosted SignalR in console app and I used simple set configuration:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR(new HubConfiguration { EnableJSONP = true });
    }
}

and client code I used like this:

$(function () {
        var hub = $.connection.serviceHub;
        $.connection.hub.url = 'http://mareq.ddns.net:8087/signalr';

        $.connection.hub.start({ jsonp: true });

        ...
    });

Upvotes: 0

Related Questions