你好,我有电话 ASP NET Core Middleware
使用 Websockets
以及 Redis Pub/Sub
. 用户通过websocket连接到服务器并:
进来的 websocket
消息通过 Pub/Sub
进来的 Redis
频道消息被写入 websocket
回到客户那里。
问题
现在,每当用户断开连接并重新连接时 Redis
消息处理程序方法引发异常,套接字状态为 Closed (Normal closure)
.
奇怪的是,重新连接的客户端中有它的websocket Open
直到消息发布到redis为止。然后代码抛出redis回调线程/任务,套接字处于 Closed
州。
因此,我得出结论,新的webocket是由服务器关闭的,而不是由客户端关闭的!
如何繁殖
-user connects
-user sends messages ( and gets them back via redis callback)
-user disconnects
-user reconnects
- code goes well until the user publishes the first message to redis at which point , the redis callback throws exception:
system.net.websockets.websocketexception:'远程方在未完成关闭握手的情况下关闭了websocket连接。'
内部异常:objectdisposedexception:无法写入响应主体,响应已完成。对象名称:“httpresponsestream”。
启动
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime) {
//connecting to redis
ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect("localhost:6379");
app.UseWebSockets();
app.Use(async (con,req) => {
if (!con.WebSockets.IsWebSocketRequest) {
await req();
}
//accepting ws
WebSocket socket = await con.WebSockets.AcceptWebSocketAsync();
ISubscriber subscriber = connectionMultiplexer.GetSubscriber();
//subscribing to redis channel
await subscriber.SubscribeAsync("mychannel",
async(chan,val) => await socket.SendAsync(Encoding.UTF8.GetBytes(val),
System.Net.WebSockets.WebSocketMessageType.Text,
true,
CancellationToken.None) //throws right here when user reconnects and publishes from the main Task the first message to redis
,CommandFlags.FireAndForget);
var database = connectionMultiplexer.GetDatabase();
byte[] buffer = new byte[1024];
//loop for publishing client ws messages to redis channel
while (true) {
WebSocketReceiveResult result=await socket.ReceiveAsync(buffer, CancellationToken.None);
if (result.MessageType == System.Net.WebSockets.WebSocketMessageType.Close) {
return;
}
var data = Encoding.UTF8.GetString(buffer[0..result.Count]);
await database.PublishAsync("mychannel", data);
}
});
}
p、 我100%确定客户端没有关闭套接字。我尝试过使用googlesimplewebsocket客户端和javascript客户端。
我想我在想 Redis
由提供的消息处理程序 ISubscriber
以某种方式关闭一个旧的套接字(其会话已结束)并将其重新用于一个新的客户端 Closed
州。
暂无答案!
目前还没有任何答案,快来回答吧!