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

The underlying connection was closed before the hub handshake could complete. #95

Open
nayefradwi opened this issue Oct 27, 2022 · 1 comment

Comments

@nayefradwi
Copy link

I am facing an issue where I am unable to connect to signalr hub using this package but I am able to connect using a different (not flutter) signalR client.

At first I thought that it could be an issue with the certificate, but i have added

class BadCertificateHttpOverride extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext? context) {
    return super.createHttpClient(context)
      ..badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
  }
}

and it is being called, I am not sure what is the issue and I am struggling to find out please help. Here are the logs:

I/flutter (23866): FINER: 2022-10-27 22:07:35.314430: Starting HubConnection.
I/flutter (23866): FINER: 2022-10-27 22:07:37.919484: Starting connection with transfer format 'TransferFormat.Text'.
I/flutter (23866): FINER: 2022-10-27 22:07:41.187448: The HttpConnection connected successfully.
I/flutter (23866): FINER: 2022-10-27 22:07:41.187898: Sending handshake request.
I/flutter (23866): FINER: 2022-10-27 22:07:46.800255: HttpConnection.stopConnection(Unknown) called while in state ConnectionState.Connected.
I/flutter (23866): FINER: 2022-10-27 22:07:48.346132: HubConnection.connectionClosed(null) called while in state HubConnectionState.Connecting.
I/flutter (23866): FINER: 2022-10-27 22:07:49.159922: Hub handshake failed with error 'The underlying connection was closed before the hub handshake could complete.' during start(). Stopping HubConnection.
I/flutter (23866): FINER: 2022-10-27 22:07:49.161156: Call to HttpConnection.stop(Exception: The underlying connection was closed before the hub handshake could complete.) ignored because the connection is already in the disconnected state.
I/flutter (23866): FINER: 2022-10-27 22:07:49.162053: HubConnection failed to start successfully because of error 'The underlying connection was closed before the hub handshake could complete.'.

this is how I am building the connection:

  HubConnection buildConnection() {
    final transportProtLogger = Logger("SignalR - transport");
    final hubProtLogger = Logger("SignalR - hub");
    PrintUtil.info(text: "building hub connection");
    HubConnection connection = HubConnectionBuilder()
        .withUrl(
          AppConfig.signalrUrl,
          options: HttpConnectionOptions(
            logger: transportProtLogger,
            logMessageContent: !AppConfig.isProd,
            transport: HttpTransportType.WebSockets,
            accessTokenFactory: () async {
              String accessToken = GetIt.I<ShopperApiClient>().accessToken;
              return accessToken;
            },
          ),
        )
        .withAutomaticReconnect(retryDelays: delaysInMilliSeconds)
        .configureLogging(hubProtLogger)
        .withHubProtocol(JsonHubProtocol())
        .build();
    return connection;
  }

it works with long polling but not websockets

@nayefradwi
Copy link
Author

nayefradwi commented Oct 31, 2022

After investigating this issue, It seems that the handshake request is being sent without the authorization header, which in the backend I am working with is required to establish the connection.

I tried to do something like this but still did not fix the issue

    MessageHeaders headers = MessageHeaders();
    headers.setHeaderValue(AuthInterceptor.authorizedHeader,
        "Bearer ${GetIt.I<ShopperApiClient>().accessToken}");
    HubConnection connection = HubConnectionBuilder()
        .withUrl(
          AppConfig.signalrUrl,
          options: HttpConnectionOptions(
            logger: transportProtLogger,
            logMessageContent: !AppConfig.isProd,
            headers: headers,
            skipNegotiation: true,
            requestTimeout: 120000,
            transport: HttpTransportType.WebSockets,
            accessTokenFactory: () async {
              String accessToken = GetIt.I<ShopperApiClient>().accessToken;
              return accessToken;
            },
          ),
        )
        .withAutomaticReconnect(retryDelays: delaysInMilliSeconds)
        .configureLogging(hubProtLogger)
        .withHubProtocol(JsonHubProtocol())
        .build();
    return connection;

I have noticed that the first request and the negotiation both have the access token in their headers, just the handshake request does not have it and this causes the error "The underlying connection was closed before the hub handshake could complete."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant