ReactNative使用websocket實現實時聊天與web端使用websocket的寫法一樣,直接new WebSocket就可以。我在github上找到了兩個有關RN的websocket組件包(react-native-websocket和react-native-reconnecting-websocket),但是發現都是簡單封裝了原始websocket的API,並沒有什麼特殊的地方,所以我推薦大家直接使用原始websocket就可以。
我在RN中使用websocket發現ws.onclose事件始終無法觸發,ws.onmessage事件可以正常使用,所以網上很多斷開重連的實現方法我這裏是無法使用的。不知道大家有沒有遇到這種情況。
不過好在我這裏(安卓手機)只要連上了,不管息屏亮屏還是後臺運行,使用期間是不會斷開的;(蘋果手機)息屏了的話,是會斷開的,如果用戶一直是亮屏使用狀態,那就不會斷開,所以我這裏加入了檢測屏幕狀態的監聽,做一些邏輯判斷,使每次亮屏就關閉之前的失效連接,再重新建立websocket連接。
我們可以把有關websocket的代碼全放在APP登陸後的首頁文件中,這樣APP運行的所有生命週期中,無論進入哪個頁面,websocket連接始終存在。下面上代碼:
首先引入判斷APP運行狀態API的組件AppState、事件監聽組件DeviceEventEmitter、判斷運行系統組件Platform:
import {
StyleSheet,
View,
Platform,
DeviceEventEmitter,
AppState
} from "react-native";
下面是首頁中有關websocket部分代碼:
class HomePage extends React.Component {
constructor(props) {
super(props);
this.state = {
Info: {},
ws: {}
};
this.WebSocketConnect = this.WebSocketConnect.bind(this);
this.handleAppStateChange = this.handleAppStateChange.bind(this);
}
async componentDidMount() {
// 首次進入建立連接
this.WebSocketConnect();
// 添加監聽前,先移除之前的監聽
AppState.removeEventListener('change', this.handleAppStateChange);
// 添加APP運行狀態監聽
AppState.addEventListener('change', this.handleAppStateChange);
}
componentWillUnmount() {
// 組件銷燬前,移除監聽
AppState.removeEventListener('change', this.handleAppStateChange);
}
//狀態改變響應
handleAppStateChange(appState) {
// console.log('當前狀態爲:'+appState);
// 只有ios系統才需要做狀態處理
if(Platform.OS === "ios"&&appState=="active"){
// 建立前先關閉之前的廢棄連接
this.state.ws.close();
this.WebSocketConnect();
// ios 喚醒時補充請求一下數據
DeviceEventEmitter.emit("sceneChange", {
// 參數
});
}
}
WebSocketConnect() {
var ws = null;
ws = new WebSocket(
"ws://11.111.111.11:90/GetWebSocket?Id=000001"
);
ws.onopen = e => {
console.log("onopen", e);
};
ws.onmessage = evt => {
console.log("onmessage", JSON.parse(evt.data));
this.setState({
Info: JSON.parse(evt.data)
});
DeviceEventEmitter.emit("sceneChange", {
// 參數
});
};
ws.onclose = e => {
console.log("onclose", e);
};
ws.onerror = e => {
console.log("onerror", e);
};
this.setState({
ws: ws
});
ws = null
}
render() {
return (
<View>
{/* 你的首頁 */}
</View>
);
}
}