websocket 是什么?
websocket 是随着 HTML5 一起出的一个全新的通信协议, 在 websocket 被提出之前,浏览器与服务器之间通信是通过 http 或者 https 协议来完成的。
首先 http 协议本身是非常棒的,我非常喜欢它。但是它自身也有一些不足点,无论是之前的
http 1.0
的短连接还是现在的http 1.1
长连接, 都不能做到让服务器主动的推送消息给浏览器,必须是浏览器主动发出 request, 然后服务器再被的 response。始终是 【浏览器 主动 requiest】 => 【服务器 被 response】这种模式。
为什么服务器不能主动一点,前端妹子要走啦!!!! 哈哈哈哈.....
为了应对 http 协议的这个不足点, HTML5 中就出了 websocket 协议这个小家伙, 她能让服务器主动推送消息给浏览器
websocket-server-edit.jpg http-server-edit.jpg
websocket 与 http 在与服务器通信时都需要先与服务器建立连接, 建立连接的过程她们几乎是一样的。
建立连接之后:
http 与 服务器进行进行通信时只能是【浏览器 主动 requiest】 => 【服务器 被 response】这种模式。
但是使用 websocket 协议时,则没有主动与被一说,浏览器与服务器之前可以相互任意的发送消息。 不再是一个 request 对应一个 response 的模式了。
说了这么多,其实 websocket 也只不过是众多协议中的一个协议而已。
兼容性
websocket-compatibility.png如何使用 websocket ?
任何协议都是需要通信双方皆支持时才可以使用的,在支持 websocket 协议的浏览器中可以直接使用相关的 API, 并且服务器也需要支持 websocket 才可以。(服务器是不能使用 http 协议与浏览器端 websocket协议进行通信, 这就好像中文件和英文之间也是不可能直接通信的)
浏览器端代码:
// WebScoket 支持 websocket 的浏览器会提供一个全局的 WebSocket
var wsUri = 'ws://127.0.0.1:8080/'
var websocket = new WebSocket(wsUri)
websocket.onopen = function (event) {
// 这里执行时表明,已经使用 websocket 协议与服务器建立好了连接,可以相互的发送消息了
console.log('websocket 连接建立成功!')
}
node.js 端代码
可以使用一个叫
ws
的第三方模块,它帮我们实现好了 websocket 协议,可以直接在 node.js 中使用
npm install ws —save
const WebSocket = require('ws');
const wsServer = new WebSocket.Server({ port: 8080 })
wsServer.on('connection', function connection(client) {
// 这里执行时表明,已经使用 websocket 协议与服务器建立好了连接,可以相互的发送消息了
console.log('websocket 连接建立成功!')
})
哈哈是不是感觉和浏览器端的代码几乎一样,哈哈~ 就是这么神奇!
🚩 参考示例代码: demo/建立websocket连接
目录中
使用 websocket 发送消息
连接成功之后,就可以调用上面两个实例各自的send方法来相互发送消息了
只有连接成功之后才可以发消息!
websocket.onopen = function () {
ws.send('消息')
}
wsServer.on('open', function () {
})
websocket 相关事件
浏览器端:
// WebScoket 支持 websocket 的浏览器会提供一个全局的 WebSocket
var wsUri = 'ws://127.0.0.1:8080/'
var websocket = new WebSocket(wsUri)
// websocket 事件:
// open 事件: 连接建立成功后触发
websocket.onopen = function (event) {
// 这里执行时表明,已经使用 websocket 协议与服务器建立好了连接,可以相互的发送消息了
console.log('websocket 连接建立成功!')
console.log('open', event)
websocket.send('发给服务器的消息')
// websocket.close() // 是关闭连接的方法
}
// message事件: 服务器发来消息时触发
websocket.onmessage = function (event) {
// event.data 是服务器发来的消息内容
console.log('message', event)
}
// close 事件: 连接关闭时触发
websocket.onclose = function (event) {
console.log('close', event)
}
// error 事件: 连接发生错误时触发(例如网络中断时)
websocket.onerror = function (event) {
console.log('error', event)
}
node.js 端
const wsServer = new WebSocket.Server({ port: 8080 })
const wsServer = new WebSocket.Server({ port: 8080 })
wsServer.on('connection', function connection (ws) {
// 这里执行时表明,已经使用 websocket 协议与服务器建立好了连接,可以相互的发送消息了
console.log('websocket 连接建立成功!')
ws.send('发给前端的消息')
// ws.close() 是关闭连接的方法
ws.on('message', function (data) {
console.log('message', data)
})
ws.on('close', function (errcode) {
console.log('close', errcode)
})
ws.on('error', function (err) {
console.log('error', err)
})
})
🚩 参考示例代码: demo/websocket消息与事件
目录中
服务器端广播
给所有人广播消息
wsServer.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send('广播消息')
}
}
给除了当前发出请求人之外的人广播
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send('广播消息');
}
}
SSE
SSE (Server-Sent Events,服务器发送事件 )
兼容性
sse-compatibility.pngsocket.io
socket.io 是什么?
socket.io 不是一个具体的技术,而是一个基于 websocket 等即时通讯手段封装的一个库。
使用它时可以不必担心长轮询写法麻烦,也不必担心 websocket 兼容性问题,这些问题,socket.io 都会帮我们处理好。
如何使用 socket.io ?
使用的方式和 websocket 大抵差不多
node.js 端
结合 express 框架的代码
const http = require('http')
const express = require('express')
const socketIO = require('socket.io')
const app = express()
const server = http.createServer(app)
// 将和 http 监听相同的端口
const io = socketIO(server)
app.use(express.static('./public'))
app.use(express.static('./node_modules'))
// 有客户端连接事件
io.on('connection', (socket) => {
// 当有客户端连接时执行, 参数 socket 就代表当前连接上来的客户端
console.log('a user connected')
})
server.listen(3000, '127.0.0.1', err => {
if (err) {
return console.log(err)
}
console.log('启动成功: http://127.0.0.1:3000/index.html')
})
浏览器端:
需要引入 socket.io.js 文件, 它在 node_modules/socket.io-client/dist/socket.io.js
, 是随着 socket.io 一同被下载下来的。
<script src="/socket.io-client/dist/socket.io.js"></script>
<script>
// 与服务器建立连接, 连接的服务器地址不需要提供, 默认就是当前地址栏的地址。
// io 是 socket.io.js 中暴露的全局变量
var socket = io();
</script>
socket.io 相关事件及消息的发送与接收
node.js 端
// connection 有客户端连接事件, 通过 io 这个对象来监听
io.on('connection', (socket) => {
// disconnect 是连接断开事件, 通过 socket 这个客户端对象监听
socket.on('disconnect', () => {
})
// 当 on 的参数1 不是上面的 connection 或者 disconnect 这种 socket.io 自带的事件时, 它就相当于是自定义事件,用来接收浏览器发来的消息
socket.on('yyy', msg => {
// 参数 msg 就是浏览器发来的消息
console.log(msg)
})
// emit 方法的作用是主动给浏览发送消息, 浏览器中也有一个 emit 方法,作用是主动给服务器发送消息
socket.emit('xxx', '要发送的消息内容')
})
浏览器端
var socket = io()
socket.on('connect', function () {
console.log('连接建立成功!')
})
// 接收服务器通过 socket.emit('xxx',) 发来的消息
// 服务器端 emit 方法的参数1 需要和这里的 on 方法的参数1 相同时这里的回调才会执行。
socket.on('xxx', function (msg) {
console.log(msg)
})
document.querySelector('form').onsubmit = function (e) {
e.preventDefault()
var oIpt = document.querySelector('input')
socket.emit('yyy', oIpt.value)
oIpt.value = ''
}
socket.io 广播
node.js 端
socket.emit() // 给自己回发
socket.broadcast.emit // 给除自己外的人发
io.emit() // 给所有人发
网友评论