其实构建一个Web多房间聊天室也并不是什么困难的技术,借助于websocket就可以轻松实现多用户在线实时通讯交互;在这里主要介绍一下在BeetleXBeetleXjs的支持下如何让这个功能实现的更简单和高效。接下来通过使用BeetleX来一步步讲解Web多房间聊天室的具体实现。

信息逻辑

既然是多房间聊天室那它具备两个主要元素,分别是用户和房间;下面通过类来描述这两个元素:

用户

    public class User
{
public string Name { get; set; } public string Address { get; set; } [JsonIgnore]
public ISession Session { get; set; } [JsonIgnore]
public Room Room { get; set; } public void Send(BeetleX.FastHttpApi.WebSockets.DataFrame frame)
{
frame.Send(Session);
} public void Exit()
{
Room?.Exit(this);
}
}

信息描述比较简单主要包括信息用:名称,会话和房间;涉及的行为有发送信息和退出房间。

房间

    public class Room
{ public string Name { get; set; } public List<User> Users { get; private set; } = new List<User>(); public HttpApiServer HttpServer { get; set; } public void Send(Command cmd)
{
cmd.Room = Name;
var frame = HttpServer.CreateDataFrame(cmd);
lock (Users)
{
foreach (var item in Users)
item.Send(frame);
} } public User[] GetOnlines()
{
lock (Users)
return Users.ToArray();
} public void Enter(User user)
{
if (user == null)
return;
if (user.Room != this)
{
user.Room?.Exit(user);
lock (Users)
Users.Add(user);
user.Room = this;
Command quit = new Command { Type = "enter",Message=$"enter room", User = user };
Send(quit);
}
} public void Exit(User user)
{
if (user == null)
return;
lock (Users)
Users.Remove(user);
user.Room = null;
Command quit = new Command { Type = "quit", Message = $"exit room", User = user };
Send(quit);
}
}

房间信息主要包括名称和用户信息,具体行为有进房间,出房间和向房间发送信息。

服务逻辑

有了逻辑信息那就需要把这个信息通过接口的服务方式提供给外部访问操作,接下来定义一个简单的控制器类来描述相关接口服务行为

    [BeetleX.FastHttpApi.Controller]
public class Home : BeetleX.FastHttpApi.IController
{
[BeetleX.FastHttpApi.NotAction]
public void Init(HttpApiServer server, string path)
{
for (int i = ; i < ; i++)
{
string key = $"{i:00}";
mRooms[key] = new Room { Name = key, HttpServer = server };
}
server.HttpDisconnect += (o, e) =>
{
GetUser(e.Session)?.Exit();
};
}
private ConcurrentDictionary<string, Room> mRooms
= new ConcurrentDictionary<string, Room>(StringComparer.OrdinalIgnoreCase);
public object Rooms()
{
return from a in mRooms.Values orderby a.Name select new {a.Name};
}
public void Enter(string room, IHttpContext context)
{
User user = GetUser(context.Session);
mRooms.TryGetValue(room, out Room result);
result?.Enter(user);
}
public void Talk(string message, IHttpContext context)
{
if (!string.IsNullOrEmpty(message))
{
var user = GetUser(context.Session);
Command cmd = new Command { Type = "talk", Message = message, User = user };
user?.Room?.Send(cmd);
}
}
public void Login(string name, IHttpContext context)
{
User user = new User();
user.Name = name;
user.Session = context.Session;
user.Address = context.Request.RemoteIPAddress;
SetUser(context.Session, user);
}
private User GetUser(ISession session)
{
return (User)session["__user"];
} private void SetUser(ISession session, User user)
{
session["__user"] = user;
}
}

Init方法

用于初始化房间信息,并绑定连接断开事件,如果用户断开了则执行用户退出房间。

Login方法

登陆到用户中

Rooms方法

获取所有房间信息

Enter方法

用户进入房间

Talk

用户向房间内发送一条消息

启动服务

