其实构建一个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. poj 2226 Muddy Fields (二分图)

    大意:给定n*m网格, 每个格子为泥地或草地, 可以用一些长度任意宽度为1的木板盖住泥地, 要求不能盖到草地, 求最少要多少块木板能盖住所有泥地. 最小点覆盖板子题, 建图跑最大匹配即可. #incl ...

  2. js对象的 两种访问方式

    来对象访问属性有两种方式.有一个对象Obj = {"Name":"Langshen","AGE":"28"} 用点访问, ...

  3. C# 中使用反射的优缺点

    本文摘至于:http://blog.csdn.net/springfileld/article/details/17720537 ----------------------------------- ...

  4. Photoshop从入门到精通所有视频教程(43G)以及素材资料免费拿

    包含了Photoshop从入门到精通所有需要了解的视频教程资料,并且包含了大量的P图素材. 资料获取方式,关注公总号RaoRao1994,查看往期精彩-所有文章,即可获取资源下载链接 更多资源获取,请 ...

  5. MySQL授权远程用户登录权限

    1 举例子,建数据库,然后 赋予用户远程访问的所有权限,最后刷新权限 create database cmf DEFAULT CHARACTER SET utf8; grant all on cmf. ...

  6. centos6.4升级openssh7.4p1

    Centos6.4版本yum升级openssh版本最高到5.3,想要升级到更高的版本需要重新编译 一.查看当前openssh版本: [root@localhost ~]# ssh -VOpenSSH_ ...

  7. EEPROM原理详解

    EEPROM(Electrically Erasable Programmable read only memory)即电可擦可编程只读存储器,是一种掉电后数据不丢失(不挥发)存储芯片. EERPOM ...

  8. c++ 常用数据类型转换

    1.int型与string型的互相转换 int型转string型 void int2str(const int &int_temp,string &string_temp) { str ...

  9. CeSharp支持MP4

    因为CefSharp不支持MP4格式(因为版权问题,MP3因为版权过期新版本已经支持了),需要自己下载源码重新编译以支持MP4,或者下载被人编译好的库.因时间问题,我直接在csdn上下载了一个(1c币 ...

  10. Windows下Redis如何永久更改密码

    公司使用的是Spring-session-redis 需要给Redis配置一个密码 本来我配置密码的方法是 先打开Redis服务 在采用 命令 CONFIG SET requirepass " ...