locked
Error 500 using Azure SignalR service RRS feed

  • Question

  • User-1202235188 posted

    Hi All,

    Apologies if this is a simple issue, but it's been driving me crazy and I'm at the end of my tether trying to find a solution to it.

    I'm working with a .net MVC 5 application (not core) and as $.connection.hub.start().done(); fires I get a 500 error in the console as such;

    ajax.ts:153 GET http://localhost:57690/AzureSignalr/negotiate?clientProtocol=2.0&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&_=1554911519819 500 (Internal Server Error)
    Request URL: http://localhost:57690/AzureSignalr/negotiate?clientProtocol=2.0&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&_=1554912978220
    Request Method: GET
    Status Code: 500 Internal Server Error
    Remote Address: [::1]:57690
    Referrer Policy: no-referrer-when-downgrade




    The response from the request says "Azure SignalR Service is not connected yet, please try again later." - I'm not able to get any more information regarding the error

    So how is this all setup you might ask?

    A very simple test page within the application;

    <script src="/Scripts/jquery-3.3.1.js"></script>
    <script src="/Scripts/jquery.signalR-2.4.0.js"></script>
    <script src="/AzureSignalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            var messages = $.connection.myHub;
    
            messages.client.broadcastMessage = function (message) {
                alert(message);
            };
    
            $.connection.hub.start().done(function () {
                $('#clicker').click(function () {
                    messages.server.send("Someone clicked");
                });
            });
        });
    </script>
    
    @{
        ViewBag.Title = "Home";
    }
    
    <div id="clicker">Click me</div>

    The hub;

    using Microsoft.AspNet.SignalR;
    
    namespace Hubs
    {
        public class MyHub : Hub
        {
            public void Send(string messageText)
            {
                Clients.All.broadcastMessage(messageText);
            }
        }
    }

    Startup.cs

    using Microsoft.AspNet.SignalR;
    using Microsoft.Owin;
    using Owin;
    
    [assembly: OwinStartupAttribute(typeof(MySystem.Startup))]
    namespace MySystem
    {
        public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                ConfigureAuth(app);
                app.MapAzureSignalR("/AzureSignalr", this.GetType().FullName, new HubConfiguration());
            }
        }
    }
    

    I've included the requisite NuGet packages for;

    Microsoft.AspNet.SignalR v2.4.0

    Microsoft.Azure.SignalR.AspNet v1.0.0-preview1-10352

    Inside the ConfigureAuth(app) function, I'm not doing anything special however it is setting up Identity

    // Configure the dbcontext, user manager and signin manager to use a single instance per request
    MyContext dbContext = DependencyResolver.Current.GetService<MyContext>();
    ISoftLockoutSettings lockoutSettings = DependencyResolver.Current.GetService<ISoftLockoutSettings>();
                
    
    app.CreatePerOwinContext<IUserStore<UserEnt>>(() => ApplicationUserStore.Create(dbContext));
    
    app.CreatePerOwinContext<ApplicationUserManager>((IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) => ApplicationUserManager.Create(options.DataProtectionProvider, context, lockoutSettings, HttpContext.Current.GetOwinContext().Get<IUserStore<UserEnt>>()));
    app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);            
    
    // Enable the application to use a cookie to store information for the signed in user
    // and to use a cookie to temporarily store information about a user logging in with a third party login provider
    // Configure the sign in cookie
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Login/Index"),
        ReturnUrlParameter = "url", // see LoginController.Index
        Provider = new CookieAuthenticationProvider
        {
            // Enables the application to validate the security stamp when the user logs in.
            // This is a security feature which is used when you change a password or add an external login to your account.  
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, UserEnt>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
        },
        ExpireTimeSpan = TimeSpan.FromMinutes(180), // TODO setting/policy
        SlidingExpiration = true, // refresh login status (when it's more than half over and user makes a request)
    });
    
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
    // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
    app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
    
    // Enables the application to remember the second login verification factor such as phone or email.
    // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
    // This is similar to the RememberMe option when you log in.
    app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

    Web config has the connection string;

    <connectionStrings>
        <add name="Azure:SignalR:ConnectionString" connectionString="Endpoint=https://xxxx.service.signalr.net;AccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxx=;Version=1.0;" />
    </connectionStrings>

    I've set up a brand new MVC project and followed the exact same steps as above (albeit without the ConfigureAuth as it was just a test application) and SignalR works

    In this test application, I get the first response as such;

    Request URL: http://localhost:50772/AzureSignalr/negotiate?clientProtocol=2.0&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&_=1554913085442
    Request Method: GET
    Status Code: 200 OK
    Remote Address: [::1]:50772
    Referrer Policy: no-referrer-when-downgrade

    Followed by;

    Request URL: https://xxxxxxxx.service.signalr.net/aspnetclient/negotiate?clientProtocol=2.0&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&_=1554913085443
    Request Method: OPTIONS
    Status Code: 204 
    Remote Address: xx.xxx.xx.xx:443
    Referrer Policy: no-referrer-when-downgrade

    This leads me to believe that it is either a routing or permissions issue, but I'm not entirely sure.

    Has anyone had a similar error or know any fixes for this?

    Many Thanks,

    Tom

    Wednesday, April 10, 2019 4:21 PM

