WebSocket协议可以实现前后端全双工通信,从而取代浪费资源的长轮询。在此协议的基础上,可以实现前后端数据、多端数据,真正的实时响应。在学习WebSocket的过程中,实现了一个简化版群聊,过程和代码详细记录在这篇文章中。

本篇文章来自董沅鑫的个人网站,引用、转载请指明出处

查看更多知识,或者技术交流:请访问godbmw.com

1 概述

1.1 WebSocket 是什么?

  1. 建立在 TCP 协议之上的网络通信协议
  2. 全双工通信协议
  3. 没有同源限制
  4. 可以发送文本、二进制数据等

1.2 为什么需要 WebSocket?

了解计算机网络协议的人,应该都知道:HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。

这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。

因此,如果在客户端想实时监听服务器变化,必须使用 ajax 来进行轮询,效率低,浪费资源。

而 websocket 就可以使得前后端进行全双工通信(两方都可以向对方进行数据推送),是真正的平等对话

2 WebSocket 客户端

支持HTML5的浏览器支持 WebSocket 协议:

var ws = new WebSocket(url); // 创建一个websocket对象

2.1 WebSocket 属性

属性 描述
ws.readyState 只读属性 readyState 表示连接状态,可以是以下值:0 - 表示连接尚未建立。1 - 表示连接已建立,可以进行通信。2 - 表示连接正在进行关闭。3 - 表示连接已经关闭或者连接不能打开。
ws.bufferedAmount 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

2.2 WebSocket 方法

属性 描述
ws.send() 数据发送
ws.close() 关闭连接

2.3 Websocket 事件

属性 描述
open 连接建立触发
message 通信时触发
error 出错触发
close 关闭连接触发

2.4 代码实现

假设我们在本地8080端口打开了websocket服务,那么,下面代码可以在浏览器中实现和这个服务的通信:

<body><script>var ws = new WebSocket("ws://localhost:8080/");// 建立连接触发ws.onopen = function () {ws.send("open ws");console.log("open ws");};// 接收服务端数据触发ws.onmessage = function (evt) {var data = evt.data;console.log("Data is ", data);};// 断开连接触发ws.onclose = function () {console.log("close ws");};</script>
</body>

3 WebSocket 服务端

关于服务端实现,根据技术选型不同,可以选用不同的库和包。我这里使用的是nodews库来websocket服务端。

在阮一峰的博文提到的socket.io库,在浏览器端的写法不兼容原生API,准确来说,它们自己实现了一套websocket。所以,使用的时候前后端都应该引用第三方库。这样就造成了代码迁移性,严重下降。

综上所述,ws库有以下优点:

  1. 兼容性好,兼容浏览器原生API
  2. 长期维护,效果稳定
  3. 使用方便(往下看就知道了)

4 实现群聊

4.1 群聊 服务端实现

首先,在命令行中,安装ws库: npm install ws --save

现在,利用ws来实现一个监听8080端口的websocket服务器,讲解都在代码注释里,一目了然

