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连接之前还添加了一个授权的中间件,如果不需要可以直接去除。
测试
由于我加了授权,所以这里还要加上请求头。如果没有授权就不需要加了。
可以看到,服务器复述了消息。