webSocket实现聊天室功能
前言
我们知道服务器是一种应答模式,也就是说服务器只能被动提供服务,而不会主动推送信息给客户端。
传统网站为了实现类似在线聊天的功能都是不断的给服务器发送信息询问是否有新消息也就是所谓的轮询
。
这种方式有很明显的弊端:大量耗费服务器内存和宽带资源,因为不停的请求服务器,很多时候 并没有新的数据更新,因此绝大部分请求都是无效请求。
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
浏览器和服务器建立了webSocket连接后就可持续连接并双向数据传输。
浏览器可发送数据给服务器,服务器有信息后也可主动推送信息给浏览器
效果
项目地址:github地址
预览地址:预览地址
请用不同的浏览器测试两个账号
聊天功能
- 用户上/下线时提示聊天组所有的成员用户已上/下线
- 聊天室可发送图片和表情进行聊天
- 仿制qq的聊天时间格式
实现
前端涉及到的依赖有react、antd、redux
以及braft-editor富文本编辑器
后端涉及到的依赖有koa
和nodejs-websocket。
这里我只会介绍大致的逻辑,详细的实现细节可以参考我的源码。
流程:
- 后台首先搭建websocket服务器
- 前后端建立websocket连接
- 前后端各自监听消息事件
- 开始聊天
我使用的是nodejs-websocket来搭建的websocket服务
var ws = require("nodejs-websocket")// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {console.log("New connection")//监听浏览器发送过来的信息conn.on("text", function (str) {console.log("Received "+str)conn.sendText(str)})//websocket连接关闭的事件conn.on("close", function (code, reason) {console.log("Connection closed")})
}).listen(8081)
上面几行代码就已经在8081端口实现了一个websocket服务(nodejs-websocket
更详细的api请参考官网)
浏览器与服务器建立websocket连接
//实例化websocket对象
const ws = new WebSocket("ws://"+window.location.hostname+":8081")//建立连接时触发
ws.onopen = function(){//发送数据到服务器ws.send("第一次建立连接")
}//监听服务器信息
ws.onmessage = function(event){console.log(event.data)
}
注意:不管是服务器还是浏览器我们发送的信息都是字符串类型的数据
。对于其他类型的数据请参考nodejs-websocket官网
这里我将服务器和浏览器发送的消息设置为两种类型:聊天消息、上线消息。
这样在浏览器和服务器才能对不同的消息类型做不同的处理。
const msgType = {onlineInfo: 0, //关于在线列表chatInfo: 1 //关于聊天内容
}
用户上线
- 浏览器第一次和服务器建立websocket连接时将用户信息发送给服务器
- 服务器在收到消息后将用户信息添加到在线列表中去,并在连接中保存当前用户信息
- 服务器将用户上线消息广播到所有与服务器成功建立连接的浏览器(消息类型为0)
- 浏览器收到服务器推送的消息后更新在线列表
这里我只做了一个聊天室,所以这里广播到所有客户端,如果想要实现多个聊天室或私人聊天室,只需将聊天目标作为信息一起传给服务器,服务器根据聊天目标去过滤广播。
用户聊天
- 前端将用户聊天内容(可以是图片、文字、表情)发送给服务器
- 服务器收到消息后将聊天内容保存到数据库并广播给所有客户端(消息类型为1)
- 浏览器收到服务器推送的消息后更新聊天列表
用户下线
- 服务器的在close事件中监听websocket连接关闭
- 用户关闭浏览器
- 服务器将下线用户弹出在线列表并广播给所有客户端(消息类型为0)
- 浏览器收到服务器推送的消息后更新在线列表
用户信息更改
- 用户信息更改时,发送新用户信息到服务器
- 服务器收到消息后更新当前用户信息(包括数据库的更新)
- 浏览器发现用户信息更新后,重新请求聊天列表和聊天记录
这里我就不放具体的实现代码了,建议先了解websocket
和nodejs-websocket
后再参考我的源码。
之所以用到redux
是因为我想在用户登录成功后就建立websocket
连接,所以放到了redux中去了。
另外我还仿制了qq聊天的时间格式,当聊天消息间隔3分钟时,在消息上方显示时间,这个时间我利用了moment
进行转换
//处理时间handleTime = (time, small) => {if (!time) {return ''}const HHmm = moment(time).format('HH:mm')//不在同一年,就算时间差一秒都要显示完整时间if (moment().format('YYYY') !== moment(time).format('YYYY')) {return moment(time).format('YYYY-MM-DD HH:mm:ss')}//判断时间是否在同一天if (moment().format('YYYY-MM-DD') === moment(time).format('YYYY-MM-DD')) {return HHmm}//判断时间是否是昨天。不在同一天又相差不超过24小时就是昨天if (moment().diff(time, 'days') === 0) {return `昨天 ${HHmm}`}//判断时间是否相隔一周if (moment().diff(time, 'days') < 7) {const weeks = ['日', '一', '二', '三', '四', '五', '六']return `星期${weeks[moment(time).weekday()]} ${HHmm}`}if (small) {return moment(time).format('MM-DD HH:mm')} else {return moment(time).format('M月D日 HH:mm')}}
webSocket实现聊天室功能相关推荐
- Node + WebSocket + Vue 聊天室创建群聊/加入群聊功能 – 第五章
前言 本次算是做了一个小小的专题吧,"Nodejs + WebSocket + Vue实现聊天室功能",目前还在一步一步推进,之前已经可以一对一.一对多聊天了,今天就来创建群聊组, ...
- SpringBoot +WebSocket实现简单聊天室功能实例
SpringBoot +WebSocket实现简单聊天室功能实例) 一.代码来源 二.依赖下载 三.数据库准备(sql) 数据库建表并插入sql 四.resources文件配置 application ...
- 原生JavaScript+WebSocket+nodejs实现聊天室功能
码字不易,有帮助的同学希望能关注一下我的微信公众号:Code程序人生,感谢!代码自用自取. WebSocket也是前端非常重要的技术栈. 现在各种网站.App.小程序都伴有即时通信的功能.WebSoc ...
- 基于WebSocket实现聊天室(Node)
基于WebSocket实现聊天室(Node) WebSocket是基于TCP的长连接通信协议,服务端可以主动向前端传递数据,相比比AJAX轮询服务器,WebSocket采用监听的方式,减轻了服务器压力 ...
- 基于django channel 实现websocket的聊天室
websocket 网易聊天室? web微信? 直播? 假如你工作以后,你的老板让你来开发一个内部的微信程序,你需要怎么办?我们先来分析一下里面的技术难点 消息的实时性? 实现群聊 现在有 ...
- 视频教程-基于Java的WebSocket的聊天室-Java
基于Java的WebSocket的聊天室 多年 Java 企业级应用开发工作经验,曾参与中国人寿.华夏人寿.泰康人寿.信达财险等保险行业内部业务管理系统以及线上在线产品的开发:参与中国人民银行.清华大 ...
- SpringBoot + Vue 实现基于 WebSocket 的聊天室(单聊)
前言 在前一篇文章SpringBoot 集成 STOMP 实现一对一聊天的两种方法中简单介绍了如何利用 STOMP 实现单聊,本文则将以一个比较完整的示例展示实际应用,不过本文并未使用 STOMP,而 ...
- 前端+node实现一个简单的聊天室功能
简单的实现一个聊天室功能 目录 前言 一.了解一下WebSocket 我们有了http协议,为什么会出现ws呢? ws出现之前,我们是怎么实现双向通信的呢? 二.使用到的websocket库 三.聊天 ...
- SSM(五)基于webSocket的聊天室
SSM(五)基于webSocket的聊天室 前言 不知大家在平时的需求中有没有遇到需要实时处理信息的情况,如站内信,订阅,聊天之类的.在这之前我们通常想到的方法一般都是采用轮训的方式每隔一定的时间向服 ...
- python udp 直播_[Python] socket发送UDP广播实现聊天室功能
原博文 2018-11-24 12:33 − 一.说明 本文主要使用socket.socket发送UDP广播来实现聊天室功能. 重点难点:理解UDP通讯流程.多线程.UDP广播收发等. 测试环境:Wi ...
最新文章
- Week1 Team Homework #2 from Z.XML-Introduction of team member with photos
- 藁城一中2021年高考成绩查询,2017藁城一中录取分数线及高考成绩情况
- 【DP】【树状数组】折线统计(金牌导航 数据结构优化DP-1)
- 自考感悟,话谈备忘录模式
- Spring for Apache Hadoop 1.0发布
- PHP 异常处理 throw new exception
- Qt插件机制介绍及实现
- google appid申请
- dockerfile入门
- iOS常用三方库、插件、知名技术博客、常用开发工具使用介绍等等(Objective-C版本)
- 调试sim800L模块
- java计算机毕业设计企业员工档案管理源码+系统+数据库+lw文档+mybatis+运行部署
- 地理信息三维可视化技术在城市规划中的应用
- android 手机滤镜
- 【懒懒的Python学习笔记六】
- 【阶段1】【定理证明】二项式定理证明
- SuperMap iDesktop 之 BIM优化流程——建筑篇
- RK CPU调试技巧
- 南京理工计算机硕士就业,南京理工大学好就业吗?附南京理工大学就业率最高的专业名单...
- linux 修改用户密码 报错,linux中修改用户密码报错 passwd:Authentication token manipulation error...
热门文章
- Jar包常见的反编译工具介绍与使用
- scratch的官方版本和其他的改编版本/小喵科技Kittenblock/snap!/TurboWarp
- 软件设计(中线提取)
- 限时免费领取育碧75元游戏《纪元Anno1404:历史版》
- 袁萌记忆中的华罗庚先生
- 实习日记5:过滤器+批量删除+角色管理
- The Crime-solving Plan of Groundhog
- 2018.12.15【HDU4622】Reincarnation(后缀自动机SAM)
- Java | PTA练习:伪随机数题解
- matlab等距偏置曲线,144 偏置曲线命令详解