2

I am trying to connect to a SignalR hub behind an Ocelot Api gateway from a React application. However, when doing so I get the following error:

Unhandled Rejection (Error): 
new HttpError
index.js:1 [2021-01-31T02:42:31.498Z] Error: Failed to complete negotiation with the server: Error
index.js:1 [2021-01-31T02:42:31.498Z] Error: Failed to start the connection: Error
Uncaught (in promise) Error
    at new HttpError (Errors.ts:20)
    at FetchHttpClient.<anonymous> (FetchHttpClient.ts:116)
    at step (FetchHttpClient.ts:2)
    at Object.next (FetchHttpClient.ts:2)
    at fulfilled (FetchHttpClient.ts:2)

I have read Ocelot's documentation on SignalR/WS (https://ocelot.readthedocs.io/en/latest/features/websockets.html) and also made sure that requests are being routed as they should in my ocelot.json:

    {
        "DownstreamPathTemplate": "/notificationhub",
        "DownstreamScheme": "ws",
        "DownstreamHostAndPorts": [
          {
            "Host": "localhost",
            "Port": 7001
          }
        ],
        "UpstreamPathTemplate": "/notifications",
        "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
      },

What is wrong?

user2768479
  • 716
  • 1
  • 10
  • 25

1 Answers1

2

First of all, web sockets secure (wss), which is not mentioned in the Ocelot documentation, can be used as DownStreamScheme as pointed out by sam9291 here (https://github.com/ThreeMammals/Ocelot/issues/1179).

Secondly, Cors must be enabled on the SignalR app with AllowCredentials() as detailed by Microsoft here (https://learn.microsoft.com/en-us/aspnet/core/signalr/security?view=aspnetcore-5.0).

Thirdly, there has to be a {catchAll} route in the ocelot.json, which is necessary becausse the handshake involves getting/posting to other routes:

    {
        "DownstreamPathTemplate": "/notificationhub/{catchAll}",
        "DownstreamScheme": "ws",
        "DownstreamHostAndPorts": [
          {
            "Host": "localhost",
            "Port": 7001
          }
        ],
        "UpstreamPathTemplate": "/notifications/{catchAll}",
        "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
      },

Fourthly, when I tried requesting /notifications after the above change I got error 404, not sure if it is a bug or a feature, like the issue LilRazi ran into here (ocelot: 404 error when add extra path on upstream url). So then I just added a route for the /notifications part, like so:

    {
        "DownstreamPathTemplate": "/notificationhub",
        "DownstreamScheme": "ws",
        "DownstreamHostAndPorts": [
          {
            "Host": "localhost",
            "Port": 7001
          }
        ],
        "UpstreamPathTemplate": "/notifications",
        "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
      },

and everything was working perfectly!

user2768479
  • 716
  • 1
  • 10
  • 25