当功能逻辑写好后,接下来的工作就是让这些接口部署到websocket服务中,部署的代码比较简单:

    class Program
{
static void Main(string[] args)
{
var builder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.UseBeetlexHttp(o =>
{
o.LogToConsole = true;
o.ManageApiEnabled = false;
o.Port = ;
o.SetDebug();
o.LogLevel = BeetleX.EventArgs.LogType.Warring;
},
typeof(Program).Assembly);
});
builder.Build().Run();
}
}

当服务部署后就可以专心去做前端实现的工作。

Web前端

为了更方便地和Beetlex服务整合,因此也单独针对性地封装了相应的javascript组件;除了自有封装的javascript还涉及到vuejs的使用。通过以上组件整合前端的代码相比服务端来说就更简单了,详细代码如下:

<body>
<div id="page">
<page-header> </page-header>
<div class="container" style="margin-top:110px;">
<div class="row">
<ul style="list-style:none;">
<li v-for="item in messages" class="message">
<h4>
<span class="label label-success">[{{item.Room}}]</span>
<span class="label label-info">{{item.User.Name}}</span>
<span class="label label-default">{{new Date()}}</span>
</h4>
<div style="padding-left:20px;">
{{item.Message}}
</div>
</li>
</ul>
</div>
</div>
<page-footer :status="loginStatus" @login="onLogin($event)"
@talk="onTalk($event)" @select="onSelectRoom($event)" :rooms="getRooms.result">
</page-footer>
</div>
<script>
beetlex.websocket.receive = function (r) {
page.messages.push(r);
};
beetlex.websocket.disconnect = function () {
page.loginStatus = false;
};
beetlex.useWebsocket();
var login = new beetlexAction("/Login");
var getRooms = new beetlexAction('/Rooms', null, []);
var enterRoom = new beetlexAction('/Enter');
var talk = new beetlexAction('/Talk');
login.requested = function (r) {
page.loginStatus = true;
};
var model = {
getRooms: getRooms,
loginStatus: false,
login: login,
talk: talk,
enterRoom: enterRoom,
messages: [],
};
var page = new Vue({
el: '#page',
data: model,
methods: {
onSelectRoom: function (r) {
// alert(r);
this.enterRoom.post({ room: r });
},
onLogin: function (r) {
this.login.post({ name: r });
},
onTalk: function (msg) {
talk.post({ message: msg });
},
},
});
getRooms.get();
</script>
</body>

beetlex

是针对httpwebsocket封装的功能类,它自动兼容这两种请求;在默认情况是http请求,调用useWebsocket后所有请求都优先使用websocket;当websocket不可用的情况组会自动切回到http.

beetlexAction

用于描述一个请求,分别提供了postget方法;当在websocket下这两个方法的处理方式一样。

运行效果

演示地址

http://chat.ikende.com

代码地址

https://github.com/IKende/BeetleX-Samples/tree/master/WebSocket.Chat

