ASP.NET Framework下SSE接口如何在OnStreamAvailable中获取SessionID作字典键
解决方案
核心逻辑是在Index请求上下文未释放时提前捕获sessionId,通过闭包传递给异步回调OnStreamAvailable使用,具体修改步骤如下:
- 调整
OnStreamAvailable方法签名,新增sessionId入参,替换字典键生成逻辑
修改后的方法代码:
// 新增string sessionId入参 public async Task OnStreamAvailable(string sessionId, Stream stream, HttpContent headers, TransportContext context) { StreamWriter streamwriter = new StreamWriter(stream) { AutoFlush = true }; await streamwriter.WriteLineAsync($"event: info"); await streamwriter.WriteLineAsync($"data: Connected 😇\n\n"); await streamwriter.WriteLineAsync(); // 同session重复连接时先清理旧流,避免添加失败 if (_streams.TryRemove(sessionId, out var oldStream)) { try { oldStream.Close(); oldStream.Dispose(); } catch { } } // 用传入的sessionId作为键 _streams.TryAdd(sessionId, streamwriter); }
- 修改Index方法中
PushStreamContent的初始化逻辑,用lambda捕获本地的sessionId变量传入回调
修改后的Index方法代码:
[System.Web.Http.Route("SSE/")] [System.Web.Http.HttpGet] public HttpResponseMessage Index(HttpRequestMessage request) { var sessionId = HttpContext.Current.Session.SessionID; var response = request.CreateResponse(); response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add("Cache-Control", "no-cache, must-revalidate"); // 用lambda捕获sessionId,传递给OnStreamAvailable response.Content = new PushStreamContent((stream, headers, context) => OnStreamAvailable(sessionId, stream, headers, context), "text/event-stream"); return response; }
注意事项
- 你已经给控制器加了
[SessionState(SessionStateBehavior.ReadOnly)]特性,避免Session锁阻塞SSE长连接,符合使用要求 - 上述代码添加了同session旧连接的清理逻辑,避免同一个用户多次发起SSE连接时,新流无法存入字典的问题
内容的提问来源于stack exchange,提问作者zsubzwary
相关产品推荐
相关产品推荐

