SignalR Asp.netcore and angular ( WebSocket is not in the OPEN state) disconnection for signalR.HttpTransportType.WebSockets
Asked Answered
M

1

1

Using .NET Core 2.2 and Angular 8 with package "@aspnet/signalr": "^1.1.4". I have set up a hub in .NET Core 2.2 which works fine with another Angular project using the same package.

Startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SignalrChat.Services;

namespace SignalrChat
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
            {
                builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed(_ => true)
                .AllowCredentials();
            }));
            services.AddSignalR();
            services.AddSingleton<IChatRoomService, InMemoryChatRoomService>();
            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseCors("CorsPolicy");
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapHub<ChatHub>("/chat");
            });
        }
    }
}

Hub:

using Microsoft.AspNetCore.SignalR;
using SignalrChat.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SignalrChat
{
    public class ChatHub : Hub
    {}
}

Angular:

import * as signalR from "@aspnet/signalr";
import {
  Component, Inject, OnInit
} from '@angular/core';

import { DeviceDetectorService } from 'ngx-device-detector';
import { DOCUMENT } from '@angular/common';
import { Router } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
    ngOnInit(): void {
        this.hub = new signalR.HubConnectionBuilder()
            .configureLogging(signalR.LogLevel. Trace)
        .withUrl('http://localhost:56328/chat')
        
            .build();

        this.hub.serverTimeoutInMilliseconds = 100000;
        this.hub.keepAliveIntervalInMilliseconds = 100000;
        this.hub
            .start()
            .then(() => {  
                console.log('Connection started!');
                console.log('Getting all rooms');  

            })
            .catch(err => {
                console.log(err);
                console.log(this.hub);
                
            });
    }
}

Here is the log for hub.start() from Angular project that works fine:

[2019-12-31T11:43:30.214Z] Debug: Starting HubConnection.
Utils.js:213 [2019-12-31T11:43:30.215Z] Debug: Starting connection with transfer format 'Text'.
Utils.js:213 [2019-12-31T11:43:30.220Z] Debug: Sending negotiation request: http://localhost:56328/chat/negotiate.
Utils.js:213 [2019-12-31T11:43:31.382Z] Debug: Selecting transport 'WebSockets'.
client:52 [WDS] Live Reloading enabled.
Utils.js:209 [2019-12-31T11:43:32.001Z] Information: WebSocket connected to ws://localhost:56328/chat?id=NafCuVY_brPNmqQlN2EvXw.
Utils.js:213 [2019-12-31T11:43:32.003Z] Debug: Sending handshake request.
Utils.js:209 [2019-12-31T11:43:32.006Z] Information: Using HubProtocol 'json'.
Utils.js:213 [2019-12-31T11:43:32.053Z] Debug: Server handshake complete.

But for the other angular project with the exact same code and package to the same hub, it cannot proceed. Here is the log:

[2019-12-31T11:41:35.294Z] Debug: Starting HubConnection.
Utils.js:213 [2019-12-31T11:41:35.639Z] Debug: Starting connection with transfer format 'Text'.
Utils.js:213 [2019-12-31T11:41:35.644Z] Debug: Sending negotiation request: http://localhost:56328/chat/negotiate.
core.js:16829 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
Utils.js:213 [2019-12-31T11:41:36.574Z] Debug: Selecting transport 'WebSockets'.
WebSocket connection to 'ws://localhost:4200/sockjs-node/694/1skccdzm/websocket' failed: WebSocket is closed before the connection is established.
[2019-12-31T11:41:38.814Z] Information: WebSocket connected to ws://localhost:56328/chat?id=qO3s36husX9-boU1SwyaBg.
Utils.js:213 [2019-12-31T11:41:38.820Z] Debug: Sending handshake request.
app.component.ts:34 WebSocket is not in the OPEN state

I tried to change all the packages of the "not-wroking angular" to the same as the "working-angular", the problem still remains.

UPDATE

I found out that changing http transport mode of signalR.HubConnectionBuilder() will get it worked as below:

var options = {
    transport: signalR.HttpTransportType.ServerSentEvents ,
    logging: signalR.LogLevel.Trace, 
};
this.hub = new signalR.HubConnectionBuilder()
    //.withUrl('http://localhost:56328/chat' , options)
    .withUrl('http://localhost:49941/chat', options) 
    .build();

ServerSentEvent is successful, yet the websocket and longpolling modes are not.

Merchant answered 31/12, 2019 at 11:54 Comment(4)
If you browse these two angular apps from same client, does also one work and another not work with websocket and longpolling transport?Odericus
And please check if the issue is caused by zone.js.Odericus
@ Fei Han : Thanks for the reply, yes im having both angular apps on my computer, one works with websocket, the other one one works with serverSentEvent.Merchant
@ Fei Han : same computer*Merchant
M
4

Thanks to @Fei Han for mentioning this useful solution: it worked when i changed my code to this:

 Object.defineProperty(WebSocket, 'OPEN', { value: 1, }); 
        this.hub
            .start()
            .then(() => {                     
                console.log('Connection started!');         

            })
            .catch(err => {
                console.log(err);                     
            });
Merchant answered 1/1, 2020 at 7:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.