Open maicFir opened 2 years ago
websocket 是一种基于http的通信协议,服务端可以主动推送信息给客户端,客户端也可以像服务端发送请求,Websocket允许服务端与客户端进行全双工通信。
http
Websocket
基于tcp协议之上,服务端实现比较容易
tcp
默认端口是80(ws)或者443(wss),握手阶段采用的http协议
80(ws)
443(wss)
数据格式比较轻量,性能开销小,通信高效
可以发送文本或者二进制数据
没有同源限制,客户端可以像任意服务发送信息
协议标识符是ws,如果加密,那么是wss,
ws
wss
新建一个html文件客户端代码
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>websocket</title> </head> <body> <h3>hello websocket</h3> <input type="number" id="textContent" /> <button id="handleSend">发送</button> <button id="auto-send">开启服务端向客户端发消息模式</button> <hr /> <div id="app"></div> </body> </html>
在html中引入下面一段 js
// index.js const sendDom = document.getElementById('send'); const appDom = document.getElementById('app'); const autoDom = document.getElementById('auto-send'); const inputContent = document.getElementById('textContent'); const socketPath = 'ws://192.168.31.40:3000'; let timer = null; let num = 0; const result = []; // 建立连接 const ws = new WebSocket(socketPath); const sendMyNum = (isSetInterval = false, to = 'client', val) => { const setNum = () => { num = val || Math.ceil(Math.random() * 10); ws.send( JSON.stringify({ clientText: `client:hello,我是${num}号`, num, to }) ); }; if (isSetInterval) { timer = setInterval(() => { setNum(); }, 1000); } else { setNum(); } }; const renderHtml = (data) => { const { serverText, clientText } = JSON.parse(data); appDom.innerHTML = ''; result.push({ serverText, clientText }); console.log(result); if (result.length > 0) { let str = ''; result.forEach((v) => { str += `<ul> <li>${v.clientText}</li> <li>${v.serverText}</li> </ul>`; }); appDom.innerHTML = str; } }; // 发送数据 ws.onopen = function () { console.log('websocket connection start'); sendMyNum(false); }; // 接收服务端发送的消息 ws.onmessage = function (evt) { console.log(`receive:${evt.data}`); if (evt.data) { renderHtml(evt.data); // 接收数据后关闭定时器 clearInterval(timer); // sendMyNum(true) } }; // 关闭连接 ws.onclose = function () { console.log('关闭了'); }; // 手动向客户端发送消息 handleSend.onclick = function () { const val = inputContent.value; if (val === '') { alert('请输入你的编号'); return; } sendMyNum(false, 'client', val); }; // 自动开启向客户端发送消息 autoDom.onclick = function () { sendMyNum(true, 'server'); };
新建一个server目录,新建创建服务端代码,主要依赖nodejs-websocket这个库是服务端websocket代码。
server
nodejs-websocket
websocket
var ws = require('nodejs-websocket'); var http = require('http'); const fs = require('fs'); const path = require('path'); const PORT = 8080; var server = http.createServer(function (request, response) { response.statusCode = 200; response.setHeader('Content-Type', 'text/html'); fs.readFile(path.resolve(__dirname, '../', 'index.html'), (err, data) => { if (err !== null) { response.end('404'); return; } response.end(data); }); }); server.listen(PORT, function (evt) { console.log(new Date() + ' Server is listening on port 8080'); }); // websocket const tcp = ws .createServer(function (connection) { console.log('New connection'); connection.on('text', function (data) { const { clientText, num, to } = JSON.parse(data); if (to === 'server') { connection.sendText( JSON.stringify({ serverText: `server:${num}号,恭喜你,你太幸运了,你已经被清华录取了`, clientText: `${num}号` }) ); } else { if (num > 6) { connection.sendText( JSON.stringify({ clientText, serverText: `server:${num}号,你非常优秀, ${num}号,你已经成功被录取了北京大学` }) ); } else { connection.sendText( JSON.stringify({ serverText: `server: ${num}号,非常遗憾,${num}号,你落榜了,再接再厉`, clientText }) ); } } }); connection.sendText( JSON.stringify({ serverText: `server:hello,我们已经建立连接了`, clientText: `client:你好` }) ); connection.on('close', function (code, reason) { console.log('Connection closed'); console.log(code, reason); }); }) .listen(3000); tcp.on('error', (err) => { console.log(err); });
我们可以执行命令node server.js,打开浏览器http://localhost:8080/ 打开network,ws下面可以看到有客户端向服务端发送的消息,也有服务端向客户端发送的两条信息。
node server.js
http://localhost:8080/
network
我们看到请求头的一些信息
我们可以看到请求头里
Request URL: ws://192.168.31.40:3000/ Request Method: GET Status Code: 101 Switching Protocols
Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cache-Control: no-cache Connection: Upgrade Host: 192.168.31.40:3000 Origin: http://localhost:8080 Pragma: no-cache Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits Sec-WebSocket-Key: Mk8Au85XqQTn+vuDsfr/kw== Sec-WebSocket-Version: 13 Upgrade: websocket User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
当输入数字,向服务端发送消息时,服务端会返回对应信息。通常来讲,服务端会不定时的向前端推送信息,前端拿到推送信息进行一系列的页面状态展示等。
通过以上的例子,我们基础的了解到websocket的使用
websocket其实需要客户端对websocket处理主要是这三个步骤
更多websocket可以参考websocket
特点
基于
tcp
协议之上,服务端实现比较容易默认端口是
80(ws)
或者443(wss)
,握手阶段采用的http
协议数据格式比较轻量,性能开销小,通信高效
可以发送文本或者二进制数据
没有同源限制,客户端可以像任意服务发送信息
协议标识符是
ws
,如果加密,那么是wss
,实现客户端与服务端通信
新建一个
html
文件客户端代码在
html
中引入下面一段 js新建一个
server
目录,新建创建服务端代码,主要依赖nodejs-websocket
这个库是服务端websocket
代码。我们可以执行命令
node server.js
,打开浏览器http://localhost:8080/
打开network
,ws
下面可以看到有客户端向服务端发送的消息,也有服务端向客户端发送的两条信息。我们看到请求头的一些信息
我们可以看到请求头里
General
Request Headers
当输入数字,向服务端发送消息时,服务端会返回对应信息。通常来讲,服务端会不定时的向前端推送信息,前端拿到推送信息进行一系列的页面状态展示等。
通过以上的例子,我们基础的了解到
websocket
的使用总结
websocket
其实需要客户端对websocket
处理主要是这三个步骤更多
websocket
可以参考websocket