html做群聊通讯方法,websocket学习和群聊实现

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

1 概述

1.1 WebSocket 是什么?

建立在 TCP 协议之上的网络通信协议

全双工通信协议

没有同源限制

可以发送文本、二进制数据等

1.2 为什么需要 WebSocket?

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

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

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

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

2 WebSocket 客户端

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

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

2.1 WebSocket 属性

专注前端与算法的系列干货分享,欢迎关注(¬‿¬):

「微信公众号:心谭博客」| xin-tan.com | GitHub

属性

描述

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服务,那么,下面代码可以在浏览器中实现和这个服务的通信:

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");

};

3 WebSocket 服务端

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

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

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

兼容性好,兼容浏览器原生API

长期维护,效果稳定

使用方便(往下看就知道了)

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 群聊 客户端实现

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

群聊

发送

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.data

showArea.val(showArea.val() + data + "\n\n") // 刷新聊天信息展示框:显示群聊信息

}

ws.onclose = function () { console.log("Connect close") }

4.3 群聊 效果展示

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

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

d9a9449e7d52?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

效果图

5. 相关资料

专注前端与算法的系列干货分享,欢迎关注(¬‿¬)

d9a9449e7d52?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值