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

思路

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

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

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

原来的聊天室是单例注入到主机的。因此,多聊天室就不能使用单例了。

我们可以使用一个聊天室工厂,根据路由参数来创建或返回已有的聊天室。而这个工厂需要保存已有的聊天室,所以聊天室工厂需要是单例的。

多聊天室情况下,每个聊天室有个名字还是有必要的

//WebSocketChatRoom.cs

public 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.cs

public 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.cs

public 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);
else
context.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来测的。

基于webapi的websocket聊天室(三)的更多相关文章

  1. 基于springboot的websocket聊天室

    WebSocket入门 1.概述 1.1 Http #http简介 HTTP是一个应用层协议,无状态的,端口号为80.主要的版本有1.0/1.1/2.0. #http1.0/1.1/2.0 1.HTT ...

  2. 基于flask的网页聊天室(三)

    基于flask的网页聊天室(三) 前言 继续上一次的内容,今天完成了csrf防御的添加,用户头像的存储以及用户的登录状态 具体内容 首先是添加csrf的防御,为整个app添加防御: from flas ...

  3. 使用.NET Core和Vue搭建WebSocket聊天室

    博客地址是:https://qinyuanpei.github.io.  WebSocket是HTML5标准中的一部分,从Socket这个字眼我们就可以知道,这是一种网络通信协议.WebSocket是 ...

  4. Netty之多用户的聊天室(三)

    Netty之多用户的聊天室(三) 一.简单说明 笔者有意将Netty做成一个系列的文章,因为笔者并不是一个善于写文章的人,而且笔者学习很多技术一贯的习惯就是敲代码,很多东西敲着敲着就就熟了,然后再进行 ...

  5. Netty入门(一)之webSocket聊天室

    一:简介 Netty 是一个提供 asynchronous event-driven (异步事件驱动)的网络应用框架,是一个用以快速开发高性能.高可靠性协议的服务器和客户端. 换句话说,Netty 是 ...

  6. 基于flask的网页聊天室(四)

    基于flask的网页聊天室(四) 前言 接前天的内容,今天完成了消息的处理 具体内容 上次使用了flask_login做用户登录,但是直接访问login_requare装饰的函数会报401错误,这里可 ...

  7. 用Java构建一个简单的WebSocket聊天室

    前言 首先对于一个简单的聊天室,大家应该都有一定的概念了,这里我们省略用户模块的讲解,而是单纯的先说说聊天室的几个功能:自我对话.好友交流.群聊.离线消息等. 今天我们要做的demo就能帮我们做到这一 ...

  8. websocket聊天室

    目录 websocket方法总结 群聊功能 基于websocket聊天室(版本一) websocket方法总结 # 后端 3个 class ChatConsumer(WebsocketConsumer ...

  9. WebSocket聊天室demo

    根据Socket异步聊天室修改成WebSocket聊天室 WebSocket特别的地方是 握手和消息内容的编码.解码(添加了ServerHelper协助处理) ServerHelper: using ...

  10. 基于flask的网页聊天室(二)

    基于flask的网页聊天室(二) 前言 接上一次的内容继续完善,今天完成的内容不是很多,只是简单的用户注册登录,内容具体如下 具体内容 这次要加入与数据哭交互的操作,所以首先要建立相关表结构,这里使用 ...

随机推荐

  1. 虚实相生,构建数智生活|HMS Core. Sparkle应用创新分论坛报名启动

    XR技术的发展,为用户带来了全新的体验模式.那么,作为支撑XR发展主要学科之一的图形学,将迎来哪些发展新机遇?移动应用开发者,该如何拥抱3D数字化转型? 7月15日,HDD·HMS Core. Spa ...

  2. Linux 编译 libjpeg-9e

    jpeg的库有两个:一个是官方的 libjpeg  还有一个是 libjpeg-turbo JPEG库(libjpeg-turbo):https://libjpeg-turbo.org/ Libjpe ...

  3. 什么是MurmurHash

    MurmurHash简介 MurmurHash是一种非加密散列函数,名称来自两个基本操作,乘法(MU)和旋转(R).与加密散列函数不同,它不是专门设计为难以被对手逆转,因此不适用于加密目的.在2018 ...

  4. 重新整理 .net core 实践篇——— 测试控制器[四十九]

    前言 其实就是官方的例子,只是在此收录整理一下. 正文 测试控制器测试的是什么呢? 测试的是避开筛选器.路由.模型绑定,就是只测试控制器的逻辑,但是不测试器依赖项. 代码部分: https://git ...

  5. 重新点亮linux 命令树————文件权限和目录权限[九]

    前言 简单整理一下文件权限和目录权限. 正文 当打开ls -al的时候会出现相关的权限信息. 那么上面文件类型包括: 普通文件 d 目录文件 b 块特殊文件 (设备,比如u盘) c 字符特殊文件 (终 ...

  6. 批处理 if的知识点

    正文 批处理的if不同于我们在一些常规语言中的if,比如说c或者c# 或者 java等. 如果我们判断两个字符是否相等,我们使用 'a'=='a' 来判断. 但是如果是不相等却不能这样. gtr 大于 ...

  7. 重新整理数据结构与算法(c#)——算法套路贪心算法[二十八]

    前言 贪心算法,记得学的时候还是大学的时候,再次来总结一下吧. 贪心算法并不是指具体的固定代码,而是指一种思路,加入我们每次都选最好的选择,那么很大可能会得到最好的结果. 题目: 正文 思路,加入把k ...

  8. 远程主机可能不符合glibc和libstdc++ VS Code服务器的先决条件

    报错信息 VSCode无法连接远程服务器,终端一直提醒: [22:46:01.906] > Waiting for server log... [22:46:01.936] > Waiti ...

  9. .Net core 3.0 SignalR+Vue 实现简单的IM(无jq依赖)

    .Net core 中的SignalR JavaScript客户端已经不需要依赖Jquery了 一.服务端 1.nuget安装 Microsoft.AspNetCore.SignalR2.在start ...

  10. python pickle模块,打包创建的对象,做持久化

    pickle提供了一个简单的持久化功能.可以将对象以文件的形式存放在磁盘上. pickle.dump(obj, file[, protocol]) 序列化对象,并将结果数据流写入到文件对象中.参数pr ...