SignalR 连接适用于控制台应用程序,但不适用于 ReactJS

问题描述 投票:0回答:2

我的 ASP.NET 服务器上有以下相关代码:

// TrackingHub.cs
public class TrackingHub : Hub
{
    public async Task SendLocationData(LocationData locationData)
    {
        await Clients.Others.SendAsync("ReceiveLocationData", locationData);
        Console.WriteLine($"{locationData.Latitude}, {locationData.Longitude}");
    }
}

// Program.cs
builder.Services.AddSignalR()
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(builder =>
    {
        builder.WithOrigins("http://localhost:3000").AllowAnyHeader().AllowAnyMethod().AllowCredentials();
    });
});

//app.UseHttpsRedirection();
app.UseCors();
app.MapHub<TrackingHub>("/tracking");

现在在我的 .NET 控制台应用程序上,我有以下相关代码。它运行良好,我在我的 asp.net 服务器上收到了它的位置数据:

HubConnection? hubConnection = new HubConnectionBuilder()
     .WithUrl("http://localhost:5191/tracking")
     .Build();

// stuff...
if (hubConnection != null)
{
    await hubConnection.SendAsync("SendLocationData", locationData);
}

最后,这是我的 React (NextJS) 应用程序上的代码:

const page = () => {
    const connection = new HubConnectionBuilder()
        .withUrl('http://localhost:5191/tracking')
        .withAutomaticReconnect()
        .build()

    connection.on('ReceiveLocationData', (locationData) => {
        console.log(locationData)
    });

    useEffect(() => {
        const startConnection = async () => {
            try {
                await connection.start()
            }
            catch (error) {
                console.log("Failed to start connection: ", error)
            }
        }

        startConnection()
    }, []);

    return (
        <Map />
    )
}

但是,该连接不适用于 React 应用程序。请注意,从 React 应用程序到服务器的其他连接工作得很好(如常规 GET 或 POST 方法)。我还检查了工作控制台应用程序使用的传输类型,以查看 websocket 协议是否有效或受支持,并且它确实使用了 Websockets,我使用 [https://stackoverflow.com/questions/49473648/define- 检查]信号核心中的传输方法]。

这是我在控制台上得到的图像:

reactjs asp.net-core websocket signalr
2个回答
1
投票

在您的

next.config.js
文件中添加如下所示的代理设置。

/** @type {import('next').NextConfig} */

const nextConfig = [
    {
      context: [
        "/tracking"
     ],
      target: "http://localhost:5191", 
      changeOrigin: true,  
      logLevel: "debug",
      rejectUnauthorzied: true, 
      secure: false,            
      strictSSL: true,          
      withCredentials: true,
      // It is important
      ws: true
    }
  ]

module.exports = nextConfig

然后在我这边,我也更改了如下代码。

const connection = new signalR.HubConnectionBuilder()
  .withUrl("http://localhost:55377/mainhub", {
    skipNegotiation: true,
    transport: signalR.HttpTransportType.WebSockets
  })
  // we can enable client logging to check more details
  .configureLogging(signalR.LogLevel.Debug).build()

测试结果


0
投票

@JasonPan 的回答部分缓解了该问题(将

skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets
添加到客户端连接)。

但是,它并没有解决真正的问题,因为即使没有这些选项,连接也应该正常工作。我在 aspnetcore github 存储库上询问,他们建议这可能是因为我使用了一个名为“tracking”的端点和 adblock,就是这样 https://github.com/dotnet/aspnetcore/issues/49918。 因此,更改端点名称或禁用 adblock 即可使其正常工作,而无需添加

skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets

© www.soinside.com 2019 - 2024. All rights reserved.