是否可以将 React Native 与 socket.io 结合使用

Posted

技术标签:

【中文标题】是否可以将 React Native 与 socket.io 结合使用【英文标题】:Is it possible to combine React Native with socket.io 【发布时间】:2015-06-07 03:28:37 【问题描述】:

我正在使用 Phonegap + React.js 和 Socket.io 开发一个应用程序。然而,随后 React-Native 发布了,原生的感觉很棒。

我尝试让 socket.io-client 与 React Native 一起工作,但不幸的是没有取得多大成功。我做了一些研究,我得到了与本期所述完全相同的错误:https://github.com/facebook/react-native/issues/375

关于这个问题的 cmets 说尝试使用 fetch 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 a function

有没有办法让 socket.io-client 与 React Native 一起工作?还是我看错了?也许还有其他更适合的解决方案?

【问题讨论】:

我觉得这个例子很全:Example full code 解决方案在这里 - ***.com/questions/35052792/… 请查看以下解决方案:***.com/questions/35052792/… 【参考方案1】:

对于像我这样偶然发现如何将 socket.io 与 react native 集成的问题的人。

由于 React Native 支持 websockets 的时间很短,现在您可以使用 Socket.io 非常轻松地设置 web sockets。您所要做的就是以下

    npm install socket.io-client 首先导入 react-native 分配window.navigator.userAgent = 'react-native'; 导入 socket.io-client/socket.io 在你的构造函数中分配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');window.navigator.userAgent = 'react-native'; 在需要socket.io-client 之前。然后您可以在那里连接您的套接字并将所有侦听器放在一个地方。然后可以将动作或函数导入配置文件并在侦听器接收到数据时执行。

【讨论】:

就我而言,不需要添加window.navigator.userAgent = 'react-native';,我不知道为什么。 +1 jsonp: false 配置很重要,因为jsonp 的默认值会导致 socket.io 尝试操作 DOM(在 react 本机环境中不存在)。对于后人搜索,触发的错误信息是:“document.createElement is not a function”。 我们我从客户端发送一个回调(确认),服务器接收到事件并发出回调但它没有在我的客户端上运行..你知道这是为什么吗? 这个答案使用了什么反应版本?不适用于 v0.19 你可以像这样显式指定传输:transports: ['websocket'] 然后你不需要jsonp: false 部分。【参考方案2】:

现在,如果你想在你的 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。

【讨论】:

【参考方案3】:

除了 WebSocket API 的 polyfill,您可以创建一个使用 web-socket 的本机模块,并使用 eventDispatcher 将事件发送到 javascript

在 Javascript 方面,您可以使用 DeviceEventEmitter.addListener 订阅这些事件。

有关使用本机模块的更多信息,请参阅react-native doc on the topic

【讨论】:

React Native 中提供了一个用于 WebSockets 的 polyfill:facebook.github.io/react-native/docs/network.html#websocket【参考方案4】:
import  io  from 'socket.io-client'
const socket = io(`$SOCKET_URL:$SOCKET_PORT`)

重要! SOCKET_URL 应该是您的本地 IP 地址,而不是 localhost127.0.0.1

要检查您的本地 IP: Mac / Linux:在终端中运行 ifconfig Windows:在 shell 中运行 ipconfig --all

应该类似于:const socket = io('http://10.0.1.6:3000', transports: ['websocket'])

【讨论】:

【参考方案5】:

2016 年 2 月编辑:React Native 现在支持 Web Sockets,因此其中一些建议无效。

恐怕你误解了 Github 问题。 aackerman 在其中说:

对于这种特定情况,您可能希望使用 fetch API 由环境提供。

没有说你应该使用 fetch API 来抓取远程 JS 模块。他的建议是使用 fetch API 代替内置的 Node.JS 请求模块,该模块在 React Native 中不可用。

让我们看看你的代码:

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

想一想 - socketScript 不是 JavaScript 对象,它是一个字符串 - 那么如何调用 io 方法呢?

你真正需要做的是在使用之前解析_bodyText(在浏览器中你可以使用eval),但是你仍然会遇到问题,虽然 React Native 有一个用于 XHR 和fetch API,它还没有用于 WebSocket API 的 API。除非我弄错了,否则这意味着你被卡住了。

我建议打开一个 Github 问题来请求 WebSocket API polyfill 并征求社区的意见。有人可能有解决方法。

【讨论】:

websocket api 已经可用facebook.github.io/react-native/docs/network.html#websocket 解决方案在这里 - ***.com/questions/35052792/…【参考方案6】:

终于找到了。

客户

import  io  from "socket.io-client/build/index"
io("ws://<LOCAL HOME NETWORK IP>:<PORT ON SERVER>")

服务器

import express from "express"
import http from "http"
import * as SocketIO from "socket.io"

const app = express()
const server = new http.Server(app)
const io = new SocketIO.Server(server)
const port = 8000
io.on("connection", socket => 
   console.log("CONNECTIONS")

【讨论】:

【参考方案7】:

可能会出错

import io from "socket.io-client/socket.io"

然后只需添加以下行......

import io from "socket.io-client/dist/socket.io";

然后在 componenDidMount 或 useEffect 函数中只需添加以下行。切勿在类组件的构造函数下使用它。

 var socket = io("https://localhost.com:3000",  jsonp: false );
        // client-side
        socket.on("chat_message", (msg) => 
            console.log(msg);
        );

【讨论】:

【参考方案8】:

虽然您可以使用socket.io-client lib,但社区抱怨大多数版本的兼容性问题(我确实遇到过一些)。它可以工作,但是现在我害怕升级lib,因为我需要验证下一个版本与我的服务器版本和react-native版本的兼容性!

好像很多人想念react's own implementation of Websockets!我真的建议您使用它而不是 socket.io-client。用法非常相似:

var ws = new WebSocket('ws://host.com/path');
ws.onopen = () =>   // connection opened  ws.send('something'); // send a message;
ws.onmessage = (e) =>   // a message was received  console.log(e.data);;
ws.onerror = (e) =>   // an error occurred  console.log(e.message);;
ws.onclose = (e) =>   // connection closed  console.log(e.code, e.reason);;

【讨论】:

以上是关于是否可以将 React Native 与 socket.io 结合使用的主要内容,如果未能解决你的问题,请参考以下文章

我可以将 Backbone 与 React Native 一起使用吗?

将 React Native 与 Buildfire 一起使用

将 CloudKit 与 React Native 一起使用

[RN][IOS]是不是可以将 React Native RCTLinking 与 RNFirebase 动态链接结合使用?

是否可以使用 Poledia/react-native-ble-plx 将 iOS 设备变成 iBeacon?

是否可以从 React-Native 中的图像中获取二进制数据?