HttpContext与HttpListenerContext AcceptWebSocketRequest无法强制转换

本文关键字:转换 HttpListenerContext AcceptWebSocketRequest HttpContext | 更新日期: 2024-10-22 01:19:42

我正在尝试使用HttpContextBaseHttpListenerHttpHandler之间共享代码。HttpContextWrapper已经提供了,但我必须制作自己的HttpListenerContextWrapper,这很容易,直到我到达AcceptWebSocketRequest。问题是HttpContextBase.AcceptWebSocketRequest中的回调类型是Func<AspNetWebSocketContext, Task>而不是Func<WebSocketContext, Task>,我很难在派生类中转换它。

public class HttpListenerContextWrapper : HttpContextBase
{
    private HttpListenerContext _context;
    public HttpListenerContextWrapper(HttpListenerContext context)
    {
        _context = context;
    }
    public override async void AcceptWebSocketRequest(Func<AspNetWebSocketContext, Task> callback)
    {
        // can't implicitly convert HttpListenerWebSocketContext to AspNetWebSocketContext..
        await callback(await _context.AcceptWebSocketAsync(null));
        // throws at runtime..
        await callback((AspNetWebSocketContext)(WebSocketContext)await _context.AcceptWebSocketAsync(null));
        // throws at runtime..
        await ((Func<WebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null));
        // throws at runtime..
        await ((Func<HttpListenerWebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null))
    }
    // no suitable method found to override..
    public override async void AcceptWebSocketRequest(Func<WebSocketContext, Task> callback)
    {

运行时异常总是:Unable to cast object of type Func<AspNetWebSocketContext,Task> to type Func<WebSocketContext,Task> ..at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__4

调用AcceptWebSocketRequest的代码类型为WebSocketContext,直接使用HttpContextHttpListenerContext时效果良好。有没有办法创建一个兼容的回调?或者有更好的方法来抽象HttpContextHttpListenerContext吗?

如果我复制HttpContextBase的代码并将类型更改为WebSocketContext,一切都会正常工作,但我不想在我的项目中保留HttpContextBaseHttpContextWrapper的屠宰副本。

edit:这是使用该方法的代码。

private async Task ProcessRequestAsync(HttpContextBase context)
{
    if (context.IsWebSocketRequest)
        await context.AcceptWebSocketRequest(HandleWebsocketRequest);
...
private async Task HandleWebsocketRequest(WebSocketContext context)
{
    ...

HttpContext与HttpListenerContext AcceptWebSocketRequest无法强制转换

如果要将Func<WebSocketContext, Task>传递到Func<AspNetWebSocketContext, Task>参数中,然后将其强制转换回Func<WebSocketContext, Task>,以便可以传递HttpListenerWebSocketContext,则需要在创建委托时具体说明该类型。

如果让编译器推断它将创建一个不能接受HttpListenerWebSocketContextFunc<AspNetWebSocketContext, Task>委托。

所以不是:

await context.AcceptWebSocketRequest(HandleWebsocketRequest);

您需要:

Func<WebSocketContext, Task> action = HandleWebsocketRequest;
await context.AcceptWebSocketRequest(action);

AcceptWebSocketRequest中,您需要将其投射回去:

await ((Func<WebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null));

但是,这是非常危险和糟糕的设计,因为callback参数的类型是Func<AspNetWebSocketContext, Task>,并且不能保证所有调用方都会发送Func<WebSocketContext, Task>而不是Func<AspNetWebSocketContext, Task>作为参数。