webapi添加添加websocket中间件

添加位置

我按照MSDN的例子添加了一个复述客户端响应的中间件。需要注意的时,中间件采用那种方式添加,添加在哪。

  • 哪种方式
    我选择创建一条管道分支,只要时ws的连接请求,就转到这个分支
    因此,我们需要使用的是MapWhen()来创建管道分支。
  • 添加在哪
    要注意授权的问题,所以应该添加到授权中间件之后,也就是UseAuthorization()之后。
    至于是放在终结点之后,还是终结点之前,我认为都可以。

请求识别

添加websocket连接阶段也是采用的http请求,因此在添加webservice中间件之前,需要添加UseWebSockets()来识别ws请求。
这个中间件能够将context.WebSockets.IsWebSocketRequest变成true。而这个属性用来识别ws请求。

添加websocket中间件

我们在管道分支处判断一下这个请求是不是ws请求,是的话就进入分支app.MapWhen(c=>c.WebSockets.IsWebSocketRequest, appbuilder =>{})

/创建websocket管道分支,只有websocket连接请求进入这条分支
            app.MapWhen(c=>c.WebSockets.IsWebSocketRequest, appbuilder =>
            {
                //websocket连接授权中间件
                appbuilder.Use(async (context, next) =>
                {
                    if (context.User.Identity.IsAuthenticated == false)
                    {
                        context.Response.StatusCode = StatusCodes.Status403Forbidden;
                    }
                    else
                    {
                        await next(context);
                    }
                });
                //websocket连接建立中间件
                appbuilder.Use(async (context,next) =>
                {
                    await next(context);
                    //此方法将 TCP 连接升级到 WebSocket 连接,并提供 WebSocket 对象
                    using (var websocket = await context.WebSockets.AcceptWebSocketAsync())
                    {
                        var buffer = new byte[1024 * 4];
                        //阻塞式调用,接收到消息才会退出,同时把消息写到buffer中
                        var reciveResult = await websocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                        while (!websocket.CloseStatus.HasValue)
                        {
                            //复述客户端消息并发回
                            await websocket.SendAsync(new ArraySegment<byte>(buffer, 0, reciveResult.Count),
                                reciveResult.MessageType,
                                reciveResult.EndOfMessage,
                                CancellationToken.None);
                            reciveResult = await websocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                        }
                        await websocket.CloseAsync(
                            reciveResult.CloseStatus!.Value,
                            reciveResult.CloseStatusDescription,
                            CancellationToken.None);
                    }
                });
            });

当然我socket连接之前还添加了一个授权的中间件,如果不需要可以直接去除。

测试

image
由于我加了授权,所以这里还要加上请求头。如果没有授权就不需要加了。
image
可以看到,服务器复述了消息。

posted @ 2024-05-03 21:37  ggtc  阅读(141)  评论(0编辑  收藏  举报
//右下角目录