React NativeでWebSocket通信する
App Engine フレキシブル環境にnodejsでWebSocketサーバーを立てて、そこに対してReact Nativeクライアントから接続します。ほぼサンプルコードをもとに作成できたのですが、ちょっとだけ詰まりました。ここではローカルでnodejsのサーバと通信するところまで書きます。
サーバー
こちらを参考に、
https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/appengine/websockets
とりあえずローカルでそのまま実行してみます。
クローンして、移動して、実行
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
cd nodejs-docs-samples/appengine/websockets/
yarn install && yarn start
これで、ブラウザからlocalhost:8080にアクセスすると、WebSocketのメッセージクライアントの画面が表示できるので、二つのブラウザで開いて実際にメッセージのやりとりを試すことができます。このサーバーにReactNativeのクライアントからつなぎます。
クライアント
クライアントを簡単に作成してサーバーに繋いでみます。expo-cliをインストールし、
expo init
から、 blank
プロジェクトを作成し、プロジェクトフォルダ
に移動して、App.tsx
を次のように変更します。(WebSocket試すための最低限のサンプルです)。スマホ実機からQRコードを読み込んでテストする場合のURLはローカルマシンのIPを指定します。(サーバー側をローカルで実行する場合)。
以下では、socket.io-clientを利用しています。標準ライブラリのWebSocketを使っても動くんじゃないかと思うんですが、なんでか上手くいかなかったです。
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity, Alert } from 'react-native';
import socketIOClient from "socket.io-client";
export default class App extends React.Component {
socket
constructor(props) {
super(props);
this.state = {text: ""}
}
componentDidMount(){
this.socket = socketIOClient("ws://192.xxx.xxx.xxx:8080");
// this.socket = socketIOClient("https://'app engine project id'.appspot.com");
const _that = this;
this.socket.on('message', function(data){
console.log('recieve', data)
Alert.alert("Message recieved. " + JSON.stringify(data))
});
}
sendMessage(){
if(!this.state.text){
Alert.alert('Please input message')
return;
}
this.socket.emit('message', this.state.text);
}
render() {
return (<View style={styles.container}>
<TextInput onChangeText={(text) => this.setState({text: text}) }
style={styles.input}></TextInput>
<TouchableOpacity style={styles.button}
onPress={() => this.sendMessage()}><Text>Click to send Message</Text></TouchableOpacity>
</View>)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
input: {
height: 40, borderColor: 'gray', borderWidth: 1 , width: '100%'
},
button: {
backgroundColor: "#888", height: 40, width: "100%", marginTop: 10, alignItems: 'center',padding: 'auto'
}
});
その後、yarn add socket.io-client
でライブラリ追加して、 yarn start
でクライアントを起動する。
AppEngine
このサンプルサーバーをAppEngineにデプロイのは、すでにサーバーのソースにapp.ymlが含まれているので、フォルダ、nodejs-docs-samples/appengine/websockets/
から、gcloud app deploy
叩くだけです。ReactNativeクライアントの方は、URLを実際のURLに変更します。
**使わなくなったサーバーは直ぐに削除した方が良いです。**私はしばらく上げっぱなしにしてしまったら、数千円利用料かかりました。AppEngineのflux環境はまあまあコストかかるんですかね?WebSocketが関係している?のでしょうか