前言——学习自Bilibili后学习复盘使用。
WebSockets原理,握手和代码实现!用Socket.io制作实时聊天室_哔哩哔哩_bilibili
原理
对于客户端发请求形象为把腿毛,服务器端响因为疼痛发出叫声。
HTTP
拔一下叫一下,拔完后叫
长轮询(long polling)
但我想让你一直叫,就揪着腿毛不放(即服务器端持续响应,而不是等到请求后再响应,客户端http请求保持一段时间)
但出现弊端,这段叫的时间中有几个瞬间我没发力(即请求服务器仍在响应等待请求)
WebSockets
设计制作"实时"应用协议,开始时使用HTTP后期使用TCP持久连接
你拔我的毛,我也拔你的,相互叫。
请求uri:
websockets请求体:
服务器返回:
WebSocket代码
使用node.js (小后端语言)
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const ws = new WebSocket('ws://localhost:3000');
ws.addEventListener('open', () => {
console.log('连接成功');
ws.send('前端发送的消息');
});
</script>
</body>
</html>
前端返回
后端代码:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3000 });
wss.on('connection', ws=>{
console.log('Client connected');
ws.on('message', message=>{
console.log(`Received: ${message}`);
ws.send(`You sent -> ${message}`);
});
ws.on('close', ()=>{
console.log('Client disconnected');
});
})
后端返回
Socket.io
对不支持websocket的浏览器使用长轮询,并支持自动重连。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat App</title>
<style>
.box{
height: 10px;
width: 100px;
}
</style>
</head>
<body>
<form>
<input type="text" class="box" placeholder="Type a message">
<button>发送</button>
</form>
<ul></ul>
<script src="/socket.io/client-dist/socket.io.js"></script>
<script>
const socket = io();
const form = document.querySelector('form');
const input = document.querySelector('input'); // 这里 input 标签是正确的,所以可以获取到
const ul = document.querySelector('ul');
form.addEventListener('submit', e => {
e.preventDefault();
if (input.value.trim()) { // 确保输入值不是空白
socket.emit('chat message', input.value);
input.value = '';
}
});
socket.on('chat message', msg => {
const li = document.createElement('li');
li.textContent = msg;
ul.appendChild(li);
});
</script>
</body>
</html>
const app = require('express')();
const server = require('http').createServer(app);
const {Server} = require('socket.io');
const io = new Server(server);
app.get('/', (req, res)=>{
res.sendFile(__dirname + '/index.html');
});
io.on('connection', socket=>{
console.log('Client connected');
socket.on('chat message', msg=>{
io.emit('chat message', msg);
});
socket.on('disconnect', ()=>{
console.log('Client disconnected');
});
});
server.listen(3000, ()=> '服务器启动成功');