Answers

  • User-1202235188 posted

    I've now managed to solve the problem.

    I had to add the SecurityProtocol to the startup.cs file

    public partial class Startup
    {
    public void Configuration(IAppBuilder app)
    {
    ConfigureAuth(app);
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    app.MapAzureSignalR("/AzureSignalrPath", this.GetType().FullName, new HubConfiguration());
    }
    }
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, April 11, 2019 2:01 PM

All replies

  • User753101303 posted

    Hi,

    Http 500 means you have a server side exception. By default it should go to the Windows event log. You don't have anything there ? How do you handle exceptions ?

    Generally speaking it is likely easier to always start from some actual error message rather than trying to guess what happens by reading code and looking at configuration settings (and so even before giving a first look at the code I always try to spend few extra minutes in gathering details about what actually happens)...

    Edit: AFAIK a routing issue should show a 404 (the server doesn't find anything that could respond to the incoming query) or 401/403 (if the user is not authenticated when it should or if access is denied).

    Another source I'm using is the IIS log and in particular the "substatus". Actually 500 means the errror happens server side. It is often a code exception but it could be some other server side error (for example 500.19 would point at a config file error)

    Wednesday, April 10, 2019 4:32 PM
  • User-1202235188 posted

    Hi ParticeSc,

    Thanks for replying.

    In terms of errors, there are in App Insights

    {
      "name": "Microsoft.ApplicationInsights.Dev.1ccd5093df4e4f839b6d433718ee566f.Request",
      "time": "2019-04-11T08:05:43.7675156Z",
      "iKey": "1ccd5093-df4e-4f83-9b6d-433718ee566f",
      "tags": {
        "ai.cloud.roleInstance": "DESKTOP-SQ9UCSB",
        "ai.session.id": "B+96s",
        "ai.user.id": "ujRi4",
        "ai.operation.id": "trS6B",
        "ai.operation.parentId": "|trS6B.adfis",
        "ai.operation.name": "GET /AzureSignalr/negotiate",
        "ai.location.ip": "::1",
        "ai.internal.sdkVersion": "web:2.8.1-19196",
        "ai.internal.nodeName": "DESKTOP-SQ9UCSB"
      },
      "data": {
        "baseType": "RequestData",
        "baseData": {
          "ver": 2,
          "id": "|trS6B.adfis.8d4e7ece_",
          "name": "GET /AzureSignalr/negotiate",
          "duration": "00:00:00.0025027",
          "success": false,
          "responseCode": "500",
          "url": "http://localhost:57690/AzureSignalr/negotiate?clientProtocol=2.0&connectionData=[{\"name\":\"myhub\"}]&_=1554969943576",
          "properties": {
            "DeveloperMode": "true",
            "_MS.ProcessedByMetricExtractors": "(Name:'Requests', Ver:'1.1')"
          }
        }
      }
    }

    Nothing gets logged to the windows event viewer sadly

    A good point that a routing error would likely return as a 400 so perhaps it is a permissions-based issue that is causing the 500

    Thursday, April 11, 2019 8:18 AM
  • User753101303 posted

    And on the App Insights portal then? I would except the usual message ie somethung such as :

    System.NullReferenceException: Object reference not set to an instgance of an object.
       at Class.Method
       at Caller.CallerMethod
       at ...
    Thursday, April 11, 2019 8:27 AM
  • User-1202235188 posted

    In the App Insights portal I can see it logs this;

    Time	10:19:31
    Name	GET /AzureSignalr/negotiate
    Incoming URL	http://localhost:57690/AzureSignalr/negotiate?clientProtocol=2.0&connectionData=[%7B%22name%22:%22myhub%22%7D]&_=1554974372330
    Response code	500
    Duration	4 ms
    DeveloperMode	true

    But it doesn't provide any more information in App Insights.

    In the IIS Express logs I can see a trace log with the following; 

    <failedRequest url="http://localhost:57690/AzureSignalr/negotiate?clientProtocol=2.0&amp;connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&amp;_=1554973262127"
                   siteId="2"
                   appPoolId="Clr4IntegratedAppPool"
                   processId="18156"
                   verb="GET"
                   remoteUserName="xxxxxxxxx"
                   userName="xxxxxxxxx"
                   tokenUserName="AzureAD\xxxxxxxxxxx"
                   authenticationType="ApplicationCookie"
                   activityId="{80000052-0004-FF00-B63F-84710C7967BB}"
                   failureReason="STATUS_CODE"
                   statusCode="500"
                   triggerStatusCode="500"
                   timeTaken="15"
                   xmlns:freb="http://schemas.microsoft.com/win/2006/06/iis/freb"
                   >

    The event within this log that shows the 500 is this;

    <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
     <System>
      <Provider Name="WWW Server" Guid="{3A2A4E84-4C21-4981-AE10-3FDA0D9B0F83}"/>
      <EventID>0</EventID>
      <Version>1</Version>
      <Level>3</Level>
      <Opcode>16</Opcode>
      <Keywords>0x100</Keywords>
      <TimeCreated SystemTime="2019-04-11T09:01:02.344Z"/>
      <Correlation ActivityID="{80000052-0004-FF00-B63F-84710C7967BB}"/>
      <Execution ProcessID="18156" ThreadID="13096"/>
      <Computer>DESKTOP-SQ9UCSB</Computer>
     </System>
     <EventData>
      <Data Name="ContextId">{80000052-0004-FF00-B63F-84710C7967BB}</Data>
      <Data Name="ModuleName">__DynamicModule_Microsoft.Owin.Host.SystemWeb.OwinHttpModule, Microsoft.Owin.Host.SystemWeb, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35_ed612830-d174-4c74-ba1f-93c69902f2c6</Data>
      <Data Name="Notification">4</Data>
      <Data Name="HttpStatus">500</Data>
      <Data Name="HttpReason">Internal Server Error</Data>
      <Data Name="HttpSubStatus">0</Data>
      <Data Name="ErrorCode">0</Data>
      <Data Name="ConfigExceptionInfo"></Data>
     </EventData>
     <RenderingInfo Culture="en-GB">
      <Opcode>MODULE_SET_RESPONSE_ERROR_STATUS</Opcode>
      <Keywords>
       <Keyword>RequestNotifications</Keyword>
      </Keywords>
      <freb:Description Data="Notification">AUTHORIZE_REQUEST</freb:Description>
      <freb:Description Data="ErrorCode">The operation completed successfully.
     (0x0)</freb:Description>
     </RenderingInfo>
     <ExtendedTracingInfo xmlns="http://schemas.microsoft.com/win/2004/08/events/trace">
      <EventGuid>{002E91E3-E7AE-44AB-8E07-99230FFA6ADE}</EventGuid>
     </ExtendedTracingInfo>
    </Event>

    I'm going to try in the meantime moving the signalr test code to a new view within the application that is outside of permissions and see if that helps things at all

    Thursday, April 11, 2019 9:27 AM
  • User753101303 posted

    Yes trial and error could help to guess but it takes time.

    Still I would recommend once past this to make sure you have the proper tools in place to start from an actual error message.

    For example one posted about a problem about reading a file on a network share and all sort of suggestions were done regarding security etc...which are the usual issues. When  I asked about the exception it became immediately clear that he had invalid characters in his path (even if he told previously the path was correct, it turned out that because of some later programming error he could have the same path twice in his variable or something like that).

    Thursday, April 11, 2019 10:44 AM
  • User-1202235188 posted

    I'd really love to be able to give you a more detailed error, but there simply isn't one being reported. Its possible the system is swallowing the error somewhere which I'll need to solve.

    Thank you for your help anyway Patrice

    Thursday, April 11, 2019 10:54 AM
  • User-1202235188 posted

    I've now managed to solve the problem.

    I had to add the SecurityProtocol to the startup.cs file

    public partial class Startup
    {
    public void Configuration(IAppBuilder app)
    {
    ConfigureAuth(app);
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    app.MapAzureSignalR("/AzureSignalrPath", this.GetType().FullName, new HubConfiguration());
    }
    }
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, April 11, 2019 2:01 PM
  • User753101303 posted

    It might explain the problem as this one likely happened earlier than your own code (you  need to opt-in for older versions, for lastest version Tls12 should be enabled by default). I'll keep that handy as a use case to see how it could be diagnosed.

    Thursday, April 11, 2019 3:47 PM