This is the second day of my participation in Gwen Challenge
Remax has been used for a long time, previously using javascript versions
In June, the project was ready for Typescript refactoring, so we rethought a version
A little knowledge
Wx. connectSocket of wechat applet can only make a maximum of two requests to a WS/WSS websocket at the same time, and can use a maximum of 5 connections for multiple different Websocket addresses.
Wechat SocketTask is a SocketTask object that can be returned after a connectSocket is used to establish a connection. You can store this connection internally. It is not recommended because websocket connections are likely to be lost when the page is refreshed. Using localstroage to cache the socket is not available. Therefore, it is recommended to instantiate each time a new WebSocket connection is used. Then pass in the corresponding WS/WSS connection for linking operation.
Wx.connectsocket -> wx.onSocketOpen -> wx.onReceivedMsg -> Wx.onReceivedMsg -> Wx.onSocketOpen -> Wx.onReceivedMsg -> wx.sendSocketMessage
So when you cannot send or receive data from the server and push data to the server, you should check the execution timing.
filename: src/utils/websocket.ts
import {
connectSocket,
closeSocket,
onSocketOpen,
onSocketClose,
sendSocketMessage,
onSocketMessage,
getNetworkType,
onNetworkStatusChange,
} from 'remax/wechat';
class Websocket {
// Whether to connect
isConnect: boolean = false;
// Current network status
private netWork: boolean = false;
// Whether to exit manually
private isClosed: boolean = false;
// Heartbeat detection frequency
private timeout: number = 3 * 1000;
private timeoutObj: NodeJS.Timeout | undefined;
// Number of current reconnections
private connectNum: number = 0;
// Heartbeat detection and disconnection reconnection switch. The value can be true or false
heartCheck: boolean = false
isReconnect: boolean = false
// Connection information
wsUrl = ' '
// Message queue
messageQueue = []
constructor(heartCheck: boolean = false, isReconnect: boolean = false) {
// Heartbeat detection and disconnection reconnection switch. The value can be true or false
this.heartCheck = heartCheck;
this.isReconnect = isReconnect;
}
// The heartbeat starts
start() {
const self = this;
this.timeoutObj = setInterval(() = > {
sendSocketMessage({
// Send heartbeat message
data: JSON.stringify({
beat: 'dj',}).success() {
// console.log(" Heartbeat sent successfully ");
},
fail(err) {
console.log(err);
console.log('Connection failed');
self.reConnect()
self.reset();
},
}).then();
}, this.timeout);
}
// Heartbeat reset
reset() {
if (this.timeoutObj) {
clearTimeout(this.timeoutObj);
}
// Return this to support chained calls
return this;
}
// Initialize the connection
init(wsUrl: string) {
if (this.isConnect) {
this.onSocketOpened()
this.onNetworkChange()
this.onSocketClosed()
} else {
// Check network status
const self = this;
getNetworkType({
success(res) {
if(res.networkType ! = ='none') {
// Start establishing a connection
console.log('Start connection')
self.connect(wsUrl)
} else {
self.netWork = false;
console.log('Network disconnected'); } }, }).then(); }}/ / the websocket connection
connect(wsUrl: string) {
// connectSocket does not support asynchronous calls
let self = this;
connectSocket({
url: wsUrl,
success(res) {
if (res.errMsg == 'connectSocket:ok') {
self.isConnect = true
self.wsUrl = wsUrl
self.onSocketOpened()
self.onNetworkChange()
self.onSocketClosed()
}
},
fail(err) {
console.log(err)
},
});
}
// The reconnection method will be slower and slower depending on the time frequency, respectively 3 seconds, 10 seconds, 45 seconds
reConnect() {
console.log(this.connectNum)
if (!this.isConnect) {
if (this.connectNum < 3) {
setTimeout(() = > {
this.init(this.wsUrl);
}, 3 * 1000);
this.connectNum += 1;
} else if (this.connectNum < 10) {
setTimeout(() = > {
this.init(this.wsUrl);
}, 10 * 1000);
this.connectNum += 1;
} else {
setTimeout(() = > {
this.init(this.wsUrl);
}, 45 * 1000);
this.connectNum += 1; }}}// Close the webSocket connection
close() {
if (this.isConnect) {
closeSocket().then()
// Reset the heartbeat and change the corresponding state
this.reset()
this.isClosed = true;
this.isConnect = false;
} else {
console.warn('No Websocket connection')}}// The webSocket connection is closed
onSocketClosed() {
onSocketClose((err) = > {
console.log('The current WebSocket connection is closed with the following error message:The ${JSON.stringify(err)}`);
// Stop the heartbeat connection
if (this.heartCheck) {
this.reset();
}
// Turn off the logon switch
this.isConnect = false;
// Check if the user exits the applet
if (!this.isClosed) {
console.log('Came in here... ')
// Reconnection
if (this.isReconnect) {
this.reConnect(); }}}); }// Check network changes
onNetworkChange() {
let self = this;
onNetworkStatusChange((res) = > {
if (res.isConnected) {
self.isConnect = false;
self.reConnect()
}
});
}
// The socket is enabled
onSocketOpened() {
onSocketOpen(() = > {
console.log('Websocket open');
// Turn on the connected switch
this.isConnect = true;
this.netWork = true;
// Send heartbeat
if (this.heartCheck) {
this.reset().start(); }}); }// Receive the message returned by the server
onReceivedMsg(callBack: any) {
onSocketMessage((msg) = > {
if (typeof callBack === 'function') { callBack(msg); }}); }// Send the WS message
sendWebSocketMsg(options: any) {
sendSocketMessage({
data: options.data,
success(res) {
if (options.success && typeof options.success === 'function') { options.success(res); }},fail(err) {
if (options.fail && typeof options.fail === 'function') { options.fail(err); } }, }).then(); }}const websocket = new Websocket(
// true indicates that heartbeat detection and disconnection are enabled
true.true,);export default websocket;
Copy the code
How do you use it?
filename: src/page/index.tsx
import * as React from 'react';
import {View, Text, Image, Button} from 'remax/wechat';
import styles from './index.css';
import websocket from "@/utils/wxsocket";
export default() = > {const connectWs = () = > {
const wsUrl = 'ws:// Test or online WS address information using WSS ://' if HTTPS encryption
if(! websocket.isConnect) { websocket.init(wsUrl) } }const closeWs = () = > {
if (websocket.isConnect) {
websocket.close()
}
}
return (
<View className={styles.app}>
<View className={styles.header}>
<Image
src="https://gw.alipayobjects.com/mdn/rms_b5fcc5/afts/img/A*OGyZSI087zkAAAAAAAAAAABkARQnAQ"
className={styles.logo}
/>
<Button onClick={()= >ConnectWs ()}> Start connecting to the WS server</Button>
<Button onClick={()= >CloseWs ()}> Close the WS connection server</Button>
</View>
</View>
);
};
Copy the code
After the connectionAfter closing the link