Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support SignalR #344

Closed
cristianiorga opened this issue May 4, 2018 · 11 comments

Comments

@cristianiorga
Copy link

@cristianiorga cristianiorga commented May 4, 2018

Expected Behavior / New Feature

SignalR websockets can be successfully rerouted with Ocelot

Actual Behavior / Motivation for New Feature

Fails on the handshake due to inability to map websockets and xhr requests for the same upstream url

Steps to Reproduce the Problem

  1. Clone https://github.com/cristianiorga/OcelotSignalRTest

  2. Start DummySignalR

  3. Start APIGatewayTest

  4. Start DummySignalRClient
    Expected: logs dummy test message to console
    Actual: cannot enstablish connection

  5. Open DummySignalRWebClient.html in browser
    Expected: logs dummy test message to browser console
    Actual: cannot establish connection

Browser network log:
error

Detailed error:
detailed error

How a successfull handshake looks like:
signalr handshake

Specifications

  • Version: 6.0.0
  • Platform: Windows
  • Subsystem: Windows 10 Enterprise 64 bit

Notes:
In order to have a successful handshake with SignalR not only the websocket has to be rerouted.

@TomPallister TomPallister changed the title SignalR doesn't work New feature - support SignalR May 4, 2018
@TomPallister

This comment has been minimized.

Copy link
Member

@TomPallister TomPallister commented May 4, 2018

@cristianiorga Thanks for your interest in the project! 😄 Ocelot doesn't currently support SignalR.

I do not have time to follow everything! Do you know if SignalR has an official release for .net core 2.0? Last time I checked it did not :(

I think this would be a useful feature so I will keep this issue open!

@cristianiorga

This comment has been minimized.

Copy link
Author

@cristianiorga cristianiorga commented May 5, 2018

@TomPallister SignalR will be part of the .NET Core 2.1 release coming mid-2018. You can read more about that at https://blogs.msdn.microsoft.com/webdev/2018/02/02/asp-net-core-2-1-roadmap/ , https://blogs.msdn.microsoft.com/webdev/2018/02/27/asp-net-core-2-1-0-preview1-getting-started-with-signalr/ and https://github.com/aspnet/SignalR/milestones
Currently there is a .NET Core 2.1 Developer preview for SignalR and is the one I used in reporting this issue.

I believe that this would be a great feature for Ocelot and I would be willing to help where I can if you can plan and coordinate the work.

@ogomaemmanuel

This comment has been minimized.

Copy link

@ogomaemmanuel ogomaemmanuel commented May 13, 2018

I am building a mobile app using Ionic, when I test it on mobile signalR and ocelot work perfectly, the only problem i have is when testing on the browser. It brings an error i believe could be as result of cors but i can't solve it. here is the error

Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
?ionicplatform=android&http://localhost:8100/ionic-lab&http://localhost:8100/ionic-lab&http://localhost:8100/ionic-lab#/products:1 Failed to load http://myIp/NotificationHub/negotiate: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 405.

@ogomaemmanuel

This comment has been minimized.

Copy link

@ogomaemmanuel ogomaemmanuel commented May 13, 2018

my configuration is as follows
{
"DownstreamPathTemplate": "/NotificationHub/negotiate",
"UpstreamPathTemplate": "/NotificationHub/negotiate",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "servicename",
"Port": 80
}
],
"UpstreamHttpMethod": ["Options", "Post" ]
},

{
  "DownstreamPathTemplate": "/NotificationHub",
  "UpstreamPathTemplate": "/NotificationHub",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "servicename",
      "Port": 80
    }
  ],
  "UpstreamHttpMethod": [ "Options", "Get", "Post" ]

},
@ogomaemmanuel

This comment has been minimized.

Copy link

@ogomaemmanuel ogomaemmanuel commented May 13, 2018

public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.WithOrigins("http://localhost:8100")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
services.AddMvc();
}

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseCors("CorsPolicy");
        app.UseMvc();
    }
@TomPallister

This comment has been minimized.

Copy link
Member

@TomPallister TomPallister commented May 14, 2018

