介绍
最近正在做一个关于websocket实时双向通讯的聊天App 所用到的技术栈是socket.io实现实时双向通讯,在使用的过程中遇到一些问题 通过看一些大佬的文章和阅读文档 总结了一下常用的知识点 有不对的的地方 各位大佬多指教
方法一:
- 服务端使用ws
- 客户端使用原生websocket
ws是一种简单易用、快速且经过全面测试的Web套接字客户端和服务器实现。
/*
1.服务端安装ws npm i ws -S
2.引入ws
3.使用node运行文件
*/
import { WebSocketServer } from "ws";
//创建一个wbsocket服务实例对象
const server = new WebSocketServer({ port: 3000 });
server.on('connection',socket => {
//向每一个连接的客户端发送这条消息
socket.send(JSON.stringify({
type:'我是服务端发送过来的消息'
}))
//获取客户端发送过来的消息
socket.on('message',data => {
let Data = JSON.parse(data)
console.log(Data); // { type: '我是客户端发送的消息' }
})
//监听客户端断开
socket.on('close',()=> {
console.log('客户端断开连接');
})
})
// 客户端wbsocket
const socket = new WebSocket('ws://localhost:8000')
socket.addEventListener('open',() =>{ //一旦建立连接,向服务器发送这条消息
socket.send(JSON.stringify({
type:'我是客户端发送的消息'
}))
})
//客户端建立连接通过监听 message 事件来获取
socket.addEventListener('message',({data}) => {
console.log(JSON.parse(data)); //{type:'我是服务端发送过来的消息'}
})
方法二:
- 服务端使用socket.io
- 客户端使用socket.io-client
与上面相似使用方法不同 Socket.IO 提供了附加功能,这些功能隐藏了在生产环境中运行基于 WebSockets 的应用程序的复杂性、
/*
1.服务端安装 npm i socket.io-client
2.创建实例 通过socket.emit()发送事件 socket.on() 监听事件
*/
const Server = require('socket.io');
const io = new Server(3000);
io.on('connection',socket =>{
//发射msg事件传递数据
socket.emit('msg',1,(res) => {
console.log(res) //我是回调函数
})
//监听客户端发射的事件
socket.on('send',data => {
console.log(data) //{name:'我是客户端传递给服务端的数据'}
})
})
注意:版本不能相差太大 否则可能造成连接上了 而无法推送数据
/*
1.客户端安装 npm i socket.io-client
2.创建实例 通过socket.emit()发送事件 socket.on() 监听事件
*/
<script src="../node_modules/socket.io-client/dist/socket.io.js"></script>
const socket = io('http://localhost:3000')
socket.on('msg',(data,callback) => { //监听客户端事件
console.log(args) // 1
callback('我是回调函数')s
})
socket.emit('send',{name:'我是客户端传递给服务端的数据'})
在服务器端,您可以向所有连接的客户端或客户端的子集发送事件:
// to all connected clients
io.emit("hello");
// to all connected clients in the "news" room
io.to("news").emit("hello");
命名空间允许您在单个共享连接上拆分应用程序的逻辑。例如,如果您想创建一个只有授权用户才能加入的“管理员”频道,这可能很有用。
io.on("connection", (socket) => {
// classic users
});
io.of("/admin").on("connection", (socket) => {
// admin users
});
服务器端
io.on("connection", (socket) => {
//基本发射
socket.emit(/* ... */);
// 发送给当前命名空间中除发件人以外的所有客户端
socket.broadcast.emit(/* ... */);
// 发送给除sende以外的room1中的所有客户
socket.to("room1").emit(/* ... */);
// 发送给除发件人以外的room1和/或room2中的所有客户端
socket.to(["room1", "room2"]).emit(/* ... */);
// 发送room1中的所有客户
io.in("room1").emit(/* ... */);
// 发送于除3号房间以外的1号房间和/或2号房间的所有客户
io.to(["room1", "room2"]).except("room3").emit(/* ... */);
// “我的命名空间”中的所有客户端
io.of("myNamespace").emit(/* ... */);
// 至命名空间“my namespace”中room1中的所有客户端
io.of("myNamespace").to("room1").emit(/* ... */);
// 至单个socketid(专用消息)
io.to(socketId).emit(/* ... */);
// 此节点上的所有客户端(使用多个节点时)
io.local.emit(/* ... */);
// 到所有连接的客户端
io.emit(/* ... */);
// 指定事件
socket.emit("question", (answer) => {
// ...
});
// 无压缩
socket.compress(false).emit(/* ... */);
// 如果低级传输不可写,则可能会丢弃的消息
socket.volatile.emit(/* ... */);
// with timeout
socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// 另一方未在给定延迟内确认事件
}
});
});
客户端
//基本发射
socket.emit(/* ... */);
// 指定事件
socket.emit("question", (answer) => {
// ...
});
// 无压缩
socket.compress(false).emit(/* ... */);
// 如果低级传输不可写,则可能会丢弃的消息
socket.volatile.emit(/* ... */);
// with timeout
socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// 另一方未在给定延迟内确认事件
}
});
事件
在每一侧,以下事件是保留的,不应被您的应用程序用作事件名称:
connectconnect_errordisconnectdisconnectingnewListenerremoveListener
// 引发错误时
socket.emit("disconnecting");)