ThreeMammals / Ocelot

.NET API Gateway
https://www.nuget.org/packages/Ocelot
MIT License
8.32k stars 1.63k forks source link

WebSocket exception #1683

Closed zhaoyongjie183 closed 11 months ago

zhaoyongjie183 commented 1 year ago

Ocelot version: 19.0.2

Ocelot configuration, a route:

{
  "UpstreamPathTemplate": "/JavaMessageService/websocket/{url}",
  "UpstreamHttpMethod": [ "Get", "Post", "PUT", "DELETE", "OPTIONS" ],
  "DownstreamPathTemplate": "/api/websocket/{url}",
  "DownstreamScheme": "ws",
  "DownstreamHostAndPorts": [{
    "Host": "192.168.1.22",
    "Port": 9082
  }]
}

Direct Access to ws://192.168.1.22:9082/api/websocket/xxl was successful. 👇 image


Ocelot UpstreamPathTemplate will report an error 👇 image


The error message of Ocelot pipeline is as follows:

System.ArgumentException: Only Uris starting with 'ws://' or 'wss://' are supported. (Parameter 'uri')
   at System.Net.WebSockets.ClientWebSocket.ConnectAsync(Uri uri, CancellationToken cancellationToken)
   at Ocelot.WebSockets.Middleware.WebSocketsProxyMiddleware.Proxy(HttpContext context, String serverEndpoint)
   at Ocelot.WebSockets.Middleware.WebSocketsProxyMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.DownstreamUrlCreator.Middleware.DownstreamUrlCreatorMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.LoadBalancer.Middleware.LoadBalancingMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.Request.Middleware.DownstreamRequestInitialiserMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.Multiplexer.MultiplexingMiddleware.Invoke(HttpContext httpContext)
   at Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
   at Ocelot.Errors.Middleware.ExceptionHandlerMiddleware.Invoke(HttpContext httpContext)
raman-m commented 1 year ago

Hi Zhao! Thanks for your interest in Ocelot!

We have a big problem in Ocelot now because WebSockets feature is broken during releasing versions from v16 to v19. .NET libs have changed much, a lot of changes in System.Net.* namespaces, including System.Net.WebSockets.ClientWebSocket during .NET 5 → .NET 6 → .NET 7 releases.

System.ArgumentException: Only Uris starting with 'ws://' or 'wss://' are supported. (Parameter 'uri')
   at System.Net.WebSockets.ClientWebSocket.ConnectAsync(Uri uri, CancellationToken cancellationToken)

This exception is strange, because it says the URL is invalid. Could you debug once again and make a screenshot, and show the real value of the Uri uri argument in runtime please?


ocelot UpstreamPathTemplate will report an error

Didn't understand that!


We need to find a root cause of the issue... Could you upload your Visual Studio solution to GitHub please, for evaluation? If you don't want to make it public, then we can go with a private mini-repo. 😉

zhaoyongjie183 commented 1 year ago

Hi raman! This is my solution image This is Nacos Config image This is the Gateway port image Direct Access to ws://192.168.1.22:9082/api/websocket/xxl was successful. An error is reported when accessing through the Gateway address (ws://192.168.1.22:4000/JavaMessage Service/websocket/xxl).The entire operation process has been uploaded. From the video, it can be seen that there is an exception when ocelot forwards websockets. Forwarding the HTTP protocol is normal. From the logs in the video, it can be seen that forwarding the HTTP protocol address:/JavaMessageService/note/ureadCount was successful video

raman-m commented 1 year ago

@zhaoyongjie183 commented on July 31

Nice pictures! But...

I cannot read non-English UI! I don't understand Korean or Chinese lyrics! 🤣

Your solution is completely custom because of custom Nacos service discovery setup. What is the Ocelot.Provider.Nacos package? Can you share NuGet link? Is this the repo of the provider: GitHub | softlgl/Ocelot.Provider.Nacos ? How does this service discovery provider constructs the URL to downstream services? That's why I asked you to show me the Uri uri argument in runtime!!! If the direct connection works it doesn't mean the URL constructed well by custom solution.

Finally,

I can say that your video and configs won't help to find a root cause of the issue.

Again,

Could you upload your Visual Studio solution to GitHub please, for evaluation? Otherwise I cannot help you, sorry! After cloning your solution repo and building the solution by VS compiler I will have a chance to debug the solution, and probably I/you/community will be lucky to find a root cause of the issue.


Next steps

Returning to the protocol error: CLOSED => 1006 CLOSE_ABNORMAL Did client (Ocelot) or downstream service close the protocol connection (generate the error)?

I'm asking you to analyze the logs of downstream service to understand why downstream server has closed the connection.

I assume we have Ocelot to Downstream server WebSocket libraries incompatibility. But we have to prove that! What WebSocket lib/package is used on the downstream service side? I am afraid we can communicate to .NET downstream service only, it is true if SignalR technology reused. But for non-SignalR aka WebSocket communication we must match packs versions... So, finally, I assume that we have ws-protocol versions incompatibility problem.

zhaoyongjie183 commented 1 year ago

Thank you very much for your patience. I've pulled the ocelot source code to local debug. Found the reason why the websocket connection is not working. The cause is that the upstream route template is defined repeatedly, causing the websocket to find the http protocol template

raman-m commented 1 year ago

@zhaoyongjie183 commented on Aug 7:

The cause is that the upstream route template is defined repeatedly, causing the websocket to find the http protocol template

Sorry, does that mean you have invalid definitions of the routes in ocelot.json? For example, if you have a duplicates of upstream templates (routes duplication) then you should have the following validation error in the logs: $"{nameof(route)} {route.UpstreamPathTemplate} has duplicate". If you have some another validation error, you should have in logs a message like that; "Unable to start Ocelot, errors are: bla-bla-bla. Could you confirm once again, that your issue is related to invalid configuration please? Can we close the issue?

raman-m commented 1 year ago

@zhaoyongjie183 Good news! Your bug-issue will be resolved by linked PR.

The issue has been accepted due to open PR #1689

raman-m commented 11 months ago

@zhaoyongjie183 Could you test & verify the bug fix plz? You just need to update develop branch of your forked repo.