BeetleX之快速构建Web多房间聊天室的更多相关文章

  1. SignalR 实现Web多人聊天室

      ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消 ...

  2. UIkit – 轻量级前端框架,帮助你快速构建 Web 界面

    UIKit 是一个轻量级,模块化的前端框架,用于构建快速和强大的 Web 界面.UIKit 为您提供了 HTML,CSS 和 JavaScirpt 组件,使用简单,容易定制和扩展.UIKit 基于 L ...

  3. Mysql EF Core 快速构建 Web Api

    (1)首先创建一个.net core web api web项目; (2)因为我们使用的是ef连接mysql数据库,通过NuGet安装MySql.Data.EntityFrameworkCore,以来 ...

  4. SpringBoot 快速构建微服务体系 知识点总结

    可以通过http://start.spring.io/构建一个SpringBoot的脚手架项目 一.微服务 1.SpringBoot是一个可使用Java构建微服务的微框架. 2.微服务就是要倡导大家尽 ...

  5. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(四) 添加表情、群聊功能

    休息了两天,还是决定把这个尾巴给收了.本篇是最后一篇,也算是草草收尾吧.今天要加上表情功能和群聊.基本上就差不多了,其他功能,读者可以自行扩展或者优化.至于我写的代码方面,自己也没去重构.好的,我们开 ...

  6. websocket 多聊天室功能

    websocket 类也是在网上找到的. 修改后可以用来创建多房间聊天室.可以发送图片表情,图片,及文字. 分享的代码,已经测试.可正常运行 HTML 端代码 <!DOCTYPE html> ...

  7. 使用轮询&长轮询实现网页聊天室

    前言 如果有一个需求,让你构建一个网络的聊天室,你会怎么解决? 首先,对于HTTP请求来说,Server端总是处于被动的一方,即只能由Browser发送请求,Server才能够被动回应. 也就是说,如 ...

  8. 使用ASP.NET 构建 Web 应用程序快速入门-8小时的免费培训视频

    - Scott Hanselman的中文博客[转载] [原文发表地址] Building Web Apps with ASP.NET Jump Start - 8 Hours of FREE Trai ...

  9. .net core下使用FastHttpApi构建web聊天室

    一般在dotnet core下构建使用web服务应用都使用asp.net core,但通过FastHttpApi组建也可以方便地构建web服务应用,在FastHttpApi功能的支持下构建多人聊天室是 ...

随机推荐

  1. Jmeter之cookie登录

    1.在web登录时,抓取登录的响应头 2.在jmeter中配置cookie HTTP Cookie管理器中添加信息 以下三个字段是必填的 3.添加HTTP请求(直接访问首页) 如果返回成功,并且响应内 ...

  2. Qt5.8.0编译QtMqtt库并使用该库连接有人云的例子

    一 编译QtMqtt库Qt5.10才官方支持MQTT,但我用的Qt版本是5.8.0 Mingw_32BIT, 为了在Qt5.8.0上添加MQTT支持,需要自己编译源码 步骤: (1) git clon ...

  3. Spring实战(九)AOP概念以及Spring AOP

    1.横切关注点(cross-cutting concern) 软件开发中,散布于应用中多处的功能被称为横切关注点,如事务.日志.安全. 横切关注点从概念上是与应用的业务逻辑相分离的(但是往往会直接嵌入 ...

  4. Spring实战(十三)Spring事务

    1.什么是事务(Transaction)? 事务是指逻辑上的一组操作,要么全部成功,要么全部失败. 事务是指将一系列数据操作捆绑成为一个整体进行统一管理.如果某一事务执行成功,则该事务中进行的所有数据 ...

  5. RHEL8配置本地yum源

    在RHEL8中把软件源分成了两部分一个是BaseOS,一个是AppStream. 在Red Hat Enterprise Linux 8.0中,统一的ISO自动加载BaseOS和AppStream安装 ...

  6. webpack的postcss的基本应用

    PostCss是什么? PostCSS在webpack中的基本应用 一.PostCss是什么? 如果有深入学习PostCss需求的话可以参考大漠的资料:https://www.w3cplus.com/ ...

  7. 输出指令(echo指令和printf 命令)

    Shell echo命令 Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出.命令格式: echo string 您可以使用echo实现更复杂的输出格式控制. 1. ...

  8. mybatis框架中 动态代理的问题

    在配置文件时候 id唯一性 所以不允许重载 <select id=" querydemo"   resultType="pojo"> sql 语句  ...

  9. Hadoop_09_HDFS 的 NameNode工作机制

    理解NameNode的工作机制尤其是元数据管理机制,以增强对HDFS工作原理的理解,及培养hadoop集群运营中“性能调优” “NameNode”故障问题的分析解决能力 1.NameNode职责: H ...

  10. CentOS 安装 elasticsearch 注意点

    注意点: 1. 从官网下载以 rpm 结尾的软件包 7.3.1版本 下载地址: https://artifacts.elastic.co/downloads/elasticsearch/elastic ...