是否可以将 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 地址,而不是 localhost
或 127.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 动态链接结合使用?