我的套接字 io 正在工作,但是当我添加新数据时,它不是实时的,ReactJS,Express,Mongoose
Posted
技术标签:
【中文标题】我的套接字 io 正在工作,但是当我添加新数据时,它不是实时的,ReactJS,Express,Mongoose【英文标题】:My socket io is working but when I add new data, it's not real time, ReactJS, Express, Mongoose 【发布时间】:2021-07-26 08:21:50 【问题描述】:我真的无法在互联网上找到答案,所以我想在这里问。我的套接字 io 工作,因为我可以在页面第一次加载时显示来自后端的数据,但是当我添加新数据时,我仍然需要刷新我的页面以便更新我的前端,它还不是实时的。我使用 express router/rest api 将新数据添加到数据库中。而且我还想问,为什么我必须在我的前端添加 transports: ['websocket', 'polling', 'flashsocket'] ?我看到其他人在没有运输的情况下这样做,但是当我这样做时会发生 CORS 错误。谢谢!
这是我在文件 App.js 上的 React JS 代码。 (我没有包含 const App = () => ....,但是 state 和 useEffect 在 const App 里面)
import io from "socket.io-client";
const socket = io("http://localhost:3001", transports: ['websocket', 'polling', 'flashsocket'] );
const [rooms,setRooms] = useState([]);
useEffect(() =>
socket.emit("rooms");
socket.on("rooms", rooms=>
setRooms(rooms);
)
,[])
这是我的 app.js (node/express)
const http = require('http').createServer(app);
const io = require("socket.io")(http);
const viewRooms = require("./events/rooms");
const onConnection = (socket) =>
viewRooms(io,socket);
io.on("connection",onConnection);
这是我的活动文件夹中的 rooms.js 文件
const Rooms= require("./../models/Rooms");
module.exports = (io,socket) =>
const view = () =>
Rooms.find()
.then(rooms=>
io.emit("rooms",rooms);
)
socket.on("rooms",view);
我用来向数据库添加数据的提交函数
const submitHandle = (e) =>
e.preventDefault();
const formData = new FormData();
formData.append('name',addForm.name);
addForm.description.forEach((val,key) =>
formData.append("article[" + key + "]" + "[" + Object.keys(val) + "]",val.paragraph);
)
addForm.images.forEach(val =>
formData.append("image",val);
)
formData.append('date',addForm.date);
let token = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYwNDU2ZmNhNTI3ZTdhMGEwODY0NjVjNSIsImlhdCI6MTYxODI3NzIyNX0.w6eBHJC72xo-NRPtzJ3gKu_hIY70eCk_-K3-pkO4bAc";
fetch("http://localhost:3001/rooms/upload",
method : "POST",
body : formData,
headers :
"Authorization" : token
)
.then(data => data.json())
.then(rooms=>
console.log(rooms);
alert(rooms.message);
)
这是我的特快路线上的代码(帖子)
const router = require("express").Router();
const Rooms = require("./../models/Rooms ");
const auth = require("./../authorization");
const passport = require("passport");
const multer = require("multer");
require("./../passport-setup");
// IMAGE DESTINATION AND FILENAME
const storage = multer.diskStorage(
destination : (req,file,cb) =>
cb(null,"public/images")
,
filename : (req,file,cb) =>
cb(null, Date.now() + "-" + file.originalname)
)
// upload
const upload = multer( storage : storage);
// upload rooms
router.post("/upload",upload.array("image",10),passport.authenticate("jwt",session : false),auth,(req,res,next) =>
let allDescription = req.body.description;
req.body.images = req.files.map(file =>
return(
roomName : req.body.name,
image : "/public/" + file.filename
)
)
Rooms .create(req.body)
.then(rooms=>
res.send(
message : "Rooms uploaded!",
success : true,
rooms
)
)
.catch(next);
)
【问题讨论】:
【参考方案1】:对于您问题的第一部分,我们必须查看更多日志信息,才能确切了解发生了什么。您的客户端 socket.emit("news");
似乎可能在您的 socket.io 连接完全建立之前发生得太早,并且可能在服务器准备好接收传入请求之前发生。您可以完全记录每个 socket.io 事件,并可能确定发生了什么。
我还想问,为什么我必须在前端添加 transports: ['websocket', 'polling', 'flashsocket'] ?
如果您没有将 websocket
列为第一个传输,那么 socket.io 会以一些 http 轮询请求开始,并且这些 http 请求受 CORS 约束。 webSocket 传输不受 COR 的约束,因此如果您强制它首先使用它,那么就没有 COR。仅供参考,socket.io 使用的 http 轮询仅用于检测不支持或阻塞 webSocket 传输的情况。如果您不关心这一点,那么您真的可以在前端执行此操作:
transports: ['websocket']
或者,您可以从客户端完全删除传输选项,然后在您的服务器上实现对 COR 的支持,以便允许 COR 轮询请求。
【讨论】:
对不起,我没有得到您对我问题第一部分的回答。我只有 1 个 socket.io 事件,因为我目前正在学习如何使用它。如何知道我的客户端:socket.emit("news",news) 是否发生得太早?在第一次加载页面时,我的套接字 io 工作,它可以从数据库中获取数据并更新我的状态,但是当我使用快速路由器/api 添加新数据时,我的 socket.io 不能实时工作,所以我有再次刷新我的页面。现在,我刚刚在使用 express api(当然在前端)添加数据的函数上添加了 socket.emit("news",news),它就可以工作了。 那么我必须在连接到我的 express api 的每个函数上添加 socket.emit("news",news) 吗?还是我做错了什么? @benjamin_nmn - 当您执行const socket = io("http://localhost:3001", transports: ['websocket', 'polling', 'flashsocket'] );
时,它不会立即连接 - 这需要一些时间。事实上,当客户端连接准备好时,套接字上会发生一个connect
事件。我猜你可能正试图在套接字准备好之前发送它。
如何确保在通过套接字发送之前,服务器已准备就绪?为什么它在第一次加载时有效,但在我使用 rest api 向数据库添加新数据时无效?
@benjamin_nmn - 你在展示你的休息 api 代码吗?我没看到。无法回答有关我们看不到的代码的问题。以上是关于我的套接字 io 正在工作,但是当我添加新数据时,它不是实时的,ReactJS,Express,Mongoose的主要内容,如果未能解决你的问题,请参考以下文章
React 和 Socket.io:能够获取初始数据 - 但是当有新帖子出现时视图不会更新