Detect broken connection via app layer ping

This commit is contained in:
Martin Bauer 2021-07-23 16:25:26 +02:00
parent db3589c86d
commit 03812fe514
2 changed files with 38 additions and 12 deletions

View File

@ -14,6 +14,7 @@ const OpCodes = {
ANSWER_SESSION_LIST: 7,
WIFI_STATE_RESPONSE: 8,
WIFI_SCAN_RESPONSE: 9,
APP_LAYER_PING: 10,
// from frontend to device
START_SESSION: 128,
@ -26,6 +27,7 @@ const OpCodes = {
WIFI_TRIGGER_SCAN: 135,
};
const HEARTBEAT_TIMEOUT = 3000;
export default class SwimTrackerWebsocketConnection {
constructor(swimTrackerHost, onData, onStarted, onStopped, onWifiStateInfo, onConnect, onDisconnect) {
@ -57,15 +59,27 @@ export default class SwimTrackerWebsocketConnection {
});
this._wifiScanPromises = [];
this.pingTimeout = null;
}
heartbeat() {
clearTimeout(this.pingTimeout);
let connection = this;
this.pingTimeout = setTimeout(() => {
connection.ws.reconnect();
}, HEARTBEAT_TIMEOUT);
}
close() {
this.ws.onmessage = null;
this.ws.onopen = null;
this.ws.onclose = null;
this.ws.onerror = null;
this.ws.close();
this.ws = null;
if (this.ws !== null) {
this.ws.onmessage = null;
this.ws.onopen = null;
this.ws.onclose = null;
this.ws.onerror = null;
this.ws.close();
this.ws = null;
}
}
sendStartCommand() {
@ -129,6 +143,8 @@ export default class SwimTrackerWebsocketConnection {
const opCode = dv.getInt8(0);
const payload = new Uint8Array(e.data).slice(1);
this.heartbeat();
if (opCode === OpCodes.INITIAL_INFO) {
const headerSize = 6;
const running = Boolean(dv.getInt8(1));
@ -157,6 +173,8 @@ export default class SwimTrackerWebsocketConnection {
} else if (opCode === OpCodes.WIFI_STATE_RESPONSE) {
const wifiInfo = msgpack.decode(payload, { codec: this.msgpackCodec });
this.onWifiStateInfo(wifiInfo);
} else if (opCode === OpCodes.APP_LAYER_PING) {
//console.log("got heartbeat");
}
}

View File

@ -11,6 +11,7 @@ import themeColors from '../components/themeColors';
import MaterialIcon from "react-native-vector-icons/MaterialCommunityIcons";
import EntypoIcon from "react-native-vector-icons/Entypo";
import ImageHeader from "../components/ImageHeader";
import { connect } from 'react-redux';
// ---------------------------------------------------------------------------------------------
@ -24,6 +25,7 @@ function SettingsTextInput(props) {
placeholder={props.placeholder}
placeholderTextColor="rgba(167,167,167,1)"
selectionColor='rgb(120,120,120)'
value={props.value}
></TextInput>
</React.Fragment>
);
@ -124,6 +126,7 @@ const settingsGroupStyles = StyleSheet.create({
textInput: {
color: "rgba(255,255,255,1)",
marginTop: 8,
textAlign: "right",
},
slider: {
minWidth: 100,
@ -140,6 +143,7 @@ const settingsGroupStyles = StyleSheet.create({
function SettingsView(props) {
console.log("settings props", props);
return (
<View style={{ flex: 1 }}>
<StatusBar hidden={true} />
@ -154,11 +158,11 @@ function SettingsView(props) {
<SettingsGroup title="swimtracker Device">
<SettingsTextInput
label="URL/IP"
placeholder="192.168.178.??"
/>
<SettingsSwitch
label="SomeSwitch"
placeholder="swimtracker-????"
value={props.settings.swimTrackerHost}
/>
<SettingsSwitch label="Start automatically" />
<SettingsSwitch label="Stop automatically" />
</SettingsGroup>
</View>
</View>
@ -166,4 +170,8 @@ function SettingsView(props) {
)
}
export default SettingsView;
const mapStateToProps = (state) => {
return { settings: state.settings };
};
export default connect(mapStateToProps)(SettingsView);