Socket.ioとReactNaiveの連携（の概要）


Socket.ioとReactNativeの接続をテストしてみます（本当の触りだけです）。
Socketのサーバ側は特に重要ではないので[Get Startedのコード](https://socket.io/get-started/chat/)を流用させていただきます。

## Socket Serverの準備

### 準備

まずは作業ディレクトリを作成し、必要なモジュールをインストールしておきます。

```bash
mkdir socket-server
cd socket-server
npm init -y

npm install --save express socket.io
```

### index.js

Socketサーバを実装します。
今回は、全員配信に加え、個人配信も試します。

* io.emit()で全員配信
* io.to(id).emit（）で個人配信（正確にはroom配信）


```js:index.js
var express = require('express');
var app = express();
var http = require('http').Server(app);
const io = require('socket.io')(http);

app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
});

io.on('connection',function(socket){
    socket.on('message',function(msg){

        console.log('message: ' + msg);

        //全員に配信
        io.emit('message', msg);

        //特定のIDに配信（ここでは送ってきたIDに返信）
        io.to(socket.id).emit('personal', 'PERSONAL');
        console.log('id: ' + socket.id)
    });
});

http.listen(3000, function () {
    console.log('server start @3000 port');
});
```

>ここで重要なことはHTML自体はSocketサーバの動きとは全く関係ないことです。サーバは http://localhost:3000 としてルーティングの指定に関係なく起動します。

### index.html

Webは本来関係ありませんが、動作確認用に用意します。

```html:index.html
<!DOCTYPE html>
<html>

<head>
    <title>socket test</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
</head>

<body>
    <ul id="messages"></ul>
    <form id="message_form" action="#">
        <input id="input_msg" autocomplete="off" /><button>Send</button>
    </form>
    <script>
        $(function () {

            var socketio = io();
            
            //内容を送る
            $('#message_form').submit(function () {
                socketio.emit('message', $('#input_msg').val());
                $('#input_msg').val('');
                return false;
            });
            
            //全員配信を受け取る
            socketio.on('message', function (msg) {
                $('#messages').append($('<li>').text(msg));
            });
            
            //個人配信を受け取る
            socketio.on('personal', function(msg){
                console.log(msg);
            })

        });
    </script>
</body>

</html>
```

### 動作確認

動作確認してみます。まず、サーバを起動させます。

```bash
node index.js
````

全員配信用のコンテンツは全ブラウザに反映され、投稿者（左）のみ、PERSONALと表示されています。
サーバ自体は正しく動作しているようです。

![スクリーンショット 2018-11-10 14.03.24.png](https://qiita-image-store.s3.amazonaws.com/0/55188/7aa813ec-56dc-a2d9-7c9f-666dd4c0c3e0.png)


## ReactNativeから利用してみる

では本題のReactNativeからの利用です。
socket.io-clientというモジュールを利用することで連携できるようです。

```bash
expo init socket-client
cd socket-client

npm install --save socket.io-client
npm install
```

### App.js

では、簡単なコードをApp.jsに記述してみます。
ボタンを押したらemitする機能と全員および個人配信を受け取ります。今回は描画はせずconsole.log()で出力するだけです。

```js:App.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import io from 'socket.io-client';

const socket = io('http://localhost:3000', {transports: ['websocket']} );

export default class App extends React.Component {
  render() {

    //全員配信の受け取り
    socket.on('message', function(msg){
      console.log(msg);
    })

    //個人配信の受け取り
    socket.on('personal', function(msg){
      console.log(msg);
    })

    return (
      <View style={styles.container}>
        <Text>Open up App.js to start working on your app!</Text>
        {/* メッセージ送信 */}
        <Button
          title="emit"
          onPress={() => socket.emit('message','from React')}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

### 動作確認

Reactアプリのボタンを押すとfrom Reactが投稿され、かつPERSONALが戻ってきています。

![スクリーンショット 2018-11-10 14.05.21.png](https://qiita-image-store.s3.amazonaws.com/0/55188/97c09da2-9c6b-d047-983b-838ea1782d8a.png)

Webにも反映されています。

![スクリーンショット 2018-11-10 14.05.08.png](https://qiita-image-store.s3.amazonaws.com/0/55188/91b8aac5-3acd-70dc-58f8-f310502eb59d.png)

簡単ですが、以上です。