web-dev-qa-db-fra.com

Est-il possible de combiner React Native avec socket.io

Je travaillais sur une application avec Phonegap + React.js et Socket.io. Cependant, React-Native est sorti et la sensation native est incroyable.

J'ai essayé de faire fonctionner socket.io-client avec React Native, mais malheureusement sans grand succès. J'ai fait des recherches et j'obtiens exactement les mêmes erreurs que celles décrites dans ce numéro: https://github.com/facebook/react-native/issues/375

Les commentaires sur le problème ont dit d'essayer d'utiliser l'API fetch pour récupérer les modules JS, mais je pense que je fais ça mal:

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

Cela renvoie un non défini n'est pas une fonction .

Existe-t-il un moyen de faire fonctionner socket.io-client avec React Native? Ou est-ce que je regarde les choses dans le mauvais sens? Peut-être existe-t-il d'autres solutions mieux adaptées?

24
Timon

Pour ceux comme moi, tombant sur cette question en cherchant comment intégrer socket.io avec react native.

Étant donné que React Native prend en charge les websockets depuis peu de temps, vous pouvez désormais configurer les sockets Web très facilement avec Socket.io. Tout ce que vous avez à faire est le suivant

  1. npm install socket.io-client
  2. première importation native de réaction
  3. attribuer window.navigator.userAgent = 'react-native';
  4. import socket.io-client/socket.io
  5. dans votre constructeur, affectez this.socket = io('localhost:3001', {jsonp: false});

Donc, dans l'ensemble, cela devrait ressembler à ceci après l'installation de 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!

  ...
}

puis dans 'UserAgent.js':

window.navigator.userAgent = 'react-native';

Remarque: étant donné que les importations de modules ES6 sont hissées, nous ne pouvons pas effectuer l'affectation userAgent dans le même fichier que les importations react-native et socket.io, d'où le module séparé.

ÉDITER:

La solution ci-dessus devrait fonctionner, mais dans le cas où elle n'essaye pas de créer un fichier socketConfig.js distinct. Dans ce fichier, importez tout ce qui est nécessaire, y compris const io = require('socket.io-client/socket.io'); et avoir window.navigator.userAgent = 'react-native'; AVANT d'exiger socket.io-client. Ensuite, vous pouvez y connecter votre prise et avoir tous les auditeurs au même endroit. Ensuite, des actions ou des fonctions peuvent être importées dans le fichier de configuration et exécutées lorsqu'un écouteur reçoit des données.

52
Russell Maxfield

Maintenant, si vous souhaitez utiliser socket.io dans votre application RN, vous devez utiliser ce code:

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

Un grand merci pour Eric Kryski .

7
Kohver

À court d'un polyfill pour l'API WebSocket, vous pouvez créer un module natif qui utilise des sockets Web et envoyer des événements à Javascript en utilisant eventDispatcher.

Côté Javascript, vous vous abonneriez à ces événements en utilisant DeviceEventEmitter.addListener.

Pour plus d'informations sur l'utilisation des modules natifs, consultez le doc react-native sur le sujet

2
Jonathan Huang

Modifier février 2016: React Native prend désormais en charge les sockets Web, certains de ces conseils ne sont donc pas valides.

Vous avez mal interprété le problème de Github, je le crains. Dans ce document, un aackerman dit:

Dans ce cas spécifique, vous souhaiterez probablement utiliser l'API fetch fournie par l'environnement.

Il ne le fait pas dit que vous devez utiliser l'API fetch pour récupérer les modules JS distants. Ce qu'il suggère, c'est que l'API fetch soit utilisée à la place du module de requête Node.JS intégré, qui n'est pas disponible dans React Native.

Regardons votre code:

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

Pensez-y un instant - socketScript n'est pas un objet JavaScript, c'est une chaîne - donc comment pouvez-vous appeler la méthode io dessus?

Ce que vous devez vraiment faire, c'est analyser _bodyText avant de l'utiliser (dans un navigateur, vous pouvez utiliser eval), mais le problème persisterait alors que React Native a un polyfill pour XHR et le fetch API, il n'en a pas encore pour l'API WebSocket. Sauf erreur, cela signifie que vous êtes bloqué.

Je suggère d'ouvrir un problème Github pour demander un polyfill API WebSocket et demander l'avis de la communauté. Quelqu'un pourrait avoir une solution de contournement.

0
Colin Ramsay