SignalR websockets can be successfully rerouted with Ocelot
Fails on the handshake due to inability to map websockets and xhr requests for the same upstream url
Start APIGatewayTest
Start DummySignalRClient
Expected: logs dummy test message to console
Actual: cannot enstablish connection
Open DummySignalRWebClient.html in browser
Expected: logs dummy test message to browser console
Actual: cannot establish connection
Browser network log:
Detailed error:
How a successfull handshake looks like:
Notes:
In order to have a successful handshake with SignalR not only the websocket has to be rerouted.
@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!
@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.
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.
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" ]
},
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();
}
@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.
@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
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
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" ]
}
]
}
Just released in 8.0.7
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 ?

hi, there's no typo here?
Most helpful comment
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 ?