Javascript socket.io中有多个axios get请求。同时通过“socket.emit”发送两个事件
我正在尝试在socket.io中创建多个axios请求。如果我同时: socket.1,req1.data; socket.2,req2.data socket.emit2,req2.data;作品socket.1,req1.data;不起作用 当我移除socket.emit2,req2.data;->emit1有效 如何将其合并以使其同时工作 我可以创建两个服务器吗。一个支持第一个组件和请求get url1,另一个支持请求URL2的服务器 客户 第一部分:Javascript socket.io中有多个axios get请求。同时通过“socket.emit”发送两个事件,javascript,node.js,reactjs,socket.io,axios,Javascript,Node.js,Reactjs,Socket.io,Axios,我正在尝试在socket.io中创建多个axios请求。如果我同时: socket.1,req1.data; socket.2,req2.data socket.emit2,req2.data;作品socket.1,req1.data;不起作用 当我移除socket.emit2,req2.data;->emit1有效 如何将其合并以使其同时工作 我可以创建两个服务器吗。一个支持第一个组件和请求get url1,另一个支持请求URL2的服务器 客户 第一部分: import socketIOCli
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
}));
}
}
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
}));
}
}
第二部分:
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
}));
}
}
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
}));
}
}
我研究你的问题已经有一段时间了,以下是我的结论: 事件发射工作正常 我以这种方式重建了您的后端:
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))
从本质上说,这正是你正在做的事情,而且效果很好,这两件事都是在承诺之后完成的。所有的承诺都解决了
前端设置工作
在此之后,我为您的前端制作了一个版本:
App.js:
import React from 'react'
import ComponentA from './ComponentA'
import ComponentB from './ComponentB'
const App = () => {
return (
<>
<ComponentA />
<ComponentB />
</>
)
}
export default App
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
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
令人惊讶的是。。。它工作得很好!那么,这里的区别是什么?所有事情看起来都是一样的:事件是如何发出的,监听器是如何仅插入componentDidUpdate的,在componentDidMount中异步调用后状态是如何变化的。
因此,唯一可能造成干扰的是您在componentDidMount内进行的axios调用,因为在这两个组件中,io.listen并没有设置为componentDidMount,我认为您有理由这样做,所以两个组件都必须在事件发生之前更新状态,否则,如果属性数据或abcd未及时更新,则在后端发出数据后将调用事件侦听器。而你关于省略Emit2 Emit1如何工作的说法也很好。但是,省略Emit1呢?Emit2也可以吗?看起来像是竞争条件,componentA的componentDidMount中的某些东西正在阻止componentB更新,反之亦然
可能的解决办法
将io的侦听器放置在两个组件的componentDidMount中,以确定是否存在这种情况。因为老实说,我想不出还有什么问题会导致这种情况。你的处理函数是什么?你是如何处理这两件事的?你能在问题中贴出来吗?@AritraChakraborty它在客户方面是如何运作的?这就是你的意思?是的。客户端代码。@AritraChakraborty我更新了我的问题,我认为您发送到的套接字不正确。你能用io.emit代替socket.emit吗?其中io是你的socket io实例。我已经试着把componentDidMount放进去了。但是在setState{}中的组件“A”中,我在加载组件之前设置了“activeTab:res.data[0].id“active tab”。当我单击“tab 3”时,它会自动移动到tab 1->`activeTab:res.data[0]。id`我没有解决它。我删除了activeTab:res.data[0].id。从这个.setState。现在我有一个问题是如何在组件didmount中设置activeTab