应该可以在经典的 ASP.NET Forms 应用程序中处理 Web 套接字连接。这些工具在HttpContext 上可用,您基本上有正确的想法。
我认为问题在于您试图从 aspx 页面调用它,而不仅仅是使用通用 IHttpHandler。 IIS 基于文件扩展名运行特定的处理管道。 Aspx 专门用于尝试呈现 HTML 页面,因此虽然可以重新配置 IIS 以允许 websockets 与 ASPX 页面交互,但使用通用 ashx 更容易 处理程序。
您可以通过转到 Visual Studio 中的“添加项目”对话框来创建处理程序
此时,您只需在处理程序代码中实现您的 websocket 逻辑。我在this aspnet sample 中添加一个简单的回声只是为了演示。
public class MyHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(EchoWebSocket);
}
}
private async Task EchoWebSocket(AspNetWebSocketContext socketContext)
{
var buffer = new byte[1024 * 4];
var result = await socketContext.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await socketContext.WebSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await socketContext.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await socketContext.WebSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
public bool IsReusable
{
get
{
return false;
}
}
}
您现在应该能够连接到 websocket。注意wss 的用法,而不是ws。我测试的设置需要安全版本(wss)。使用与您正在处理的应用程序相关的任何内容。
// Replace with port/path to your handler.
var ws = new WebSocket("wss://localhost:44336/MyHandler.ashx");
ws.onmessage = function(evt) {
console.log(evt);
};
ws.send("Hello, World!");
您应该会看到与此类似的输出:
注意:我通常不建议尝试从 websocket 处理程序访问 Session 数据。您的会话可能会在 websocket 的生命周期之外过期。您可能希望使用其他机制在套接字和其余页面(可能是数据库或应用程序级缓存,您可以在上面的示例中从socketContext.Cache 访问)之间保持状态。
编辑:添加了在套接字初始化时使用会话值的示例。
根据您的评论,如果您想在 websocket 的 初始化 期间使用会话值(这应该是一个安全的操作),那么您的处理程序只需要实现 IRequiresSessionState 并需要添加一些额外的将会话值传递给接受处理程序的语法。
public class MyHandler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
var sessionValue = context.Session["session_key"] as string;
context.AcceptWebSocketRequest(async (socketContext) =>
{
await SetupWebSocket(socketContext, sessionValue);
});
}
}
private async Task SetupWebSocket(AspNetWebSocketContext socketContext, string sessionValue)
{
// Handle socket as before, but 'sessionValue' is now available for use.
}
public bool IsReusable
{
get
{
return false;
}
}
}