0

I've spent too much time trying to figure this out, and I'm starting to exhaust the threads here on SO that are dealing with this very issue. Feel free to link to other threads about this issue, but I've probably already consulted those with no success.

I'm following Microsoft's Signalr example app from this url: https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr

I'm running IIS 8.5 on Windows Server 2012 R2, SignalR 2.2.1, and .Net 4.5.2 and when I run the application from Visual Studio, this simple chat application runs as expected. As soon as I throw it up on IIS, it breaks (404 for generated proxy). Below is the code I'm working with and the error output.

index.html:

<!DOCTYPE html>
<html>
<head>
    <title>SignalR Simple Chat</title>
    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <input type="hidden" id="displayname" />
        <ul id="discussion"></ul>
    </div>
    <!--Script references. -->
    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-3.1.1.min.js"></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="signalr/hubs"></script>
    <!--Add script to update the page and send messages.-->
    <script type="text/javascript">
        $(function () {
            // Declare a proxy to reference the hub.
            var chat = $.connection.chatHub;
            // Create a function that the hub can call to broadcast messages.
            chat.client.broadcastMessage = function (name, message) {
                // Html encode display name and message.
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page.
                $('#discussion').append('<li><strong>' + encodedName
                    + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };
            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            // Set initial focus to message input box.
            $('#message').focus();
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // Call the Send method on the hub.
                    chat.server.send($('#displayname').val(), $('#message').val());
                    // Clear text box and reset focus for next comment.
                    $('#message').val('').focus();
                });
            });
        });
    </script>
</body>
</html>

ChatHub.cs:

using System;
using System.Web;
using Microsoft.AspNet.SignalR;

namespace SOChatApp
{
    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }
}

Startup.cs:

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}

Browser Console Error:

Failed to load resource: the server responded with a status of 404 (Not Found) which points to http://sub.domain.com/MyApp/signalr/hubs

My application started as an empty web application as instructed by the demo app I linked at the top of this post, so the script reference issues associated with MVC style applications should not apply here.

I've tried many solutions relevant to Signalr 2. Since I'm on IIS 8.5, it shouldn't be having an issue with extensionless urls. I also have a few suggested installed features on my IIS including WebSocket protocol, though I was told that wasn't 100% necessary. I've tried restarting the w3svc, recycling the application pool, and clearing the ASP.NET temp files cache as well.

Am I just messing this up?

UPDATE

With @klabranche's extensive help, I decided not to use the very basic sample tutorial that I linked to at the top of this question.

Instead, he suggested I try this tutorial here: https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc

Following this tutorial was enough to get the application running on IIS. I had to target .net 4.5 instead of 4.5.2 though.

  • try check here http://stackoverflow.com/questions/38392489/signalr-2-2-returns-404-not-found-on-iis-8-5 – Mark Feb 15 '17 at 02:10

1 Answers1

0

The 404 means your file is not being found by the web server. You moved from localhost to a server where the relativity of the link changed. In ASP.Net relative paths are represented by the tilde character (~/).

It looks to me like your script references are not relative and since you moved it to a server the location is not as expected.

Add ~/ to all your script paths.

instead of <script src="signalr/hubs"></script> try <script src="~/signalr/hubs"></script>

The docs use ~/ but unfortunately the sample does not. It would work localhost with IIS Express as you have expressed.

You can also generate the proxy file. Read "How to create a physical file for the SignalR generated proxy section on how to do that. You don't have to do this to get SignalR to work though but wanted to throw it out there as another option.

Kevin LaBranche
  • 20,908
  • 5
  • 52
  • 76
  • I've tried this in the past, and I just double checked. This causes a 404 against `http://sub.domain/MyApp/~/signalr/hubs` -- I noticed adding ~/ to script paths cleared up the issue for some people running MVC style apps, but this example app I'm running is not MVC. – Johnny Pints Feb 15 '17 at 17:18
  • ~/ is ASP.Net in general. Works for WebForms or MVC. If you are actually getting a 404 to http://sub.domain/myapp/~/signalr/hubs then it's not resolving the ~/ to the relative path and actually is using it as the actual path. This says to me that your app is not running as an ASP.Net application on the server. Have you setup the IIS application settings properly? IISExpress & Visual Studio does this automatically for you.... – Kevin LaBranche Feb 15 '17 at 17:28
  • Is it not resolving to the relative path because I'm actually not using a .aspx web form? All the client side work is inside a raw html file, index.html – Johnny Pints Feb 15 '17 at 17:43
  • But the hub is generated by the C# dll that is created on compile at runtime via reflection. If your app is not setup as an .NET application in IIS then the hub won't be created and the ~/ syntax won't be recognized and properly handled. As in your comment, IIS is literally looking for a folder of ~. Additionally, your c# hub code will never be executed. It doesn't matter that you aren't using any webform or mvc syntax, aka - just raw html. It's still an .Net application. – Kevin LaBranche Feb 15 '17 at 17:49
  • For example you could generate your proxy as I mentioned in my answer and change your link to point to it like a normal javascript file. However, you'll find that your server side C# code will never execute since it appears to me that this IIS folder/app has not been setup to run as an .Net application. – Kevin LaBranche Feb 15 '17 at 17:50
  • The folder MyApp on your IIS server needs to be an "application" (right click the folder in IIS Manager and select "convert to application" and the application pool it runs in needs to be the correct .Net version. The default application pool might be enough but you will have to make sure it is running the correct version. Although if this is a server, it is recommended to have an application pool per app. Changing the default app pool settings will affect all apps using it. So do this with care. This assumes IIS was setup properly to run Asp.Net applications in the first place. – Kevin LaBranche Feb 15 '17 at 18:00
  • Yeah, I've tried what you mentioned in your answer in the past. I pulled in the physical file for hubs, but then was hitting a different 404 during negotiating. As to the rest, I'm in the middle of working on it. This is extremely helpful. – Johnny Pints Feb 15 '17 at 18:11
  • The best way to put this is you are having an issue with deploying the sample properly to IIS with ASP.Net. The sample is extremely basic and didn't go over any of this. It's good for VS/IIS Express. I would look for real world examples that could help you better. I would use the getting started with signalr and asp.net mvc sample -> https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc as a better "real" starting point. – Kevin LaBranche Feb 15 '17 at 18:52
  • I, for example, just deployed the same sample you used https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr to one of my boxes with SignalR apps already on it and it doesn't run as is. – Kevin LaBranche Feb 15 '17 at 18:54
  • Yeah, I feel like I've opened up a huge can of worms, and configuring IIS is not one of my strengths. I know we've run asp.net apps in the past off this same server using the same .net framework that I'm currently trying to use, but I feel like you've pointed me in the right direction. – Johnny Pints Feb 15 '17 at 19:12
  • Thanks so much, @klabranche. With the sample application you linked at https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc I was able to get this running on IIS and now I can go forward with my actual project. – Johnny Pints Feb 15 '17 at 21:38
  • @JohnnyPints That's great news!!!! So glad to help. No person is an island. WE NEED EACH OTHER! Good Luck on your project! :-) – Kevin LaBranche Feb 16 '17 at 17:55