簡體   English   中英

將 NodeJS 應用程序連接到 SignalR(使用 .NET Core 3)

[英]Connecting NodeJS app to SignalR (with .NET Core 3)

我有一台使用 .NET Core 3 運行 SignalR 的服務器。該項目是從模板開始的,我遵循了指南( https://docs.microsoft.com/en-gb/aspnet/core/tutorials/signalr?tabs=visual -studio&view=aspnetcore-3.0 )。

我已經創建了該項目的克隆,並且可以成功連接到服務器並可以按預期接收消息。 這也意味着我添加了 CORS。

我希望能夠在 Node JS 環境中使用 SignalR,但連接停留在“協商”我創建了一個全新的文件夾,運行npm init -ynpm i @microsoft/signalr 創建了一個名為main.js的新 js 文件,如下所示:

const signalR = require("@microsoft/signalr");

let connection = new signalR.HubConnectionBuilder()
    .withUrl("http://localhost:44336/chathub")
    .configureLogging(signalR.LogLevel.Trace)
    .build();

connection.on("send", data => {
    console.log(data);
});

connection.start()
    .then(() => connection.invoke("send", "Hello"));

使用node main.js運行它后,我在控制台中收到以下錯誤

[2019-11-26T14:56:14.933Z] Debug: Starting HubConnection.
[2019-11-26T14:56:14.935Z] Debug: Starting connection with transfer format 'Text'.
[2019-11-26T14:56:14.936Z] Debug: Sending negotiation request: http://localhost:44336/chathub/negotiate.
[2019-11-26T14:58:18.890Z] Warning: Error from HTTP request. Error: read ECONNRESET
[2019-11-26T14:58:18.891Z] Error: Failed to complete negotiation with the server: Error: read ECONNRESET
[2019-11-26T14:58:18.892Z] Error: Failed to start the connection: Error: read ECONNRESET
[2019-11-26T14:58:18.892Z] Debug: HubConnection failed to start successfully because of error 'Error: read ECONNRESET'.

好像超時了。 服務器、客戶端和 nodejs 應用程序都在本地托管。 我確保檢查使用npm i安裝的信號器版本是否與服務器版本(3.0.1)匹配。 我什至在 node_modules 中提取了 js 文件並將它們用於另一個客戶端(使用 VS 模板制作),它可以正常連接。

我不知道如何進一步調試。 我嘗試使用 VS 連接到服務器,但無法獲取任何信息。 服務器使用 IIS Express(通過 Visual Studio 啟動)托管。 關於如何進一步調試的任何提示? 否則我可能會使用另一個信號器版本降級到以前的 .NET Core 版本

我在 VS 中的 startup.cs 代碼

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddControllersWithViews();

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAll",
                    builder =>
                    {
                        builder
                            .WithOrigins("http://localhost:44399", "http://localhost:44336", "https://localhost:44399", "https://localhost:44336")
                            .AllowCredentials()
                            .AllowAnyMethod()
                            .AllowAnyHeader();
                    });
            });

            services.AddSignalR();
        }

        // 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.UseCors("AllowAll");
            app.UseEndpoints(endpoints =>
                {
                    endpoints.MapHub<ChatHub>("/chathub");
                });
        }
    }

不知道這是否是根本原因,但我在我的設置中偶然發現了這一點。

Visual Studio 中 IISExpress 的默認設置不會在同一端口上偵聽httphttps 我在 node.js 文件中使用 SSL 端口,但使用http協議。 我懷疑您的問題可能是相同的,因為 VS 通常默認為 SSL 端口的 44000 范圍。

令我困惑的是,我的瀏覽器在調試期間會在 SSL 端口上彈出。

就我而言,我檢查了./Properties/launchSettings.json以獲取正在使用的端口:

  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:63591",
      "sslPort": 44357
    }
  },

然后相應地更新了我的 js 文件:

const signalR = require("@microsoft/signalr");

var hubConnection = new signalR.HubConnectionBuilder()
    .configureLogging(signalR.LogLevel.Trace)
    .withUrl("http://localhost:63591/chatHub")
    .build();

瞧。 在 Visual Studio 2019 中運行應用程序,然后在命令行上運行:

davek-win64% node app.js
[2020-08-05T21:20:15.483Z] Debug: Starting HubConnection.
[2020-08-05T21:20:15.490Z] Debug: Starting connection with transfer format 'Text'.
[2020-08-05T21:20:15.491Z] Debug: Sending negotiation request: http://localhost:63591/chatHub/negotiat
e.
[2020-08-05T21:20:15.591Z] Debug: Selecting transport 'WebSockets'.
[2020-08-05T21:20:15.592Z] Trace: (WebSockets transport) Connecting.
[2020-08-05T21:20:15.615Z] Information: WebSocket connected to ws://localhost:63591/chatHub?id=sYmFd19
_rNCR7q3mddpJBA.
[2020-08-05T21:20:15.616Z] Debug: The HttpConnection connected successfully.
[2020-08-05T21:20:15.616Z] Debug: Sending handshake request.
[2020-08-05T21:20:15.619Z] Trace: (WebSockets transport) sending data. String data of length 32.
[2020-08-05T21:20:15.621Z] Information: Using HubProtocol 'json'.
[2020-08-05T21:20:15.633Z] Trace: (WebSockets transport) data received. String data of length 3.
[2020-08-05T21:20:15.634Z] Debug: Server handshake complete.
[2020-08-05T21:20:15.635Z] Debug: HubConnection connected successfully.
Connected!
[2020-08-05T21:20:28.547Z] Trace: (WebSockets transport) data received. String data of length 74.
stackoverflow test
[2020-08-05T21:20:30.637Z] Trace: (WebSockets transport) sending data. String data of length 11.
[2020-08-05T21:20:31.197Z] Trace: (WebSockets transport) data received. String data of length 11.

你應該考慮你的中間件順序

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("AllowAll",
            builder =>
            {
                builder
                    .WithOrigins("http://localhost:44399",
                        "http://localhost:44336",
                        "https://localhost:44399",
                        "https://localhost:44336")
                    .AllowCredentials()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
            });
    });

    services.AddSignalR();
    services.AddControllersWithViews();
}

試試這個,看看它是否適合你。 你可以在這里參考我的另一個答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM