我正在使用Phonegap + React.js和Socket.io开发应用程序。然而,然后React-Native发布了,原生的感觉很棒。
我尝试让socket.io-client使用React Native,但遗憾的是没有太大的成功。我做了一些研究,并且得到了与此问题中描述的完全相同的错误:https://github.com/facebook/react-native/issues/375
关于该问题的评论说试图使用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不是函数。
有没有办法让socket.io-client与React Native一起使用?或者我是以错误的方式看待这个?也许还有其他更合适的解决方案?
答案 0 :(得分:51)
对于那些喜欢我的人来说,看看如何将socket.io与react native集成在一起。
由于React Native现在支持websockets很短的时间,现在可以使用Socket.io轻松设置Web套接字。您所要做的就是以下
window.navigator.userAgent = 'react-native';
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。然后,您可以将套接字连接到那里,并将所有侦听器放在一个位置。然后可以将操作或函数导入配置文件,并在侦听器接收数据时执行。
答案 1 :(得分:7)
现在,如果您想在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。
答案 2 :(得分:2)
如果没有WebSocket API的polyfill,您可以创建一个使用Web套接字的本机模块,并使用eventDispatcher
将事件发送到Javascript。
在Javascript方面,您可以使用DeviceEventEmitter.addListener
订阅这些活动。
有关使用本机模块的更多信息,请参阅react-native doc on the topic
答案 3 :(得分:0)
编辑2016年2月:React Native现在支持Web套接字,因此部分建议无效。
你害怕我误解了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的polyfill,它还没有一个用于WebSocket API。除非我弄错了,否则这意味着你被困住了。
我建议打开一个Github问题来请求WebSocket API polyfill并询问社区的想法。有人可能有解决方法。
答案 4 :(得分:0)
终于找到了。
客户
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")
}
答案 5 :(得分:0)
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']})
答案 6 :(得分:0)
可能会通过错误
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);
});