const PORT = 8080; // 监听端口
const WebSocket = require("ws"); // 引入 ws 库const wss = new WebSocket.Server({ port: PORT }); // 声明wss对象/*** 向除了本身之外所有客户端发送消息,实现群聊功能* @param {*} data 要发送的数据* @param {*} ws 客户端连接对象*/
wss.broadcastToElse = function broadcast(data, ws) { wss.clients.forEach(function each(client) {if (client !== ws && client.readyState === WebSocket.OPEN) {client.send(data);}});
};/* 客户端接入,触发 connection */
wss.on("connection", function connection(ws, req) {let ip = req.connection.remoteAddress; // 通过req对象可以获得客户端信息,比如:ip,headers等/* 客户端发送消息,触发 message */ws.on("message", function incoming(message) { ws.send(message); // 向客户端发送消息wss.broadcastToElse(message, ws); // 向 其他的 客户端发送消息,实现群聊效果});});

4.2 群聊 客户端实现

为了方便编写,这里引入了jquerybootstrap这两个库,只需要关注js代码即可。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>群聊</title><link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script>
</head>
<body><div class="container"><textarea class="form-control" rows="30" disabled="disabled" id="show-area"></textarea><input type="text" class="form-control" placeholder="请输入聊天内容" id="chat-input"><button type="button" class="btn btn-info" id="send-btn">发送</button></div><script>var userName = parseInt(Math.random() * 1000, 10) // 随机用户名, 以标识身份var sendBtn = $("#send-btn"), // 发送信息按钮chatInput = $("#chat-input"), // 聊天信息输入框showArea = $("#show-area") // 聊天信息展示框var ws = new WebSocket("ws://localhost:8080/") // 初始化WebSocket对象sendBtn.on("click", function () {var content = chatInput.val()if (content.length === 0) {return alert("请不要输入空白内容")}content = "At " + (new Date()).toString() + "\n" + "来自用户" + userName + "\n" + content // 拼接用户信息、时间信息和消息ws.send(content) // 发送消息chatInput.val("") // 清空输入框})ws.onopen = function () { console.log("Conncet open") }ws.onmessage = function (evt) {var data = evt.datashowArea.val(showArea.val() + data + "\n\n") // 刷新聊天信息展示框:显示群聊信息}ws.onclose = function () { console.log("Connect close") }</script>
</body>
</html>

4.3 群聊 效果展示

首先启动我们的服务端代码:node server.js 。其中,server.js是放置服务端代码的文件。

然后,我们打开2次编写的html代码,这相当于,打开2个客户端。来检测群聊功能。

5. 相关资料

  • 概念解释:

    • http://www.ruanyifeng.com/blog/2017/05/websocket.html
    • https://www.cnblogs.com/jingmoxukong/p/7755643.html
  • ws文档:https://www.npmjs.com/package/ws

本篇文章来自董沅鑫的个人网站,引用、转载请指明出处

查看更多知识,或者技术交流:请访问godbmw

转载于:https://www.cnblogs.com/geyouneihan/p/9502280.html

websocket学习和群聊实现相关推荐

  1. 【Java分享客栈】SpringBoot整合WebSocket+Stomp搭建群聊项目

    前言 前两周经常有大学生小伙伴私信给我,问我可否有偿提供毕设帮助,我说暂时没有这个打算,因为工作实在太忙,现阶段无法投入到这样的领域内,其中有两个小伙伴又问到我websocket该怎么使用,想给自己的 ...

  2. django+vue3实现websocket聊天室(群聊)

    1.如何实现聊天功能 2.什么是websocket 2.1解释什么叫全双工,半双工,单工 3.websocker的概念 4.websocket的优点 5.django ,vue如何实现websocke ...

  3. websocket(二)--简单实现网页版群聊

    websocket可以实现服务端的消息推送,而不必在客户端轮询,大大的节省的资源,对于实时通讯来说简直是个大喜讯. 在上一篇文章中介绍了协议握手,这篇文章将通过实现简单的群聊来帮助进一步了解webso ...

  4. WebSocket刨根问底(三)之群聊

    前两篇文章[WebSocket刨根问底(一) ][WebSocket刨根问底(二) ]我们介绍了WebSocket的一些基本理论,以及一个简单的案例,那么今天继续,我们来看一个简单的群聊的案例,来进一 ...

  5. springboot整合websocket实现群聊

    1.依赖 2.websocket配置: 3.前端 4.注意事项 效果: 也可以打开新窗口连接一个新用户发消息 1.依赖 <dependency><groupId>org.spr ...

  6. python网页版_经典python学习教程:20行代码打造一个微信群聊助手,解放双手

    今天的Python学习教程教大家如何用20行Python代码实现微信群聊助手,可以用来活跃群气氛,好多群主创建完群后,拉完一群人,之后就一片寂静,有个群聊助手,就可以帮忙活跃群里气氛,通过今天在自己的 ...

  7. js 链接websocket马上断开_WebSocket之基于STOMP协议的广播模式实现群聊功能

    又是一个老套的古诗词赏析 不恨此花飞尽,恨西园.落红难缀.--苏轼<水龙吟·次韵章质夫杨花词> WebSocket与STOMP协议 相关简介 WebSocket WebSocket 是一种 ...

  8. (3)websocket实现单聊和群聊

    1 资源下载地址  http://download.csdn.net/detail/jianfpeng241241/9325049 2  群聊图 2.1 zhangsan 发给所有人的图 2.2 发送 ...

  9. Node + WebSocket + Vue 聊天室创建群聊/加入群聊功能 – 第五章

    前言 本次算是做了一个小小的专题吧,"Nodejs + WebSocket + Vue实现聊天室功能",目前还在一步一步推进,之前已经可以一对一.一对多聊天了,今天就来创建群聊组, ...

最新文章

  1. 【开发环境】安装 Visual Studio Code 开发环境 ( 下载 Visual Studio Code 安装器 | Visual Studio Code )
  2. Android Studio 的 build 过程
  3. delphi xe http 收不到反馈消息_好消息接二连三!苹果将在双·11当天举办发布会_笔记本新闻...
  4. 使用qt的qtcore库怎么包含_GitHub - coologic/QtCoreExamples: QtCore模块相关类库范例
  5. Spring boot Tomcat配置
  6. mysql5.715 安装在d盘_mysql5.7.15在windows环境下的安装设置图文详细教程
  7. appium常用参数(一)
  8. 使用 telnet 命令 查看端口的开放、可用情况
  9. Emacs取消键值绑定
  10. C++ 类 class 构造函数 : 成员赋值 父类提前构造
  11. TypeScript1---数据类型和函数
  12. PCSHARE VIP 2005源代码
  13. photoshop基础操作集合01
  14. 百度云图片识别(ImageRecognition)
  15. ubuntu系统打开.chm文件方式
  16. 计算机网络设计大赛总结,大学生海报设计大赛总结
  17. xposed修改手机屏幕分辨率
  18. 使用IDEA编写Java程序时遇到的小提醒Common part can be extracted from ‘if‘
  19. CSDN20181219博客黑板报
  20. 检测浏览器flash是否安装

热门文章

  1. getbean方法找不到bean_?找不到产品卖点?你需要这些方法!
  2. 职称计算机考试选择题,职称计算机考试综合选择题「附答案」.docx
  3. python运行界面英文翻译_python使用百度api翻译中英文
  4. git远程版本硬删除
  5. Linux之后台运行(nohup和)
  6. php单词出现频率,PHP计算文件或数组中单词出现频率
  7. java怎么获取文本里的值_怎么获取到text中的文本,或者title中的值
  8. 多线程可以使用计算机多核那,【多线程逻辑面试题】面试问题:异步操作的优缺… - 看准网...
  9. (8)操作系统安全机制之二
  10. 需求分析中应该注意的问题