preface
Recently, webSocket has been used in the development of H5 and APP. Sometimes the network of web/app is unstable or the server is disconnected actively, which leads to the failure of message push, and the client needs to be reconnected. After consulting the data, we found a heartbeat mechanism, that is, the client sends a message to the server at an interval of time. If the server receives the message, it will reply with a message. If there is no reply within a certain period of time, it means that it has been disconnected from the server, and reconnection is required at this time.
The passive disconnection is reconnected, and the active disconnection is not reconnected.
Note: for the two Tab items (Open Trades and Closed Trades) in the following figure, you only want to trigger the webSocket when tabIndex = 0 (when Open Trades is highlighted). If you click the second column and tabIndex = 1 (when Closed Trades is highlighted), you will actively close the webSocket connection.
When TabIndex = 0, passive disconnection automatically reconnects
Original link: The use of websocket in uni app the mechanism of disconnection, reconnection and heartbeat
effect
- Websocket connects and receives push messages
- Convert the received message into target data and render it
- If it is actively closed, it will not be reconnected and the closing event will be monitored
- The display is closed and will not be reconnected
- Listening for error events, such as address and protocol errors, will automatically reconnect five times. After five reconnections still fail, you need to manually reconnect
- If the server actively disconnects, the heartbeat mechanism will send a piece of data to the server at regular intervals. If there is no reply, it will reconnect the websocket.
code
- Create a new socket JS, copy the following code and expose it to the outside.
import api from '@/common/js/config.js' // Interface Api, picture address and other configurations can be introduced according to your own situation, or you can directly fill in your webSocket connection address in the following url class socketIO { constructor(data, time, url) { this.socketTask = null this.is_open_socket = false //Avoid duplicate connections this.url = url ? url : api.websocketUrl //Connection address this.data = data ? data : null this.connectNum = 1 // Reconnection times this.traderDetailIndex = 100 // traderDetailIndex ==2 reconnection this.accountStateIndex = 100 // traderDetailIndex ==1 reconnection this.followFlake = false // traderDetailIndex == true reconnection //Heartbeat detection this.timeout = time ? time : 15000 //How many seconds does the test take this.heartbeatInterval = null //Check whether the server side is still alive this.reconnectTimeOut = null //How long after reconnection } // When entering this page, create a websocket connection [the whole page can be used at any time] connectSocketInit(data) { this.data = data this.socketTask = uni.connectSocket({ url: this.url, success: () => { console.log("Preparing to establish websocket in..."); // Return instance return this.socketTask }, }); this.socketTask.onOpen((res) => { this.connectNum = 1 console.log("WebSocket The connection is normal!"); this.send(data) clearInterval(this.reconnectTimeOut) clearInterval(this.heartbeatInterval) this.is_open_socket = true; this.start(); // Note: messages can be received only when the connection is opened normally this.socketTask.onMessage((e) => { // String to json let res = JSON.parse(e.data); console.log("res---------->", res) // Here to view the pushed messages if (res.data) { uni.$emit('getPositonsOrder', res); } }); }) // Failed to listen to the connection. The reason I commented out here is that if the server is shut down, it will initiate the reconnection operation together with the onclose method below, which will lead to repeated connections uni.onSocketError((res) => { console.log('WebSocket Connection opening failed, please check!'); this.socketTask = null this.is_open_socket = false; clearInterval(this.heartbeatInterval) clearInterval(this.reconnectTimeOut) uni.$off('getPositonsOrder') if (this.connectNum < 6) { uni.showToast({ title: `WebSocket Connection failed, trying to connect ${this.connectNum}Secondary connection`, icon: "none" }) this.reconnect(); this.connectNum += 1 } else { uni.$emit('connectError'); this.connectNum = 1 } }); // Here is only event listening [it will be executed if the socket is closed] this.socketTask.onClose(() => { console.log("It has been closed-------") clearInterval(this.heartbeatInterval) clearInterval(this.reconnectTimeOut) this.is_open_socket = false; this.socketTask = null uni.$off('getPositonsOrder') if (this.connectNum < 6) { this.reconnect(); } else { uni.$emit('connectError'); this.connectNum = 1 } }) } // Actively close socket connection Close() { if (!this.is_open_socket) { return } this.socketTask.close({ success() { uni.showToast({ title: 'SocketTask Closed successfully', icon: "none" }); } }); } //send message send(data) { console.log("data---------->", data); // Note: messages can be sent successfully only when the connection is opened normally if (this.socketTask) { this.socketTask.send({ data: JSON.stringify(data), async success() { console.log("Message sent successfully"); }, }); } } //Turn on heartbeat detection start() { this.heartbeatInterval = setInterval(() => { this.send({ "traderid": 10260, "type": "Ping" }); }, this.timeout) } //Reconnect reconnect() { //Stop sending heartbeat clearInterval(this.heartbeatInterval) //If it is not shut down manually, reconnect if (!this.is_open_socket && (this.traderDetailIndex == 2 || this.accountStateIndex == 0 || this .followFlake)) { this.reconnectTimeOut = setInterval(() => { this.connectSocketInit(this.data); }, 5000) } } /** * @description Filter the socket data * @param {array} array * @param {string} type Distinguish pop-up openposition into follow and mine */ arrayFilter(array, type = 'normal', signalId = 0) { let arr1 = [] let arr2 = [] let obj = { arr1: [], arr2: [] } arr1 = array.filter(v => v.flwsig == true) arr2 = array.filter(v => v.flwsig == false) if (type == 'normal') { if (signalId) { arr1 = array.filter(v => v.flwsig == true && v.sigtraderid == signalId) return arr1 } else { return arr1.concat(arr2) } } else { if (signalId > 0) { arr1 = array.filter(v => v.flwsig == true && v.sigtraderid == signalId) obj.arr1 = arr1 } else { obj.arr1 = arr1 } obj.arr2 = arr2 return obj } } } module.exports = socketIO
- Mount socket io on the Vue prototype in the portal file, or introduce the top page as needed.
import socketIO from '@/common/js/scoket.js' Vue.prototype.socketIo = new socketIO()
- The following methods are used in the pages that need WebSockets (which can be rectified according to their own business needs)
scoketClose() { this.socketIo.connectNum = 1 const data = { "value1": "demo1" "value2": "demo2" } this.socketIo.send(data) // This is to send specific data to the back end and turn off push this.socketIo.Close() // Actively close the connection without reconnecting }, getWebsocketData() { // Packets to send const data = { "value": "value1", "type": "type1" } // open a connection this.socketIo.connectSocketInit(data) // receive data uni.$on("getPositonsOrder", (res) => { this.connect = true const { Code, data } = res if (Code == xxxx) { // Write the business according to the data transmitted from the back end... } else { } }) // What do you do when you make a mistake uni.$on("connectError", () => { this.connect = false this.scoketError = true }) }
- Leave the page and remember to disconnect.
onUnload() { this.scoketClose() this.socketIo.traderDetailIndex = 100 // Initialize tabIndex }
Problems encountered
If you encounter any problems in use, you can give it to me Leave a message , you will reply as soon as you see the message.
This article is from the blog Park and written by: Ah Mu For reprint, please indicate the original link: Use of websocket in uni app disconnection and reconnection, heartbeat mechanism - ah mu - blog Garden