| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <!-- 顶栏订单消息通知 -->
- <template>
- <!-- <div class="large-screen-socket m-t-5 m-b-5 font-23"> -->
- <!-- <text class="m-r-20 text-white font-20">屏幕: {{deviceInfo.screenWidth}} * {{deviceInfo.screenHeight}}</text>
- <text class="p-r-10">
- <text v-if="socketOnlineStatus === 0" class="text-yellow">
- <text class="cuIcon-wifi"></text>
- <text class="m-l-8">连接中···</text>
- </text>
- <text v-if="socketOnlineStatus === 1" class="text-green">
- <text class="cuIcon-wifi"></text>
- <text class="m-l-8">在线</text>
- </text>
- <text v-if="socketOnlineStatus === 2" class="text-red">
- <text class="cuIcon-wifi"></text>
- <text class="m-l-8">关闭中</text>
- </text>
- <text v-if="socketOnlineStatus === 3" class="text-red">
- <text class="cuIcon-wifi"></text>
- <text class="m-l-8">已断开</text>
- </text>
- </text> -->
- <!-- </div> -->
- </template>
- <script>
- const app = getApp();
- import api from '@/utils/api'
- import util from '@/utils/util'
- import __config from '@/config/env';
- export default {
- name: 'LargeScreenSocket',
- props: {
- },
- data() {
- return {
- deviceInfo: app.globalData.systemInfo,
- //在线状态 0:CONNECTING 1:OPEN 2:CLOSING 3:CLOSED
- socketOnlineStatus: 0,
- // websocket相关
- socketObj: undefined, // websocket实例对象
- //心跳检测
- heartCheck: {
- // vue实例
- vueThis: this,
- // 心跳时间
- timeout: 1000 * 30,
- // 计时器对象——向后端发送心跳检测
- timeoutObj: null,
- // 计时器对象——等待后端心跳检测的回复
- serverTimeoutObj: null,
- // 心跳Key(和后台协商一致)
- heartBeatString: 'RS_LARGE_SCREEN_NOTICE_HEART_BEAT',
- // 心跳检测重置
- reset: function() {
- clearTimeout(this.timeoutObj);
- clearTimeout(this.serverTimeoutObj);
- return this;
- },
- // 心跳检测启动
- start: function() {
- this.timeoutObj && clearTimeout(this.timeoutObj);
- this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
- this.timeoutObj = setTimeout(() => {
- // 这里向后端发送一个心跳检测,后端收到后,会返回一个心跳回复
- uni.sendSocketMessage({
- data: this.vueThis.heartCheck.heartBeatString
- });
- //this.vueThis.socketObj.send(this.vueThis.heartCheck.heartBeatString);
- console.log('WebSocket',
- `发送心跳检测[KEY: ${this.vueThis.heartCheck.heartBeatString}]`)
- this.serverTimeoutObj = setTimeout(() => {
- // 如果超过一定时间还没重置计时器,说明websocket与后端断开了
- console.log('WebSocket', `未收到心跳检测回复`)
- // 关闭WebSocket
- this.vueThis.socketObj.close();
- }, this.timeout);
- }, this.timeout);
- },
- },
- socketReconnectTimer: null, // 计时器对象——重连
- socketReconnectLock: false, // WebSocket重连的锁
- socketLeaveFlag: false, // 离开标记(解决 退出登录再登录 时出现的 多次相同推送 问题,出现的本质是多次建立了WebSocket连接)
- };
- },
- created() {
- console.log('WebSocket', `离开标记: ${this.socketLeaveFlag}`)
- },
- mounted() {
- // websocket启动
- this.createWebSocket();
- },
- destroyed() {
- // 离开标记
- this.socketLeaveFlag = true;
- // 关闭WebSocket
- this.socketObj.close();
- },
- methods: {
- // websocket启动
- createWebSocket() {
- let baseSocketUrl = __config.socketBasePath;
- //let baseSocketUrl = process.env.VUE_APP_WS_BASE_URL;
- let webSocketLink = `${baseSocketUrl}/ws/large_screen/notice/${this.deviceInfo.deviceId}`;
- console.log('WebSocket', `远程连接地址: ${webSocketLink}`)
- try {
- this.socketObj = uni.connectSocket({ url: webSocketLink, complete: ()=> {} });
- // websocket事件绑定
- this.socketEventBind();
- } catch (e) {
- console.error("catch" + e);
- // websocket重连
- this.socketReconnect();
- }
- },
- // websocket事件绑定
- socketEventBind() {
- // 连接成功建立的回调
- uni.onSocketOpen(this.onopenCallback);
- // 连接发生错误的回调
- uni.onSocketError(this.onerrorCallback);
- // 连接关闭的回调
- uni.onSocketClose(this.oncloseCallback);
- // 向后端发送数据的回调
- //this.socketObj.onSend = this.onsendCallback;
- // 接收到消息的回调
- uni.onSocketMessage(this.getMessageCallback);
- },
- // websocket重连
- socketReconnect() {
- if (this.socketReconnectLock) {
- return;
- }
- this.socketReconnectLock = true;
- this.socketReconnectTimer && clearTimeout(this.socketReconnectTimer);
- this.socketReconnectTimer = setTimeout(() => {
- console.log('WebSocket', '重连中......')
- this.socketOnlineStatus = this.socketObj.readyState
- this.socketReconnectLock = false;
- // websocket启动
- this.createWebSocket();
- }, 4000);
- },
- // 连接成功建立的回调
- onopenCallback: function(event) {
- console.log('WebSocket', '已连接 SUCCESS ')
- this.socketOnlineStatus = 1
- // 心跳检测重置
- this.heartCheck.reset().start();
- },
- // 连接发生错误的回调
- onerrorCallback: function(event) {
- console.error('WebSocket', '发生错误')
- console.error(event)
- this.socketOnlineStatus = 3
- // websocket重连
- this.socketReconnect();
- },
- // 连接关闭的回调
- oncloseCallback: function(event) {
- console.error('WebSocket', '已关闭 CLOSE')
- this.socketOnlineStatus = 2
- // 心跳检测重置
- this.heartCheck.reset();
- if (!this.socketLeaveFlag) {
- // 没有离开——重连
- // websocket重连
- this.socketReconnect();
- }
- },
- // 向后端发送数据的回调
- onsendCallback: function() {
- console.log('WebSocket', '发送信息给后端')
- },
- // 接收到消息的回调
- getMessageCallback: function(msg) {
- if (JSON.stringify(msg.data).indexOf(this.heartCheck.heartBeatString) > -1) {
- // 心跳回复——心跳检测重置
- // 收到心跳检测回复就说明连接正常
- console.log('WebSocket', `收到心跳检测回复[KEY: ${this.heartCheck.heartBeatString}]`)
- // 心跳检测重置
- this.heartCheck.reset().start();
- } else {
- // 普通推送——正常处理
- console.log('WebSocket', '收到推送消息: ' + JSON.stringify(JSON.parse(msg.data), 'null', '\t'))
- let data = msg.data;
- // 相关处理
- //console.log('WebSocket', `接收到的数据并做相关处理: ${JSON.stringify(data)}`)
- this.$emit('receivedMessage', JSON.parse(data))
- }
- },
- },
- }
- </script>
- <style lang="scss" scoped>
- .large-screen-socket{
- width: 100%;
- text-align: right;
- }
- </style>
|