LoginSignup
2
1

More than 3 years have passed since last update.

React NativeクライアントからWebSocketでnodejsのサーバと通信する

Last updated at Posted at 2020-08-09

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のクライアントからつなぎます。

スクリーンショット 2020-08-09 15.54.49.png

クライアント

クライアントを簡単に作成してサーバーに繋いでみます。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が関係している?のでしょうか

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1