web-dev-qa-db-ja.com

React Nativeとsocket.ioを組み合わせることは可能ですか?

Phonegap + React.jsおよびSocket.ioを使用してアプリを開発していました。しかし、その後React-Nativeがリリースされ、ネイティブの感触は素晴らしいです。

Socket.io-clientをReact Nativeで動作させようとしましたが、残念ながらあまり成功しませんでした。いくつかの研究を行ったところ、この問題で説明したものとまったく同じエラーが発生します: https://github.com/facebook/react-native/issues/375

この問題に関するコメントでは、フェッチAPIを使用してJSモジュールをフェッチしようとしていますが、これは間違っていると思います。

var socketScript;    
fetch('https://cdn.socket.io/socket.io-1.2.0.js')
    .then(function(response) {
        socketScript = response._bodyText;
    }).done(function() {
        var socket = socketScript.io();
    });

これは、undefined is not functionを返します。

Socket.io-clientをReact Nativeで動作させる方法はありますか?または、これを間違った方法で見ていますか?おそらく、より適切な他のソリューションがありますか?

24
Timon

Socket.ioとreact nativeを統合する方法を探しているこの質問に出くわした私のような人のために。

React Nativeは短い間websocketをサポートしているため、Socket.ioを使用してWebソケットを簡単にセットアップできます。必要な作業は次のとおりです。

  1. npm install socket.io-client
  2. 最初のインポートのreact-native
  3. _window.navigator.userAgent = 'react-native';_を割り当てます
  4. socket.io-client/socket.ioのインポート
  5. コンストラクタでthis.socket = io('localhost:3001', {jsonp: false});を割り当てます

したがって、npmでsocket.io-clientをインストールすると、次のようになります。

_import React from 'react-native';

// ... [other imports]

import './UserAgent';

import io from 'socket.io-client/socket.io';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.socket = io('localhost:3001', {jsonp: false});
  }

  // now you can use sockets with this.socket.io(...)
  // or any other functionality within socket.io!

  ...
}
_

そして、「UserAgent.js」で:

_window.navigator.userAgent = 'react-native';
_

注:ES6モジュールのインポートは引き上げられているため、react-nativeインポートおよびsocket.ioインポートと同じファイルでuserAgentを割り当てることはできません。したがって、個別のモジュールです。

編集:

上記の解決策は機能するはずですが、その場合は別のsocketConfig.jsファイルを作成しようとしません。そこには、const io = require('socket.io-client/socket.io');や、socket.io-clientを要求する前に_window.navigator.userAgent = 'react-native';_を含む、必要なものをすべてインポートします。次に、そこにソケットを接続し、すべてのリスナーを1か所に配置できます。次に、アクションまたは関数を構成ファイルにインポートして、リスナーがデータを受信したときに実行できます。

52

RNアプリでsocket.ioを使用する場合は、次のコードを使用する必要があります。

if (!window.location) {
    // App is running in simulator
    window.navigator.userAgent = 'ReactNative';
}

// This must be below your `window.navigator` hack above
const io = require('socket.io-client/socket.io');
const socket = io('http://chat.feathersjs.com', {
  transports: ['websocket'] // you need to explicitly tell it to use websockets
});

socket.on('connect', () => {
  console.log('connected!');
});

Eric Kryski に感謝します。

7
Kohver

WebSocket APIのポリフィルではなく、Webソケットを使用するネイティブモジュールを作成し、eventDispatcherを使用してイベントをJavascriptに送信できます。

Javascript側では、DeviceEventEmitter.addListenerを使用してこれらのイベントをサブスクライブします。

ネイティブモジュールの使用の詳細については、 トピックに関するreact-native doc を参照してください。

2
Jonathan Huang

2016年2月編集:React NativeはWebソケットをサポートするようになったため、このアドバイスの一部は無効です。

あなたは私が恐れているGithubの問題を誤解しています。その中で、aackermanは次のように述べています。

この特定のケースでは、環境によって提供されるフェッチAPIを使用する可能性があります。

彼はdoes n't fetch APIを使用してリモートJSモジュールを取得する必要があると言っています。彼が提案しているのは、React Nativeでは利用できないビルトインNode.JSリクエストモジュールの代わりにフェッチAPIを使用することです。

コードを見てみましょう:

socketScript = response._bodyText;
var socket = socketScript.io();

ちょっと考えてみてください-socketScriptはJavaScriptオブジェクトではなく、文字列です-それでioメソッドをどのように呼び出すことができますか?

本当に必要なのは、_bodyText使用する前(ブラウザではevalを使用できます)が、それでもReact NativeにはXHRとフェッチのためのポリフィルがあるという問題がありますAPI、まだWebSocket API用のものはありません。

Githubの問題を開いてWebSocket APIポリフィルを要求し、コミュニティの意見を求めることをお勧めします。誰かが回避策を持っているかもしれません。

0
Colin Ramsay