keyword:websocket回调,websocket像ajax一样,websocket接口请求,同步回调,websocket MVC框架
前言
传统http短连接拉取接收数据太浪费资源,tcp每次都得建立连接,三次握手,释放,只能单向通信,定时轮询。
而websocket可以建立长连接,后一直保持,节约服务器资源,跟每台客户机只维持一个连接就行。
节省流量 不需要频繁地发起关闭tcp连接,可以双向通信,
协议以及数据格式自己算了算,浏览器、app、物联网多种设备一套接口通用,省略HTTP上不多余的信息,
基于以上原因,开发一套socket框架来代替http ajax模式,同时保持跟http一样容易上手
目的
用websocket实现Ajax回调效果,所有接口请求用websocket进行,
想要使websocket发送的消息实现跟ajax回调消息那种效果,发送出去,然后回调函数里收到服务器发送来的消息
难点
websocket与http不同的之处在于,http发的请求是同步的,浏览器发起请求会同步等待服务器返回,而socket是发送完了就结束了,不管服务器又没返回,而且先发地数据不一定先收到,不按顺序返回,
难点就在于发送数据在ws.send函数里,而接收数据在ws.onmessage里,数据不能互通
原理
解决方法
发送消息的时候把回调函数存到一个数组中,数组下标用唯一键名避免冲突,键名要发送给服务器,服务器返回数据的时候要带上,
收到服务器消息时,取出键名去调用数组中对应的回调函数,把数据传入回调函数执行回调操作
这样就实现了跟ajax一样的效果
实现
//websocket地址
let host = "ws://localhost:8282";
let ws = null;
let socketOpen = false;
let callbackArr = [];
let msgArr = [];
//心跳时间
let heartCheckTime = 45000;
//重连尝试次数
let reconnectTime = 0;
function wsConnect() {
ws = new WebSocket(host);
// 打开socket连接
ws.onopen = e => {
socketOpen = true;
console.log('连接成功');
//待发送消息队列
if (msgArr.length) {
for (let i in msgArr) {
sendMsg(msgArr[i].data, msgArr[i].callback)
}
msgArr = []
}
// 心跳
heartCheck()
};
// socketClose
ws.onclose = e => {
console.log('连接已断开', e);
socketOpen = false;
reconnect();
};
//连接发生错误
ws.onerror = e => {
console.log('连接发生错误', e);
socketOpen = true;
reconnect();
};
//接收消息
ws.onmessage = e => {
// 按api保存回调
let callBackData = JSON.parse(e.data);
let key = callBackData.key;
if (!key) return;
callbackArr[key](callBackData)
}
}
// 发送消息
function send(data, callback) {
callbackArr[data.key] = callback
if (socketOpen) {
ws.send(JSON.stringify(data))
} else {
// 未开启,加入队列
msgArr.push({data, callback});
wsConnect();
}
}
// 心跳检测
function heartCheck() {
if (socketOpen) {
setInterval(() => {
ws.send('ping')
console.log("发送ping", heartCheckTime)
}, heartCheckTime);
}
}
// 重连
function reconnect() {
if (!socketOpen && reconnectTime <= 10) {
setTimeout(() => {
wsConnect()
reconnectTime++
console.log('重新连接', reconnectTime)
}, 2000)
}
}
module.exports.send = send
调用
const socket = require('./socket.js');
socket.send({
api: 'login',
app: 'ios',
key: 'callback'+new Date().getTime()+Math.round(Math.random()*10),
data: {name: 'admin',password:'123456'}
}, res => {
if (res.code == 0) {
console.log(res)
}
})
具体字段跟协议根据实际情况设计,我后端用的是php,基于workerman跟thinkOrm封装的一套框架,基本用法跟thinkphp一致,现在全部接口都用websocket,如需参考请移步
https://github.com/feixuekeji/flysocket
flysocket
flysocket是一款基于GatewayWorker开发的的支持双向通信长连接websocketMVC开发框架,适用于前后端通过长连接进行通讯的web项目,游戏服务器,同时也适用于开发tcp长连接应用如即时通信、物联网、消息推送、智能家居等。
开发初衷是为了实现客户端(包括浏览器web,APP,小程序,物联网设备)与服务端通信使用统一的socket长连接接口,开发一套接口用于多种客户端,服务器与客户端保持长连接,解决传统http模式每次连接都要初始化浪费系统资源的问题。
框架是一个通过websocket协议的MVC框架,前后端数据以json格式传输,框架多处参考thinkPHP,用法也尽量保持了跟tp方法一致,跟传统http项目一样容易上手。
原文地址:https://blog.csdn.net/flysnownet/article/details/124492197
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_25560.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!