我有一个工作的Blazor服务器应用程序,其中的聊天组件在本地正确运行,使用信号R集线器连接。
部署到Azure时,我收到错误“收到无效的协商响应"。---〉System.Text.Json.JsonReaderException:“0x 1F”是无效的值开头。
下面是一张类似的关联罚单,但从未得到回复:Blazor Server SignalR hub fails on StartAsync due to Azure ADB2C
目标:为Blazor服务器应用程序创建一个私人聊天功能。我不能使用单例服务,因为所有用户不能共享同一个服务示例。
我还没有找到blazor server中用户/用户组之间有消息传递功能的示例。
由于我使用的是带有OIDC默认身份验证方案的Azure B2C身份验证,因此我必须手动传递cookie和头。
就像我提到的,这个示例在localhost上运行得很好,当我打开两个浏览器(一个是匿名的)时,我可以在登录的用户之间发送消息。但是,当我发布到Azure应用服务时,我无法连接到集线器。
代码:
private HubConnection _hubConnection;
private User user;
ObservableCollection<Message> messages = new ObservableCollection<Message>();
SfTextBox MessageBox;
SfTextBox SendTo;
public class Message
{
public string Id { get; set; }
public string UserName { get; set; }
public string MessageText { get; set; }
public string Chat { get; set; }
}
protected override async Task OnInitializedAsync()
{
var state = await authenticationStateProvider.GetAuthenticationStateAsync();
user = state.ToUser();
_hubConnection = new HubConnectionBuilder()
.WithUrl(navigationManager.ToAbsoluteUri("/chatHub"), options =>
{
options.UseDefaultCredentials = true;
var httpContext = HttpContextAccessor.HttpContext;
var cookieCount = httpContext.Request.Cookies.Count();
var cookieContainer = new System.Net.CookieContainer(cookieCount);
foreach (var cookie in httpContext.Request.Cookies)
cookieContainer.Add(new System.Net.Cookie(
cookie.Key,
WebUtility.UrlEncode(cookie.Value),
path: httpContext.Request.Path,
domain: httpContext.Request.Host.Host));
options.Cookies = cookieContainer;
NameValueHeaderValue headers = null;
foreach (var header in httpContext.Request.Headers)
{
if (header.Key != ":method")
options.Headers.Add(header.Key, header.Value);
}
options.HttpMessageHandlerFactory = (input) =>
{
var clientHandler = new HttpClientHandler
{
PreAuthenticate = true,
CookieContainer = cookieContainer,
UseCookies = true,
UseDefaultCredentials = true,
};
return clientHandler;
};
})
.WithAutomaticReconnect()
.Build();
_hubConnection.On<string, string, string, string>("ReceiveMessage", (userName, from, to, message) =>
{
if (user.Email == to || user.Id == from)
{
messages.Add(new Message()
{
Id = Guid.NewGuid().ToString(),
MessageText = message,
Chat = user.Id == from ? "sender" : "receive",
UserName = user.Id == from ? "You" : userName
});
StateHasChanged();
}
});
await _hubConnection.StartAsync();
}
public async void Send()
{
if (MessageBox.Value != "" && SendTo.Value != "")
{
var userName = user.DisplayName;
var to = SendTo.Value;
var message = MessageBox.Value;
var from = user.Id;
_hubConnection.SendAsync("SendMessage", userName, from, to, message);
}
}
public bool IsConnected => _hubConnection.State == HubConnectionState.Connected;
}
2条答案
按热度按时间gmxoilav1#
问题是Azure平台上的身份验证。由于您使用手动提供Cookie,因此它在本地运行良好,而在Azure平台上,我们需要提供身份验证。
点击以下链接获取支持。
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-invalid-json?pivots=dotnet-6-0
https://learn.microsoft.com/en-us/azure/azure-signalr/signalr-tutorial-build-blazor-server-chat-app
j8yoct9x2#
我在这里发布了一个解决方案:Solution: Custom SignalR Endpoints (Hubs) in a Blazor Server Application using Azure B2C When Deployed to Azure
基本上:
此时抓取所有Cookie,并将其放入Cookie集合中,以便将其传递给app. razor控件。
将它们设置为将传递给所有其他Blazor控件的CascadingValue。检索Cookie集合作为CascadingParameter,并在创建SignalR客户端时使用这些Cookie手动设置Header和Cookie。