思考:这种网页版的聊天功能应该如何去实现??
websocket介绍
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
websocket是一种持久协议,http是非持久协议
现在很多网站都有实时推送的需求,比如聊天,客服咨询等
早期没有websocket时,通过ajax轮询,由于http请求,服务器无法给浏览器主动发送数据,因此需要浏览器定时的给服务器发送请求(比如1s一次),服务器把最新的数据响应给浏览器。这种模式的缺点就是浪费性能和资源。
websocket是一种网络协议,允许客户端和服务端全双工的进行网络通讯,服务器可以给客户端发消息,客户端也可以给服务器发消息。
websocket基本使用
在HTML5中,浏览器已经实现了websocket的API,直接使用即可。
创建websocket对象
1 | // 参数1: url:连接的websocket属性 |
websocket事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
websocket方法
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
使用nodejs开发websocket服务
我们刚刚使用了官网提供的echo服务,接下来我们自己通过nodejs实现一个简单的websocket服务。
使用nodejs开发websocket需要依赖一个第三方包。Nodejs Websocket
项目搭建
新建一个websocket server端的项目1
2
3
4
5mkdir server-demo
cd server-demo
yarn init -y
yarn add nodejs-websocket
touch app.js
开发服务程序
在app.js中1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// 导入第三方模块
const ws = require('nodejs-websocket')
// websocket占用的端口号
const PORT = 3000
const server = ws.createServer(connect => {
console.log('新的连接')
// 接收到客户端的文本内容时触发
connect.on('text', str => {
console.log('接收:' + str)
// 把接收到的字符串转换成大写,并且给客户端响应
connect.sendText(str.toUpperCase() + '!!!!')
})
// 监听关闭事件
connect.on('close', () => {
console.log('连接关闭了')
})
// 监听错误事件, 比如浏览器关闭了连接,或者发送的数据格式不对等
connect.on('error', err => {
console.log('连接异常')
})
})
// 启动websocket服务
server.listen(PORT, function() {
console.log(`websocket server listening on ${PORT}`)
})
启动服务
1 | node app.js |
在终端中看到websocket server listening on 3000
就说明webserver服务启动成功了
进行测试
修改客户端中index.js
文件中的连接地址,重新进行测试1
2
3// 创建websocket对象,地址已经修改称为了自己编写的地址
const URL = 'ws://localhost:3000'
const websocket = new WebSocket(URL)
websocket开发聊天室程序
app.js
1 | const ws = require('nodejs-websocket') |
index.html
1 |
|
如果使用原生的websocket进行开发,会比较麻烦,比如支持的事件太少,发送的数据只能是字符串格式的,提供的api也很少,类似于广播这种方法都没有,需要自己封装。
socket.io基本使用
基于socket.io开发完整的聊天室
Tips: Please indicate the source and original author when reprinting or quoting this article.