uniapp连接websocket报错?

论坛问题: https://ask.dcloud.net.cn/question/74505

使用: uni.connectSocket(OBJECT) 和  SocketTask.onOpen(CALLBACK) 在安卓手机无法触发websocket的open方法

解决办法使用plus-websocket插件

https://ext.dcloud.net.cn/plugin?id=647

注意方法使用:

socket.connectSocket(OBJECT)

  • socket.onSocketOpen(CALLBACK)
  • socket.onSocketError(CALLBACK)
  • socket.sendSocketMessage(OBJECT)
  • socket.onSocketMessage(CALLBACK)
  • socket.closeSocket(OBJECT)
  • socket.onSocketClose(CALLBACK)

转载大佬的插件案例: https://www.jianshu.com/p/241fd3a81c3f

/**uni websocket工具类*/
//npm i plus-websocket --save
import socket from ‘plus-websocket‘
export default class websocket {
    constructor({
        heartCheck,
        isReconnection
    }) {
        // 是否连接
        this._isLogin = false;
        // 当前网络状态
        this._netWork = true;
        // 是否人为退出
        this._isClosed = false;
        // 心跳检测频率
        this._timeout = 3000;
        this._timeoutObj = null;
        // 当前重连次数
        this._connectNum = 0;
        // 心跳检测和断线重连开关,true为启用,false为关闭
        this._heartCheck = heartCheck;
        this._isReconnection = isReconnection;
        // this._onSocketOpened();
    }
    // 心跳重置
    _reset() {
        clearTimeout(this._timeoutObj);
        return this;
    }
    // 心跳开始
    _start() {
        let _this = this;
        this._timeoutObj = setInterval(() => {
            //发送心跳
            _this.sendHeartbeatData();
        }, this._timeout);
    }
    // 监听websocket连接关闭
    onSocketClosed(options) {
        socket.onSocketClose(err => {
            console.log(‘当前websocket连接已关闭,错误信息为:‘ + JSON.stringify(err));
            // 停止心跳连接
            if (this._heartCheck) {
                this._reset();
            }
            // 关闭已登录开关
            this._isLogin = false;
            // 检测是否是用户自己退出小程序
            if (!this._isClosed) {
                // 进行重连
                if (this._isReconnection) {
                    this._reConnect(options)
                }
            }

        })
    }
    // 检测网络变化
    onNetworkChange(options) {

        uni.onNetworkStatusChange(res => {
            console.log(‘当前网络状态:‘ + res.isConnected);
            if (!this._netWork) {
                this._isLogin = false;
                // 进行重连
                if (this._isReconnection) {
                    this._reConnect(options)
                }
            }
        })
    }
    _onSocketOpened() {
        socket.onSocketOpen(res => {
            console.log(‘【websocket】已打开‘);
            // 打开已登录开关
            this._isLogin = true;
            // 发送心跳
            if (this._heartCheck) {
                this._reset()._start();
            }
            // 发送登录信息
            this.sendLoginData();
            // 打开网络开关
            this._netWork = true;
        })
    }
    // 接收服务器返回的消息
    onReceivedMsg(callBack) {
        socket.onSocketMessage(event => {
            let msg = this.socketEventDataToStr(event)
            // console.log(msg);
            if (typeof callBack == "function") {
                callBack(msg)
            } else {
                console.log(‘参数的类型必须为函数‘)
            }
        })
    }

    // 建立websocket连接
    initWebSocket(options) {

        let _this = this;
        if (this._isLogin) {
            console.log("您已经登录了");
        } else {
            // 检查网络
            uni.getNetworkType({
                success(result) {
                    if (result.networkType != ‘none‘) {
                        // 开始建立连接
                        console.log(‘建立websocket连接‘ + options.url);
                        socket.connectSocket({
                            url: options.url,
                            success(res) {
                                if (typeof options.success == "function") {
                                    options.success(res)
                                    _this._onSocketOpened();
                                } else {
                                    console.log(‘参数的类型必须为函数‘)
                                }
                            },
                            fail(err) {
                                if (typeof options.fail == "function") {
                                    options.fail(err)
                                } else {
                                    console.log(‘参数的类型必须为函数‘)
                                }
                            }
                        })
                    } else {
                        console.log(‘网络已断开‘);
                        _this._netWork = false;
                        // 网络断开后显示model
                        uni.showModal({
                            title: ‘网络错误‘,
                            content: ‘请重新打开网络‘,
                            showCancel: false,
                            success: function(res) {
                                if (res.confirm) {
                                    console.log(‘用户点击确定‘)
                                }
                            }
                        })
                    }
                }
            })
        }
    }
    // 发送websocket消息
    sendWebSocketMsg(options) {
        this.sendBinary(1,options);
    }