@ogomaemmanuel it is probably the same problem as @cristianiorga mentioned to open this ticket. I have not had time to look into the issue yet I'm afraid. I cannot give a time frame either. Maybe I will have time in the next few months. If you want to help out I would suggest forking the Ocelot repository and debugging the code to see whats going on. I'm more than happy to accept PRs and give advice.

@TomPallister TomPallister changed the title New feature - support SignalR support SignalR May 14, 2018
@IvanMeng

This comment has been minimized.

Copy link

@IvanMeng IvanMeng commented May 16, 2018

@cristianiorga APIGatewayTest project will be changed.
ocelot.json
{ "ReRoutes": [ { "DownstreamPathTemplate": "/dummy", "DownstreamScheme": "ws", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 50000 } ], "UpstreamPathTemplate": "/api/dummy" }, { "DownstreamPathTemplate": "/dummy/negotiate", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 50000 } ], "UpstreamPathTemplate": "/api/dummy/negotiate" } ], "GlobalConfiguration": { "BaseUrl": "http://localhost", "AdministrationPath": "/administration", "RequestIdKey": "OcRequestId" } }

and Program.cs
.Configure(app => { app.UseWebSockets(); app.UseOcelot().Wait(); })
you can try. I get the same result as DummySignalR

@TomPallister

This comment has been minimized.

Copy link
Member

@TomPallister TomPallister commented Aug 2, 2018

from #524

Expected Behavior / New Feature
We are using ocelot with the feature websockets. We are using Signalr Core and trying to forward it to the correct server. With that we are using headers on the requests.

The headers disappear once it goes through ocelot. Is this on purpose?
We verified that the headers will be send to the signalr server when it doen't use ocelot.

Config:

"ReRoutes": [{
"DownstreamPathTemplate": "/{catchAll}",
"DownstreamScheme": "ws",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5000
}
],
"UpstreamPathTemplate": "/gateway/{catchAll}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
}]
Actual Behavior / Motivation for New Feature
The headers are being forwarded with the websockets

Steps to Reproduce the Problem
Start a signalr core server
Configure ocelot as described in http://ocelot.readthedocs.io/en/latest/features/websockets.html
Connect a client throuh ocelot and send a header with it.
Check the headers received on the server
Specifications
Version: 8.0.2
Platform: Windows 10
Subsystem: Microsoft.AspNetCore.SignalR.Client 1.0.1

@JanKolk

This comment has been minimized.

Copy link
Contributor

@JanKolk JanKolk commented Aug 3, 2018

I created a pull request to add headers to the request.

With the following templates it works:

Do not run it in IISExpress or install the websockets feature in the IIS features

Target framework: 2.1.2
Microsoft.AspNetCore.SignalR.Client 1.0.2
Ocelot develop with my pull-request

 public class Program
    {
        public static void Main(string[] args)
        {
            var webHost = WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseIISIntegration()
                .Build();

            webHost.Run();
        }
    }

    public class Startup : IStartup
    {
        public IConfiguration Configuration { get; }

        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("ocelot.json")
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot(Configuration);
            return services.BuildServiceProvider();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseWebSockets();
            app.UseOcelot().Wait();
        }
    }

ocelot.json

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/{catchAll}",
      "DownstreamScheme": "ws",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 50000
        }
      ],
      "UpstreamPathTemplate": "/gateway/{catchAll}",
      "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
    }
 ]
}

TomPallister pushed a commit that referenced this issue Aug 4, 2018
Tom Pallister
TomPallister added a commit that referenced this issue Aug 4, 2018
@TomPallister TomPallister reopened this Aug 4, 2018
@TomPallister TomPallister added the merged label Aug 4, 2018
@TomPallister

This comment has been minimized.

Copy link
Member

@TomPallister TomPallister commented Aug 4, 2018

Just released in 8.0.7

@souchprod

This comment has been minimized.

Copy link

@souchprod souchprod commented Nov 2, 2019

Hi, sorry to ask as it may be a stupid question but i don't really get how it fix the original issue "Fails on the handshake due to inability to map websockets and xhr requests for the same upstream url".
For the http(s) negociate part, should be still add an http(s) DownstreamScheme plus a ws DownstreamScheme for the same route ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.