基于webapi的websocket聊天室(三)

news/2024/9/27 5:43:47

上一篇处理了超长消息的问题。我们的应用到目前为止还是单聊天室,这一篇就要处理的多聊天室的问题。

思路

  • 第一个问题,怎么访问不同聊天室

这个可以采用路由参数来解决。我把路由设计成这样/chat/{room}。访问不同路径就代表进入不同聊天室。

  • 第二个问题,怎么创建不同的聊天室

原来的聊天室是单例注入到主机的。因此,多聊天室就不能使用单例了。
我们可以使用一个聊天室工厂,根据路由参数来创建或返回已有的聊天室。而这个工厂需要保存已有的聊天室,所以聊天室工厂需要是单例的。
多聊天室情况下,每个聊天室有个名字还是有必要的

//WebSocketChatRoom.cspublic string roomName { get; set; }

实现

聊天室工厂

  • 工厂类
//ChatRoomFactory.cs/// <summary>
/// 聊天室工厂
/// </summary>
public class ChatRoomFactory
{public ConcurrentDictionary<string, WebSocketChatRoom> _rooms;/// <summary>/// WebSocketChatRoom工厂/// </summary>/// <param name="createDelegate">在注册配置WebSocketChatRoom的构造委托</param>public ChatRoomFactory(Func<WebSocketChatRoom> createDelegate){CreateDelegate = createDelegate;_rooms = new ConcurrentDictionary<string, WebSocketChatRoom>();}private Func<WebSocketChatRoom> CreateDelegate { get; }public WebSocketChatRoom GetRoom(string path){            if (_rooms.TryGetValue(path ,out WebSocketChatRoom socketroom)) {return socketroom;}else{var newRoom = CreateDelegate();newRoom.roomName = path;this._rooms.TryAdd(path, newRoom);return newRoom;}}
}
  • 注册工厂
//program.cs//添加聊天室服务(不需要了)
//builder.Services.AddSingleton<WebSocketChatRoom>();
//添加聊天室工厂
builder.Services.AddSingleton<ChatRoomFactory>((provider) =>
{return new ChatRoomFactory(() =>{return new WebSocketChatRoom();});
});

中间件改造

改造的点有两个

  • 使用的服务从WebSocketChatRoom改为ChatRoomFactory
  • 判断路由参数
//WebSocketChatRoomMiddleware.cspublic class WebSocketChatRoomMiddleware
{private readonly RequestDelegate _next;public WebSocketChatRoomMiddleware(RequestDelegate next, Func<ChatRoomFactory> handler){_next = next;Handler = handler;}public Func<ChatRoomFactory> Handler { get; }public async Task InvokeAsync(HttpContext context){await _next(context);WebSocket client = await context.WebSockets.AcceptWebSocketAsync();var room = Handler().GetRoom(context.Request.Path.Value.Trim('/')?.ToString() ?? "defaultRoom");await room.HandleContext(context, client);}
}
//WebSocketChatRoomMiddlewareExtensions.cspublic static class WebSocketChatRoomMiddlewareExtensions
{public static WebApplication UseWebSocketChatRoomMiddleware(this WebApplication builder){//建立websocket分支builder.MapWhen(c => c.WebSockets.IsWebSocketRequest, appbuilder =>{//授权appbuilder.Use(async (context, next) =>{if (context.User.Identity.IsAuthenticated)await next(context);elsecontext.Response.StatusCode = StatusCodes.Status403Forbidden;}).Map("/chat", roombranch =>{roombranch.UseMiddleware<WebSocketChatRoomMiddleware>(new Func<ChatRoomFactory>(() =>{return roombranch.ApplicationServices.GetRequiredService<ChatRoomFactory>();}));});});return builder;}
}

聊天室改造

聊天室基本不用改。这里为了明确不同聊天室,就在加入广播和退出广播中加上聊天室名字吧

//WebSocketChatRoom.cs//广播游客加入聊天室
CascadeMeaasge(null, $"{roomName}: {visitor.Name}加入聊天室");
...
//广播游客退出
CascadeMeaasge(visitor,$"{roomName}: {visitor.Name}退出聊天室");

测试

这里列出每个游客聊天截图,还是用的ApiPost来测的。
image

image

image

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/30559.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

越权漏洞(Pikachu)

原理 该漏洞是指应用在检查授权时存在纰漏,使得攻击者在获得低权限用户账户后,利用一些方式绕过权限检查,访问或者操作其他用户或者更高权限。越权漏洞的成因主要是因为开发人员在对数据进行增、删、改、查询时对客户端请求的数据过分相信而遗漏了权限的判定,一旦权限验证不…

同单元格内计算加号个数

问题:一个单元格内若干个加号,计算其个数 函数公式解决:传统套路 =LEN(A2)-LEN(SUBSTITUTE(A2,"+",)) 新套路 =COUNTA(TEXTSPLIT(A2,"+"))-1 正则套路 =COUNTA(REGEXP(A2,"[^+]"))-1

rdp利用技巧总结

近期在项目中管理员在rdp挂载之后搞掉了管理员,想着有时间就整理下针对rdp的利用方法。针对挂盘的利用方法复制文件这个不多说,可以根据的不同的挂盘来决定是拖文件还是放启动项。有一些自动文件监控和拷贝的应用,如:https://github.com/cnucky/DarkGuardianDarkGuardian是一…

小小redis持久化,拿捏

前言 我们先来说说什么是持久化持久化顾名思义就是数据长久保存,Redis为什么需要持久化呢,好呆的问题,Redis数据是存储在内存中的,内存数据的特点就是一旦重启就什么都没了我们将文件由内存中保存到硬盘中的这个过程,我们叫做数据保存,也就叫做持久化。但是把它保存下来不…

表格结构转换(Power Query)

问题:左表转成右表let源 = Excel.CurrentWorkbook(){[Name="表1_5"]}[Content],添加公司名列 = Table.TransformColumns(Table.ExpandTableColumn(Table.Group(源, {"件号"}, {"内容", each Table.AddIndexColumn(_,"公司名",1)}), &…

实战中内网穿透的打法

前言在内网渗透时,一个WebShell或CobaltStrike、Metasploit上线等,只是开端,更多是要内网横向移动,扩大战果,打到核心区域。但后渗透的前提是需要搭建一条通向内网的“专属通道”,才能进一步攻击。可实战中因为网络环境不同,所利用的方式就不同。以下为自我总结“实战中…

Linksys MAX-STREAM AC2600 / Linksys EA8100 固件资源整合分享

注意:这款路由默认地址为192.168.10.1 初始化时选手动安装!!!官方固件 https://www.linksys.com/support-article?articleNum=49022 升级教程: https://linksys-sh.com/home-ea8100/firmware-update-ea8100 (适用于官方固件和Openwrt固件) 转存 V1 Firmware for StarHub(St…

MIT6S081课程笔记

MIT6S081 课程笔记 mit6s081 lecture notes Created: 2023-06-05T20:26+08:00 Published: 2024-05-12T12:13+08:00 Categories: OperatingSystem 关于这门课程使用到的资料:schedule: https://pdos.csail.mit.edu/6.S081/2020/schedule.html schedule 可以认为提供了资源(如 …