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> ); } }