[英]Multiple axios get requests in socket.io. Sending two events via `socket.emit` at the same time
I am trying to create multiple axios requests in socket.io. 我试图在socket.io中创建多个axios请求。 If I have simultaneously:
如果同时有:
socket.emit ("Emit1", req1.data);
socket.emit ("Emit2", req2.data);
socket.emit("Emit2", req2.data);
works. 作品。
socket.emit ("Emit1", req1.data);
does not work. 不起作用。
When I remove socket.emit("Emit2", req2.data);
当我删除
socket.emit("Emit2", req2.data);
--> emit1
works. ->
emit1
作品。
How to combine it so that it works simultaneously?. 如何组合它以使其同时工作?
Can I create two servers. 我可以创建两个服务器。 One supporting the first component and request get
url1
and a second server that supports request url2
? 一个支持第一个组件和请求的服务器获取
url1
,另一个支持请求url2
服务器?
const Emit = async socket => {
try{
const [req1, req2] = await Promise.all([
axios.get(url1, {
headers: {
}
}),
axios.get(url2, {
headers: {
'Authorization': `Bearer ${token}`
}
})
]);
socket.emit("Emit1", req1.data);
socket.emit("Emit2", req2.data);
}
catch(error){
console.log(error)
}
};
Client 客户
First component: 第一部分:
import socketIOClient from "socket.io-client";
componentDidMount() {
axios.get
axios({
url,
method: "GET",
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(res => {
this.setState({
scores: res.data,
activeTab: res.data[0].id
});
})
.catch(error => {
console.log(error);
})
}
componentDidUpdate(prevProps, prevState) {
const endpoint = 'http://127.0.0.1:3000';
if (prevState.scores !== this.state.scores) {
const socket = socketIOClient(endpoint);
socket.on("Emit1", data => this.setState({
scores: data
}));
}
}
Second component: 第二部分:
import socketIOClient from "socket.io-client";
componentDidMount() {
axios.get
axios({
url,
method: "GET",
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(res => {
this.setState({
abcd: res.data
});
})
.catch(error => {
console.log(error);
})
}
componentDidUpdate(prevProps, prevState) {
const endpoint = 'http://127.0.0.1:3000';
if (prevState.abcd !== this.state.abcd) {
const socket = socketIOClient(endpoint);
socket.on("Emit2", data => this.setState({
abcd: data
}));
}
}
I've been working on your question for a while now and this are my conclusions: 我一直在研究您的问题已有一段时间了,这是我的结论:
I've reconstructed your backend this way: 我以这种方式重建了您的后端:
const express = require('express')
const app = express()
const http = require('http').createServer(app)
const io = require('socket.io')(http)
const port = 3003
app.use(express.json())
app.get('/emit', async({ res }) => {
const [data1, data2] = await Promise.all([fakeApiCall(1), fakeApiCall(2)])
io.emit('Emit1',data1)
io.emit('Emit2',data2)
res.status(200).json('emitted')
})
const fakeApiCall = id =>{
return new Promise((resolve, reject) =>{
setTimeout(() => resolve(`data${id}`), 3000)
})
}
http.listen(port, () => console.log('listening on port ' + port))
Essencially that's exactly what you are doing, and works just fine, both events are emmited after Promise.all
solves all promises. 从本质上讲,这就是您正在做的事情,并且工作正常,这两个事件都在
Promise.all
兑现所有诺言之后Promise.all
。
After that I've made a version of your frontend: 之后,我制作了您的前端版本:
App.js: App.js:
import React from 'react'
import ComponentA from './ComponentA'
import ComponentB from './ComponentB'
const App = () => {
return (
<>
<ComponentA />
<ComponentB />
</>
)
}
export default App
Component A : 成分A:
import React from 'react'
import socketIOClient from 'socket.io-client'
class ComponentA extends React.Component {
state = {
data: null
}
componentDidMount(){
setTimeout(() => this.setState({data: 'bla'}), 2000)
}
componentDidUpdate(prevProps, prevState) {
const endpoint = 'http://127.0.0.1:3003';
if (prevState.data !== this.state.data) {
const socket = socketIOClient(endpoint);
socket.on("Emit1", data => this.setState({ data }))
}
}
render() {
const { data } = this.state
return (
<div>
{data}
</div>
)
}
}
export default ComponentA
Component B : 成分B:
import React from 'react'
import socketIOClient from 'socket.io-client'
class ComponentB extends React.Component {
state = {
data: null
}
componentDidMount(){
setTimeout(() => this.setState({data: 'bla'}), 2000)
}
componentDidUpdate(prevProps, prevState) {
const endpoint = 'http://127.0.0.1:3003';
if (prevState.data !== this.state.data) {
const socket = socketIOClient(endpoint);
socket.on("Emit2", data => this.setState({ data }))
}
}
render() {
const { data } = this.state
return (
<div>
{data}
</div>
)
}
}
export default ComponentB
And surprisingly... It works just fine! 令人惊讶的是,它工作得很好! So, what is the difference here?
那么,这里有什么区别? Everything looks the same (how the events are emitted, how the listener is only inserted in
componentDidUpdate
, how the state changes after an async call in componentDidMount
). 一切看起来都一样(该事件是如何发出的,如何监听器只在插入
componentDidUpdate
,如何在一个异步调用后的状态变化componentDidMount
)。 So the only thing that can possibly be interfering is the axios call you make inside componentDidMount
, cause in both components the io.listen
isn't setted at componentDidMount
how it should be (I assume you have reasons for that), so both components MUST update the state before the event is emmited, otherwise if the properties data
or abcd
don't get updated in time the event listener will be called after the backend emits the data. 因此,唯一可能造成干扰的是您在
componentDidMount
内部进行的axios调用,这是因为两个组件中的io.listen
都没有在componentDidMount
设置(应该是有原因的),所以两个组件都必须在发出事件之前更新状态,否则,如果未及时更新属性data
或abcd
则在后端发出数据后将调用事件侦听器。 And your claim about how if you omit Emit2
Emit1
will work just fine. 您关于如何省略
Emit2
Emit1
也可以正常工作。 But, what about omit Emit1
? 但是,忽略
Emit1
呢? Emit2
will work as well? Emit2
也可以吗? Looks like a race condition, something in componentA
's componentDidMount
is preventing componentB
from updating or vice-versa 看起来像是竞争条件,
componentA
的componentDidMount
某些内容阻止了componentB
的更新,反之亦然
Place the io's listeners in componentDidMount
in both components to determine if this is the case. 放置在io的听众
componentDidMount
在这两个组件,以确定是否是这种情况。 Cause honestly, I couldn't think in any other problem that may be causing this. 老实说,我无法想到可能导致此问题的任何其他问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.