版本号:4.1.2
1、目录结构:(link.js、emit.js、on.js、methods.js)
(1)、link.js(连接)
import io from 'socket.io-client'
import {socket_on} from './on.js'
/**
* @enter socket信息
* @callback 回调
*/
//socket建立链接
export const link_socket = (enter, callback = () => {}) => {
if(!window.$socket_arr) window.$socket_arr = []//初始化socket集合
var obj = {
url: enter.url,
socket: null,
success: false // 是否链接成功
}
let timer = null//链接超时
//这里是避免多个socket链接
window.$socket_arr.forEach(item => {
if(enter.url === item.url){
obj = item
if(item.success) {
if(timer) clearTimeout(timer)//清空超时
callback({code:1, data:'已连接'})
}else{
setTimeout(() => {
link_socket(enter, callback)
},1000)
}
}
});
if(obj.socket && !obj.success) return
if( !obj.socket ){
obj.socket = io.connect(enter.url, {
reconnection: true,// 是否自动重连
reconnectionDelay: 500,// 重连间隔时间
reconnectionAttempts: 1000000000000,// 尝试重连次数
reconnectionDelayMax: 5000,// 重连间隔时间上限,即最长的重连间隔时间
...enter.data
})
window.$socket_arr.push(obj)
}
//链接成功
obj.socket.on('connect', (data) => {
if(timer) clearTimeout(timer)
obj.success = true
callback({code:1, data:'连接成功'})
console.log(obj.socket)
socket_on('public', obj.socket) // 开启public监听
socket_on('public2', obj.socket) // 开启public2监听
});
//断开链接
obj.socket.on('disconnect', (Reason) => {
obj.success = false
if(Reason === 'transport close') console.log('断开链接:连接被关闭(例如:用户失去连接,或者网络由WiFi切换到4G)')
else if(Reason === 'io server disconnect') console.log('断开链接:服务器使用socket.disconnect()强制断开了套接字。')
else if(Reason === 'io client disconnect') console.log('断开链接:使用socket.disconnect()手动断开socket。')
else if(Reason === 'ping timeout') console.log('断开链接:服务器没有在pingInterval + pingTimeout范围内发送PING')
else if(Reason === 'transport error') console.log('断开链接:连接遇到错误(例如:服务器在HTTP长轮询周期期间被杀死)')
else console.log('断开链接:', Reason)
});
obj.socket.on('connect_error', (data) => {
console.log(`连接错误,重连中:${data}`)
});
// 首次连接超时处理(5s)
timer=setTimeout(() => {
if(!obj.success){
obj.socket.close()
window.$socket_arr = window.$socket_arr.filter(item => {
return item.url! = obj.url
})
callback({code:0, data:'连接超时,检查服务'})
}
},5000)
}
(2)、emit.js(发送)
//发送事件
/**
* @emitName 发送方法名
* @enter 发送内容
*/
export const socket_emit = async (emitName='Public', enter ) => {
return new Promise(async resolve => {
var res = await getsocket(enter)
if(res.code ===0) resolve(res)
else{
res.data.emit(emitName,enter)
resolve({code:1, data:'发送成功'})
}
})
}
//获取 socket 对象
export const getsocket = (enter) => {
var obj = {url:enter.url, socket:null, success:false} //success:是否链接成功
window.$socket_arr.forEach(item => {
if(enter.url === item.url) obj=item
});
if(!obj.socket) return {code:0, data:'没查到socket连接'}
if(!obj.success) return {code:0, data:'socket未正常连接'}
return {code:1, data:obj.socket}
}
(3)、on.js(监听)
import Methods from './methods.js'
//监听事件
export const socket_on = async (onName = 'public', socket) => {
//是否存在监听,避免重复监听
let isOn = socket._callbacks[`$${onName}`]
if(isOn) return
socket.on(onName, async (data, callback) => {
// data 收到的内容
// callback 给服务端回调消息
//执行相对应的方法
if(Methods[onName]) Methods[onName](data, callback)
});
}
(4)、methods.js
// 监听事件相对应执行的方法
const public = async(data, callback) => {
console.log('执行public命令')
callback('回调给服务端,执行public命令成功')
}
const public2 = async(data, callback) => {
console.log('执行public2命令')
callback('回调给服务端,执行public2命令成功')
}
const methods={
public,
public2
}
export default methods;
使用方法:
// 1、连接
import {link_socket} from './socket/link.js'
let socket_enter = {
url:'http://127.0.0.1:3001',
data:{
// path:'/ws/socket.io', //url路由
// extraHeaders:{} // socket连接携带请求头
}
}
link_socket(socket_enter, res => {
console.log('连接回调', res)
})
// 2、发送消息
import {socket_emit} from './socket/emit.js'
socket_emit('方法名', ...发送内容)
// 3、监听消息(socket对象可以在emit.js文件里getsocket方法获取)
import {socket_on} from './socket/on.js'
socket_on('方法名', socket对象)
# 官方文档:https://socket.io/docs/v4/client-api/#flag-volatile
第一次发文章,用的上麻烦点个心~,后面会持续分享一些开发经验