    //发送心跳连接
    sendHeartbeatData() {
        this.sendBinary(99, {
            data: {},
            success(res) {
                console.log(‘【websocket】心跳连接成功‘)
            },
            fail(err) {
                console.log(‘【websocket】心跳连接失败‘)
                console.log(err)
            }
        });
    }

    //发送第一次连接数据
    sendLoginData() {
        this.sendBinary(99, {
            data: {},
            success(res) {
                console.log(‘【websocket】第一次连接成功‘)
            },
            fail(err) {
                console.log(‘【websocket】第一次连接失败‘)
                console.log(err)
            }
        });
        // this.sendBinary(99, {});
        // socket.sendSocketMessage({
        //  // 这里是第一次建立连接所发送的信息,应由前后端商量后决定
        //  data: JSON.stringify({
        //      "key": ‘value‘
        //  })
        // })
    }

    // 重连方法,会根据时间频率越来越慢
    _reConnect(options) {
        let timer, _this = this;
        if (this._connectNum < 20) {
            timer = setTimeout(() => {
                this.initWebSocket(options)
            }, 3000)
            this._connectNum += 1;
        } else if (this._connectNum < 50) {
            timer = setTimeout(() => {
                this.initWebSocket(options)
            }, 10000)
            this._connectNum += 1;
        } else {
            timer = setTimeout(() => {
                this.initWebSocket(options)
            }, 450000)
            this._connectNum += 1;
        }
    }
    // 关闭websocket连接
    closeWebSocket() {
        socket.closeSocket();
        this._isClosed = true;
    }

    //发送二进制
    sendBinary(commendType, options) {
        let sendMsg = options.data
        let uint8Array = new TextEncoder().encode(JSON.stringify(sendMsg));
        let byteArr = new ArrayBuffer(4 + uint8Array.length);
        //DataView有三个参数,后两个可以缺省;每一个要是ArrayBuffer对象或SharedArrayBuffer对象
        let dv = new DataView(byteArr);
        dv.setUint32(0, commendType, false);
        for (let i = 0; i < uint8Array.length; i++) {
            dv.setUint8(4 + i, uint8Array[i]);
        }
        // console.log(dv);
        socket.sendSocketMessage({
            data: dv.buffer,
            success(res) {

                if (typeof options.success == "function") {
                    options.success(res)
                } else {
                    console.log(‘参数的类型必须为函数‘)
                }
            },
            fail(err) {
                if (typeof options.fail == "function") {
                    options.fail(err)
                } else {
                    console.log(‘参数的类型必须为函数‘)
                }
            }
        });
    }

    //转化方法
    socketEventDataToStr(event) {
        let dv = new DataView(event.data);
        let commendType = dv.getUint32(0, true);
        let slice = event.data.slice(4, event.data.length);
        let unit8Arr = new Uint8Array(slice);
        let s = new TextDecoder("utf-8").decode(unit8Arr);
        console.log("【websocket】标志位:" + commendType);
        console.log("【websocket】返回信息:" + s);
        return s;
    }

}

转载简书大佬的案例

原文地址:https://www.cnblogs.com/yxgmagic/p/11791366.html

时间: 2024-10-26 20:23:05

uniapp连接websocket报错?的相关文章

连接mysql报错:error 2003 (hy000):can&#39;t connect to mysql server on &#39;localhost&#39; (10061)

