redis发布/订阅回调中websocket无故关闭

b0zn9rqh  于 2021-06-07  发布在  Redis
关注(0)|答案(0)|浏览(262)

你好,我有电话 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 州。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题