WebSocket 未处于 OPEN 状态

WebSocket is not in the OPEN state

我正在 ASP.NET Core 上试用 SignalR。它在 VisaulStudio 调试器中运行良好运行。

但是它在部署的代码中不起作用,显示错误消息 "WebSocket is not in the OPEN state" 和 "Handshake was canceled"。问题的可能原因是什么?

Google Chrome

上的网络控制台
WebSocket is not in the OPEN state (kms-event-exit.js:12)
Uncaught Error: Seerver returned handshake error: Handshake was canceled. (signalr.min.js:16)
 at HubConnection.processHandshakeResponse (signalr.min.js:16)
 at HubConnection.processIncomingData (signalr.min.js:16)
 at WebSocketTransport.HubConnection.connection.onreceive (signalr.min.js:16)
 at WebSocket.webSocket.onmessag (signalr.min.js:16)
[2019-04-06T01:06:41.965Z] Error: Connection disconnected with error 'Error: Server returned handshake error: Handshake was canceled.'. signalr.min.js:16
Uncaught (in promise) Server returned handshake error: Handshake was canceled. (signalr.min.js:16)

启动函数。

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddRazorOptions(options => options.AllowRecompilingViewsOnFileChange = true);

        services.AddSignalR(options => options.EnableDetailedErrors = true);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseDeveloperExceptionPage();
        if (!env.IsDevelopment())
        {
            //app.UseExceptionHandler("/Home/Main");
            app.UseHsts();
        }

        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseSignalR(routes =>
        {
            routes.MapHub<Hubs.KmsHub>("/KmsHub");
            routes.MapHub<Hubs.AllResetHub>("/AllResetHub");
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "areaDefault",
                template: "{area:exists}/{controller=Home}/{action=Main}/{id?}");

            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Main}/{id?}/{exit?}");
        });
    }

日志

dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionDispatcher[4]
      Establishing new connection.
dbug: Microsoft.AspNetCore.SignalR.HubConnectionHandler[5]
      OnConnectedAsync started.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.Transports.WebSocketsTransport[1]
      Socket opened using Sub-Protocol: '(null)'.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/favicon.ico
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
      Sending file. Request path: '/favicon.ico'. Physical path: 'D:\K4\KMS\KMS\bin\Release\netcoreapp2.2\publish\wwwroot\favicon.ico'
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 6.664ms 200 image/x-icon
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/lib/Popper/popper.min.js.map
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 3.4573ms 404
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/lib/bootstrap/dist/js/bootstrap.min.js.map
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/lib/signalr/dist/browser/signalr.min.js.map
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 2.3443ms 404
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
      Sending file. Request path: '/lib/bootstrap/dist/js/bootstrap.min.js.map'. Physical path: 'D:\K4\KMS\KMS\bin\Release\netcoreapp2.2\publish\wwwroot\lib\boo
tstrap\dist\js\bootstrap.min.js.map'
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 114.858ms 200 text/plain
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/lib/bootstrap/dist/css/bootstrap.min.css.map
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
      Sending file. Request path: '/lib/bootstrap/dist/css/bootstrap.min.css.map'. Physical path: 'D:\K4\KMS\KMS\bin\Release\netcoreapp2.2\publish\wwwroot\lib\b
ootstrap\dist\css\bootstrap.min.css.map'
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 18.0356ms 200 text/plain
dbug: Microsoft.AspNetCore.SignalR.HubConnectionContext[2]
      Handshake was canceled.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.Transports.WebSocketsTransport[7]
      Waiting for the client to close the socket.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.Transports.WebSocketsTransport[2]
      Socket closed.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionManager[2]
      Removing connection 8K2CDgDs6jWXM7DPMWk_Dg from the list of connections.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 15047.5227ms 101

JavaScript 捕获异常的代码。

function kmsEventExit(url) {
    var exitButton = document.getElementById("exitButton");
    var connection = new signalR.HubConnectionBuilder().withUrl(url + "/KmsHub").build();

    //Disable send button until connection is established
    exitButton.disabled = true;

    //Wait until connection finishes.
    connection.start().then(function () {
        exitButton.disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());   //WebSocket is not in the OPEN state
    });

    //Call ExitKms on clicking the button.
    exitButton.addEventListener("click", function (event) {
        connection.invoke("ExitKms").catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });

    //Catch the result.
    connection.on("ExitKmsResult", function (isAlert, options) {
        if (isAlert) {
            swal(JSON.parse(options));
        }
    });
}

我找到问题了!

它不起作用,因为 pace.js 与 signalr.js 不兼容。 WebSocket 变量在这两个插件中重复。删除 pace.js.

后 SignalR 工作正常

VisualStudio 上的 SignalR 与 pace.js 一起工作,因为它使用 SSE 和 IIS Express,而不是 WebSocket 和 Kestrel,因此 pace.js 和 signalr.js 可以与此特定配置兼容。

参考: https://github.com/aspnet/SignalR/issues/2389

根据 OP 在他的回复中提供的相同 URL,已对对我有用的问题进行了更新(解决方法)。

连接前,添加:

Object.defineProperty(WebSocket, 'OPEN', { value: 1, });

感谢:https://github.com/aspnet/SignalR/issues/2389#issuecomment-393760284

这样,我就不必删除 pace.js。

如上所述,pace 和 signalr 不直接兼容,但是在加载之前将脚本放在下面 pace.js 将解决问题而不是完全删除 pace.js

<script>
            window.paceOptions = { ajax: { ignoreURLs: ['mainHub', '__browserLink', 'browserLinkSignalR'], trackWebSockets: false } }
        </script>

Reference to above answer:

'mainHub' 的值是您正在连接的 C# 应用程序中的 signalR 集线器。