sefidgaran / signalr_client

A Flutter SignalR Client for ASP.NET Core
https://pub.dev/packages/signalr_netcore
MIT License
71 stars 111 forks source link

Not working with WebSockets: The underlying connection was closed before the hub handshake could complete. #84

Closed kyi87 closed 4 months ago

kyi87 commented 4 months ago

Hello, im not able to connect to the server via HttpTransportType.WebSockets. Only LongPolling is working.

The error in my Flutter App:

Flutter:

I/flutter ( 8403): WebSocketException: Connection to 'http://10.0.2.2:5000/chat?id=pzbBXHKBQZlYW1Mbfhv3Og&access_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjgwNzhkMGViNzdhMjdlNGUxMGMzMTFmZTcxZDgwM2I5MmY3NjYwZGYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZGlhYmVzdGllcy1kZXYiLCJhdWQiOiJkaWFiZXN0aWVzLWRldiIsImF1dGhfdGltZSI6MTcxMDQyOTU2MywidXNlcl9pZCI6IkRXOWNmSDVNU3pZbGE5aTlybzI0aUdVaXFqSTIiLCJzdWIiOiJEVzljZkg1TVN6WWxhOWk5cm8yNGlHVWlxakkyIiwiaWF0IjoxNzEyNTc3MTk1LCJleHAiOjE3MTI1ODA3OTUsImVtYWlsIjoibGFuemluZ2VyLmpvY2hlbkBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJsYW56aW5nZXIuam9jaGVuQGdtYWlsLmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6InBhc3N3b3JkIn19.m8P7SpdxtLBRysGXSF0FMEYYYKwh_fvyUbRwyX5mGtI_NLwi0NCVq1WDIYa6boolkP1DxHdqKTIkUFBpukYBR6qk6bcezrwedLcHNvkSNjYCMIDWIRb915vmYbZUPQWqQSGYaIap8SYsmzQuS2zKk1JVeZ3WiPUXEVJZu8qZFvRLAsg5aLF0Eg2l7RGvHJgLxkGxL5bjLjqOsZDW-fj68A5rH_W6gdeJpJE0lB4iSC92cDJaTBhGbVgVivgcrgCpynwrPmL0vUvsSGN7yR1fAmdDW74zE_pKnvJJq4a6B8edrXZeGkLiPKcUnAvFhOJWiX7Vx1-
I/flutter ( 8403): #0      _WebSocketImpl.connect (dart:_http/websocket_impl.dart:1011:41)
I/flutter ( 8403): #1      WebSocket.connect (dart:_http/websocket.dart:320:22)
I/flutter ( 8403): #2      new IOWebSocketChannel.connect (package:web_socket_channel/io.dart:81:28)
I/flutter ( 8403): #3      connect (package:web_socket_channel/src/_connect_io.dart:15:24)
I/flutter ( 8403): #4      new WebSocketChannel.connect (package:web_socket_channel/src/channel.dart:115:16)
I/flutter ( 8403): #5      WebSocketTransport.connect (package:signalr_netcore/web_socket_transport.dart:53:35)
I/flutter ( 8403): <asynchronous suspension>
I/flutter ( 8403): #6      HttpConnection._createTransport (package:signalr_netcore/http_connection.dart:529:9)
I/flutter ( 8403): <asynchronous suspension>
I/flutter ( 8403): #7      HttpConnection._startInternal (package:signalr_netcore/http_connection.dart:409:9)
I/flutter ( 8403): <asynchronous suspension>
I/flutter ( 8403): #8      HttpConnection.start (package:signalr_netcore/http_connection.dart:255:5)
I/flutter ( 8403): <asynchronous suspension>
I/flutter ( 8403): #9      HubConnection._startInternal (package:signalr_netcore/hub_connection.dart:222:5)
I/flutter ( 8403): <asynchronous suspension>
I/flutter ( 8403): #10     HubConnection._startWithStateTransitions (package:signalr_n
I/flutter ( 8403): ----------------------------------------------------
I/flutter ( 8403): The underlying connection was closed before the hub handshake could complete.

The Server is running AspNetCore .NET 6. and it seems the connection is established:

Server:

dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionManager[1]
      New connection BTYadsgw16KtE0icTiVAuQ created.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionDispatcher[10]
      Sending negotiation response.

Does anyone experiencing the same Problem?

Thank you.

kyi87 commented 4 months ago

I found the solution, problem as in the server. I had to add the JwtBearerEvents in my AddJwtBearer Method:

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = "https://securetoken.google.com/" + firebaseConfig.AppId;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = "https://securetoken.google.com/" + firebaseConfig.AppId,
                ValidateAudience = true,
                ValidAudience = firebaseConfig.AppId,
                ValidateLifetime = true
            };
            options.Events = new JwtBearerEvents
            {
                OnMessageReceived = context =>
                {
                    var path = context.Request.Path;
                    if (path.StartsWithSegments("/chat"))
                    {
                        var accessToken = context.Request.Query["access_token"];
                        if (!string.IsNullOrEmpty(accessToken))
                        {
                            context.Request.Headers.Add("Authorization", new[] { $"Bearer {accessToken}" });
                        }
                    }
                    return Task.CompletedTask;
                }
            };
        });
Ertuss commented 1 month ago

@kyi87 thanks man saved lots of time waste