英文:
incoming msgs/msgs sent by user are not being rendered after changing rooms
问题
让我首先说一下,我只有一个月的React.js经验 -
我的React.js与Flask SocketIO后端应用程序连接。我已经多次测试过,问题不是来自这里(通常是加入、离开、发送功能)。问题是,当首次加入任何房间(通过点击3个按钮之一:general、room_1、room_2)时,一切都会正确渲染。传入的消息以及发送到服务器的消息都会显示出来。然而,已经在一个房间中后,点击加入任何其他房间的按钮会停止任何传入的消息渲染。
例如:点击“general”按钮,然后点击“room_2”按钮将显示“用户离开general”,并且不会再渲染任何其他内容。返回“general”会使一切恢复正常(这适用于您首次加入的任何房间,如果是room_2,返回它将产生预期的行为)。
例如2:
- 用户加入了general!
- 你好世界
[切换房间]
[聊天框清空] - 用户离开general
[不再渲染其他消息]
function ChatComponent(props) {
const socket = io('//localhost:5000/', {
transport: ['websocket'],
cors: { origin: '//localhost:5000/' },
extraHeaders: {"Auth" : sessionStorage.getItem('access_token') }
});
const [texttmsg,setTextmsg] = useState([])
const [sender,setSender] = useState([])
const [input, setInput] = useState("")
const [rooms, setRoomc] = useState("")
const [loading, setLoading] = useState(false)
const Message = (e) => {
e.preventDefault();
console.log("msgs: ",texttmsg)
console.log("room :",rooms,"Input:", input)
if(input.trim() !== ''){
socket.emit('send',{room: rooms, message: input, user_id : props.id})
setInput("")
}
console.log("msgs: ",texttmsg)
console.log("room :",rooms,"Input:", input)
}
const joinRoom = (newRoom) => {
if(rooms !== ""){socket.emit('leave', {room: rooms, user_id : props.id});}
if(rooms !== newRoom){socket.emit('join', {room : newRoom, user_id : props.id });}
setRoomc(newRoom)
console.log("ROOM CHANGE!")
setTextmsg([]);
setSender([]);
};
useEffect( () =>{
console.log("USE EFFECT!")
socket.off("message");
socket.off("change");
socket.on("message", (data) => {
setTextmsg((prevTextmsg) => [...prevTextmsg, data.msg]);
setSender((prevSender) => [...prevSender, data.sender]);
});
socket.on("change", (data) => {
setTextmsg((pastTextmsg) => [...pastTextmsg, data.msg])
});
return () => {
socket.off("message");
socket.off("change");
}
},[])
}
预期行为是继续按预期工作。正在使用的模块:axios、socket.io-client、flask、flask_socketio、sessions、flask_jwt。
编辑2:我想指出,如果您打开另一个客户端并加入初始客户端首次出现问题的房间,您可以看到正在发送的消息。
英文:
Let me start by saying that I only have a month of react-js experience -
My reactjs is connected to to a flask socketio backend app. I have tested it multiple times and the issue does not arrive from here (its the usual join,leave,send functions). The problem is that when joining any room (done by clicking one of the 3 buttons, general, room_1, room_2) for the first time everything renders correctly. The incoming messages as well as the ones you send to the server show up. However, clicking the button to join any other room after already being in one stops any incoming msgs from rendering.
Ex: clicking the "general" button then the "room_2" will display "user left general" and will not render anything else. Going back to "general" makes everything work again (this applies to whichever room you joined first, if it was room_2, going back to it will result in the expected behavior").
Ex2:
- User joined general!
- hello world
[changes room]
[chat box clears] - user left general
[no other msgs are rendered]
function ChatComponent(props) {
const socket = io('//localhost:5000/', {
transport: ['websocket'],
cors: { origin: '//localhost:5000/' },
extraHeaders: {"Auth" : sessionStorage.getItem('access_token') }
});
const [texttmsg,setTextmsg] = useState([])
const [sender,setSender] = useState([])
const [input, setInput] = useState("")
const [rooms, setRoomc] = useState("")
const [loading, setLoading] = useState(false)
const Message = (e) => {
e.preventDefault();
console.log("msgs: ",texttmsg)
console.log("room :",rooms,"Input:", input)
if(input.trim() !== ''){
socket.emit('send',{room: rooms, message: input, user_id : props.id})
setInput("")
} // end of if
console.log("msgs: ",texttmsg)
console.log("room :",rooms,"Input:", input)
} //end of message
const joinRoom = (newRoom) => {
//console.log("old room:", rooms,"new room: ", newRoom)
if(rooms !== ""){socket.emit('leave', {room: rooms, user_id : props.id});}
if(rooms !== newRoom){socket.emit('join', {room : newRoom, user_id : props.id });} // if we want to pass more variables we can write it like this and add more
setRoomc(newRoom)
console.log("ROOM CHANGE!")
setTextmsg([]);
setSender([]);
//setLoading(false)
};
//setLoading(true)
useEffect( () =>{
console.log("USE EFFECT!")
socket.off("message");
socket.off("change");
socket.on("message", (data) => {
setTextmsg((prevTextmsg) => [...prevTextmsg, data.msg]);
setSender((prevSender) => [...prevSender, data.sender]);
});
socket.on("change", (data) => {
setTextmsg((pastTextmsg) => [...pastTextmsg, data.msg])
});
return () => {
socket.off("message");
socket.off("change");
}
},[])
The expected behavior is for the rendering to continue working as intended.
modules being used: axios, socket.io-client, flask, flask_socketio, sessions, flask_jwt
edit 2: I would like to note that the msgs being sent can be seen if you were to open up another client and join the room were the initial client starts having issues for the first time.
答案1
得分: 0
我明白了。const socket必须放在函数外面。然而,因为我每次有人调用任何socket.io时都使用会话存储,这会导致它发送"null",因为令牌没有被创建得足够快,尽管使用了promise函数。为了解决这个问题,我现在正在使用数据库来处理定时会话。这允许我将const socket放在函数外面,而不会遇到任何时间上的问题。
英文:
I figured it out. const socket must be placed outside of the function. However,because I am using session storage every time someone calls any socket.io. This would cause it to send "null" since the token wasn't being created fast enough despite the promise functions. To fix this, I am now taking care of my timed sessions using the database. This allows me to place const socket outside my function without running into any timing issues.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论