一.mysql 的bin目录下有个MySQLInstanceConfig.exe,运行就可以进行创建数据库实例,创建实例时也可以生成windows 服务,把服务设置成自动启动就可以了 二.安装在D盘的discuzz!打开后出现上述错误,请问应如何处理?winmysqladmin已经启动,但三色树上有一个小红点如果出现"ERROR 2003: Can't connect to MySQL server on 'localhost' (10061)",说明你的MySQL还没有启动.解决办法

使用plSQL连接Oracle报错,SQL*Net not properly installed和TNS:无法解析指定的连接标识符

1.在64位机器上了64位的oracle客户端.然后装上PL/SQL Developer,但是连接oracle老报这个错: 解决办法:在64位的机器上安装32位的Oracle客户端.这样的话便连接成功. 依据:从安装角度考虑,32bit的平台(操作系统和硬件系统)只支持32bitORACLE的安装:64bit平台既支持32bitORACLE的安装也支持64位ORACLE的安装 2.重新安装32的oracle客户端解决了第一个问题,但是用plsql连接接着报错:“TNS:无法解析指定的连接标识符”

PHP连接MySQL报错:SQLSTATE[HY000] [2002] Can&#39;t connect to local MySQL server through socket &#39;MySQL&#39; (2)

如下所示,PHP连接MySQL报错: SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket 'MySQL' (2) 测试代码如下: <?php try { $dsn = 'mysql:dbname=php-note;host=localhost;port=3306;charset=utf8'; $username = 'root'; $password = 'root'; new PDO( $dsn,

java连接sqlserver2008报错 java.sql.SQLException: 对象名 &#39;表名&#39; 无效.

注意:c3p0的数据库配置方式为: <named-config name="sqlsvr"> <property name="driverClass">net.sourceforge.jtds.jdbc.Driver</property> <property name="jdbcUrl">jdbc:jtds:sqlserver://localhost:1433/WaterNet_DaFeng<

Window2003 64位IIS连接ACCESS报错“Microsoft.Jet.OLEDB.4.0”问题

Window2003 64位IIS连接ACCESS报错“Microsoft.Jet.OLEDB.4.0”问题 由于64位操作系统不支持Microsoft OLE DB Provider for Jet驱动程序,也不支持更早的Microsoft Access Driver (*.mdb)方式连接.所以用于Access 和 Excel 数据库的 MicrosoftOLE DB Provider for Jet 在 64 位版本中不可用,也就是说,如下两种连接字符串都已经无法正常工作了:"Provid

jdbc连接sqlserver报错java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerDriver

使用2008的数据库, 我已经引入的sqljdbc4的包,单还是报这个错,很奇怪突然想到在配置hibernate的时候,是拷贝下来的代码 然后到网上查了下, 因为是2008的版本驱动和2000的有点不同, 之前的都是可能是2000或者2005的class是com.microsoft.jdbc.sqlserver.SQLServerDriver 可是2008  去是com.microsoft.sqlserver.jdbc.SQLServerDriver 就这么改过来就可以了 jdbc连接sqlse

Atom远程连接服务器报错服务器版本和客户端版本不一致

Atom远程连接服务器 报错信息: Server version is different than client version Original error message: Version mismatch. Client at 139 while server at 141. 在setting里check for update 一下,然后重启编辑器!!!重启

redis运用连接池报错解决

redis使用连接池报错解决redis使用十几小时就一直报异常 redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at redis.clients.util.Pool.getResource(Pool.java:22) at com.derbysoft.jredis.longkeytest.BorrowObject.run(BorrowObject.jav

jdbc连接mysql报错:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column &#39;&#233;?‘&#229;?‰&#230;—&#173;&#39; in &#39;field list&#39;

解决了中文显示乱码问题之后,又出现了这么一个问题, 思考一下,这绝对是输入文本的问题. 试了一下,果然不出所料. 再次怀疑编码,没有办法, 只有很无奈地去百度了,结果是与编码没有问题啊. sql.execute("insert into reader values('"+rn+"','"+pid+"','"+tele+"','"+kno+"')"); 原来报错是因为我没写单引号,mysql当然不认识啊.OK