user1594757
user1594757

Reputation: 301

SignalR Negotiate 404

I am using SignalR 2.0. Everything works fine when running locally on my VS 2012. But when I publish the site on IIS, it breaks. The site loads but one of the scripts returns 404 Not Found. The script is something like.

https://example.com/signalr/negotiate?xxx

This path doesn't exist indeed. The correct path should be:

https://example.com/private/signalr/negotiate?xxx

Note the part in bold.

Inside the WebSite (https://example.com/) I have another Application (https://example.com/private/). This one is using SignalR.

This seems like a bug in SignalR since the signalr/hubs path is accessible from my private site.

Upvotes: 27

Views: 47745

Answers (8)

PeterF
PeterF

Reputation: 161

I had the same problem, with an application running in the IIS Default Web Site.
All the Microsoft examples show the hub url with a starting \, and I had copied those examples. But this meant that the signalr routing was from the Default Web Site rather than the application. Removing the leading \ solved it.

So I used endpoints in Startup.cs like:

endpoints.MapHub<MyHub>("myHub");

and hub connections in Javascript like:

var connection = new signalR.HubConnectionBuilder().withUrl("myHub").build();

Upvotes: 10

Shakibuz_Zaman
Shakibuz_Zaman

Reputation: 270

I faced the same problem. The mistake i was doing that i was calling the wrong endpoint url like i was mapping the Signal Url in Configure service like /notification but calling [API-Host]/api/notification. Removing the api from url and calling [API-Host]/notification fixed for me.

Upvotes: 2

Mehdi Payervand
Mehdi Payervand

Reputation: 251

I had the same problem, it is all about CORS, you should add Host URL in CORS config in Startup.cs like this:

            services.AddCors(option =>
        {
            option.AddPolicy("AutomationCors", builder =>
            {
                builder.AllowAnyMethod()
                    .AllowAnyHeader()
                    .WithOrigins("YOUR LOCALHOST URL",
                                 "YOUR HOST URL")
                    .AllowCredentials();
            });
        });

Upvotes: 2

David Reche
David Reche

Reputation: 13

@styfle point me in the right direction the problem can be resolve in a more flexible way injecting BASE_URL (at least in angular 4)

import { Injectable, Inject } from '@angular/core';
import { HubConnection } from '@microsoft/signalr';
import * as signalR from '@microsoft/signalr';
import { Subject, Observable } from 'rxjs';

@Injectable()
export class SignalRService {
    private hubConnection: HubConnection;
    private message: Subject<any>;

    constructor(@Inject('BASE_URL') private baseUrl: string) {
    }

    public connect() {
        this.message = new Subject<any>();
        this.hubConnection = new signalR.HubConnectionBuilder()
            .withUrl(this.baseUrl+"notification-hub")
            .withAutomaticReconnect()
            .build();
        // ...
    }
}

Upvotes: 0

YY_Minneapolis
YY_Minneapolis

Reputation: 31

Had the same issue. web sites running as virtual directories of the root site. For some reason prefixing with ../ as in ../signalr didn't work, but ./signalr did.

My sample code:

function initSR() {
    // logs signalr messages
    $.connection.hub.logging = true;

    // Declare a proxy to reference the hub.             
    var chat = $.connection.myHub;
    $.connection.hub.url = "./signalr";
    $.connection.hub.start();
    // Create a function that the hub can call to broadcast messages.
    chat.client.broadcastMessage = function (message) {
        // Process Message, take action upon receipt
        alert(message);
    };
}

Upvotes: 3

Gustavo Armenta
Gustavo Armenta

Reputation: 1553

Probably you added MapSignalR() in your Application (https://example.com/private/). If you want it on the root, then do the configuration on your WebSite (https://example.com/)

Upvotes: 0

Jyo Reddy
Jyo Reddy

Reputation: 732

I had the same issue when web site with signalr is not running as root site. Below solution worked for me. instead of using /signalr, use ../signalr. it will work with any site name folder. no hardcoded name 'MyApp' var connection = $.hubConnection('../signalr', {useDefaultPath: false});

Upvotes: 3

styfle
styfle

Reputation: 24700

I had a similar problem. Here is the documentation for configuring the /signalr URL.

However, my solution differed from the docs. Instead of changing the standard app.MapSignalR(), I changed my client code to use /MyApp/signalr. Here is the code where "MyApp" is the virtual directory of my web application.

        var connection = $.hubConnection('/MyApp/signalr', {useDefaultPath: false});
        var changesHub = connection.createHubProxy('changesHub');

        changesHub.on('userCountChanged', function (count) {
            $('#user-count').text(count);
        });

        connection.start().done(function () {
            console.log('Hub has started');
            changesHub.invoke('subscribeToChanges', user.id);
        });

I tried the other way around (change the MapSignalR to the /signalr path) but this did not work and the negotiation was still routed to /MyApp/signalr/negotiate.

Upvotes: 22

Related Questions