客户端无法连接到 IIS 托管环境中 Blazor WebAssembly 应用 运行 的 SignalR 中心
Client cannot connect to SignalR hub of a Blazor WebAssembly app running on IIS hosting environment
我已经根据 This Tutorial 创建了一个 Blazor WebAssembly 解决方案。
索引页面(下面的代码,与教程相同):
- 适用于 VS2019 开发环境。
- 在我部署到 (machine2, Win10 pro) 的另一台 PC 上,页面 在 localhost:5000 上也能正常工作(如果我使用命令在 IIS 之外启动它网络AppName.dll)
- 但是在那台 PC(machine2)上,在托管 SignalR 的 IIS 上没有连接(页面在连接到 public URL 时加载,但是发送 SignalR 消息的按钮被禁用,因为 IsConnected 是假的,而且它真的断开连接了)。
- 具有相同代码(见底部代码)的 ConsoleApp,从机器 1 连接 到 public 没有问题] URL(在 machine2 上),证明 SignalR 集线器本身 运行 正确。
这是什么原因造成的?
如何调试客户端?
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
<div class="form-group">
<label>
User:
<input @bind="_userInput" />
</label>
</div>
<div class="form-group">
<label>
Message:
<input @bind="_messageInput" size="50" />
</label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>
<hr>
<ul id="messagesList">
@foreach (var message in _messages)
{
<li>@message</li>
}
</ul>
@code {
private HubConnection _hubConnection;
private List<string> _messages = new List<string>();
private string _userInput;
private string _messageInput;
protected override async Task OnInitializedAsync()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))
.Build();
_hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
var encodedMsg = $"{user}: {message}";
_messages.Add(encodedMsg);
StateHasChanged();
});
await _hubConnection.StartAsync();
}
Task Send() =>
_hubConnection.SendAsync("SendMessage", _userInput, _messageInput);
public bool IsConnected =>
_hubConnection.State == HubConnectionState.Connected;
}
下面是一个控制台应用程序,可以毫无问题地连接到 public signalR 集线器。
using System;
using Microsoft.AspNetCore.SignalR.Client;
namespace ConsoleSignalRDebug
{
class Program
{
static private HubConnection _hubConnection;
static void Main(string[] args)
{
try
{
_hubConnection = new HubConnectionBuilder()
.WithUrl("https://myblazorSite.com:443/chatHub")
.Build();
_hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{ Console.WriteLine("/////////////RECEIVED///////////////" + user + " " + message);});
_hubConnection.StartAsync().GetAwaiter().GetResult();
string x = Console.ReadLine();
_hubConnection.SendAsync("SendMessage", x, x);
Console.ReadLine();
}
catch (Exception e)
{
throw;
}
}
}
}
我试过这个用于调试,但它只在控制台上有效(无论如何都有效):
_hubConnection = new HubConnectionBuilder()
.WithUrl("https://myblazorSite.com:443/chatHub")
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Debug);
logging.AddConsole();
})
.Build();
WebSockets 在 IISExpress 上默认启用(用于本地测试),但在全功能 IIS 上默认禁用。
因此,当使用 WebSockets 部署应用程序时,例如 SignalR(或服务器端 Blazor),您需要在 IIS 上启用 WebSockets。
启用 IIS WebSocket 的说明位于 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-3.1#iisiis-express-support
我已经根据 This Tutorial 创建了一个 Blazor WebAssembly 解决方案。 索引页面(下面的代码,与教程相同):
- 适用于 VS2019 开发环境。
- 在我部署到 (machine2, Win10 pro) 的另一台 PC 上,页面 在 localhost:5000 上也能正常工作(如果我使用命令在 IIS 之外启动它网络AppName.dll)
- 但是在那台 PC(machine2)上,在托管 SignalR 的 IIS 上没有连接(页面在连接到 public URL 时加载,但是发送 SignalR 消息的按钮被禁用,因为 IsConnected 是假的,而且它真的断开连接了)。
- 具有相同代码(见底部代码)的 ConsoleApp,从机器 1 连接 到 public 没有问题] URL(在 machine2 上),证明 SignalR 集线器本身 运行 正确。
这是什么原因造成的? 如何调试客户端?
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
<div class="form-group">
<label>
User:
<input @bind="_userInput" />
</label>
</div>
<div class="form-group">
<label>
Message:
<input @bind="_messageInput" size="50" />
</label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>
<hr>
<ul id="messagesList">
@foreach (var message in _messages)
{
<li>@message</li>
}
</ul>
@code {
private HubConnection _hubConnection;
private List<string> _messages = new List<string>();
private string _userInput;
private string _messageInput;
protected override async Task OnInitializedAsync()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))
.Build();
_hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
var encodedMsg = $"{user}: {message}";
_messages.Add(encodedMsg);
StateHasChanged();
});
await _hubConnection.StartAsync();
}
Task Send() =>
_hubConnection.SendAsync("SendMessage", _userInput, _messageInput);
public bool IsConnected =>
_hubConnection.State == HubConnectionState.Connected;
}
下面是一个控制台应用程序,可以毫无问题地连接到 public signalR 集线器。
using System;
using Microsoft.AspNetCore.SignalR.Client;
namespace ConsoleSignalRDebug
{
class Program
{
static private HubConnection _hubConnection;
static void Main(string[] args)
{
try
{
_hubConnection = new HubConnectionBuilder()
.WithUrl("https://myblazorSite.com:443/chatHub")
.Build();
_hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{ Console.WriteLine("/////////////RECEIVED///////////////" + user + " " + message);});
_hubConnection.StartAsync().GetAwaiter().GetResult();
string x = Console.ReadLine();
_hubConnection.SendAsync("SendMessage", x, x);
Console.ReadLine();
}
catch (Exception e)
{
throw;
}
}
}
}
我试过这个用于调试,但它只在控制台上有效(无论如何都有效):
_hubConnection = new HubConnectionBuilder()
.WithUrl("https://myblazorSite.com:443/chatHub")
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Debug);
logging.AddConsole();
})
.Build();
WebSockets 在 IISExpress 上默认启用(用于本地测试),但在全功能 IIS 上默认禁用。
因此,当使用 WebSockets 部署应用程序时,例如 SignalR(或服务器端 Blazor),您需要在 IIS 上启用 WebSockets。
启用 IIS WebSocket 的说明位于 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-3.1#iisiis-express-support