本文介绍: keyword:websocket回调websocketajax一样,websocket接口请求同步回调websocket MVC框架前言传统http连接拉取接收数据浪费资源tcp每次都得建立连接三次握手,释放,只能单向通信定时轮询。而websocket可以建立长连接,后一直保持,节约服务器资源,跟每台客户机只维持一个连接就行。节省流量需要频繁地发起关闭tcp连接,可以双向通信协议以及数据格式自己算了算,省略HTTP上不必要的信息基于以上原因开发一套socket框架

keyword:websocket回调websocketajax一样,websocket接口请求,同步回调,websocket MVC框架

前言

传统http短连接拉取接收数据浪费资源tcp每次都得建立连接,三次握手,释放,只能单向通信定时轮询。
而websocket可以建立长连接,后一直保持,节约服务器资源,跟每台客户机只维持一个连接就行。
节省流量需要频繁地发起关闭tcp连接,可以双向通信
协议以及数据格式自己算了算,浏览器app、物联网多种设备一套接口通用,省略HTTP上不多余的信息

基于以上原因开发一套socket框架来代替http ajax模式,同时保持跟http一样容易上手

目的

用websocket实现Ajax回调效果,所有接口请求用websocket进行,
想要使websocket发送消息实现ajax回调消息那种效果发送出去,然后回调函数收到服务器发送来的消息

难点

websockethttp不同的之处在于,http发的请求是同步的,浏览器发起请求会同步等待服务器返回,而socket发送完了就结束了,不管服务器又没返回,而且先发地数据不一定先收到,不按顺序返回
难点就在于发送数据ws.send函数里,而接收数据ws.onmessage里,数据不能互通

原理

解决方法
发送消息时候把回调函数存到一个数组中,数组下标用唯一键名避免冲突,键名要发送给服务器服务器返回数据时候要带上,
收到服务器消息时,取出键名去调用数组对应的回调函数,把数据传入回调函数执行回调操作
这样就实现了跟ajax一样的效果

实现

代码示例
socket.js

//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 &amp;&amp; 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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注