首页 > 解决方案 > API路由控制器中的套接字连接保留先前调用的数据

问题描述

我的 Node/Express 应用程序中有一个 API 端点。端点负责上传文件。上传过程涉及几个阶段。比如图像转换,将图像发送到另一个第三方 API 等。我正在使用 socket.io 告诉客户端当前的上传阶段。

问题是,套接字连接在第一次调用中工作正常,但在我对端点的第二次调用中,套接字连接运行了两次并保留了我在上一次调用中发送的数据。

这是我的代码:

服务器.js

import ClientsRouter from './api/routes/clients';
import express from 'express';
import http from 'http';
import io from 'socket.io';

const port  = process.env.PORT || 3000;

const app = express();
const server = http.Server(app);
const socket = io(server);

app.set('socket', socket);

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(express.static('dist'))
app.use('/uploads', express.static('uploads'));


app.use('/api/clients', ClientsRouter);

server.listen(port, () => console.log(`Server Listening on ${process.env.URL}`));

api/routes/clients.js

import express from 'express';
import ClientsController from '../controllers/clients';

ClientsRouter.post('/uploadClientData/', clientDataUpload.array('client_data'), ClientsController.uploadClientData);

控制器/clients.js

const uploadClientData = async (req, res) => {
    try {
        const files = req.files
        const clientFolder = req.body.client_folder
        const { dbxUser } = req;
        const team_member_id = req.body.team_member_id;
        const data = req.files.map( i => ({team_member_id, destination: i.destination.substring(1), filename: i.filename, status: 1 } ))
        const io = req.app.get("socket");
        console.log("Outside Socket", data);  //This contains my currently passed data
        io.on('connection', async socket => {
            console.log("Socket Connection established");
            console.log("Inside Socket", data);  //But This contains my current data aling with the data that I passed in previous call
            await uploadQueue.collection.insertMany(data)
            socket.emit('upload stage', { upload_stage: 2, progress: 33 })
            await helpers.convertImagesToWebResolution(team_member_id, req.body.dpi, req.body.resolution);
            socket.emit('upload stage', { upload_stage: 3, progress: 66 })
            await helpers.uploadImagesToDropbox(team_member_id, dbxUser, clientFolder)
            socket.emit('upload stage', { upload_stage: 4, progress: 100 })
        })

        res.status(200).json({message: "Uploaded"});

    } catch (error) {
        console.log(error)
        res.status(500).json({
            error
        });
    }
}

在我的前端反应组件中

componentDidMount(){
    const { currentFolder } = this.props;
    this.setState({ client_folder: currentFolder }, () => this.afterFileSelect())
}



componentDidUpdate(prevProps){
    const { selectedFiles } = this.props;
    if(prevProps.selectedFiles !== selectedFiles){
        this.afterFileSelect()
    }
}

afterFileSelect = async () => {
    const { selectedFiles, setSelectedFiles, currentFolder, user, uploadSettings} = this.props;
    let formData = new FormData()
    formData.append('client_folder', currentFolder)
    formData.append('team_member_id', user.team_member_id)
    formData.append('resolution', uploadSettings.resolution.split("x")[0])
    formData.append('dpi', uploadSettings.dpi)
    for(let selectedFile of selectedFiles){
        formData.append('client_data', selectedFile)
    }
    let uploadResp = uploadSettings.convert_web_res ? await uploadClientData(formData) : await dropboxDirectUpload(formData)
    const endpoint = uploadResp.config.url;
    const host = endpoint.substring(0, endpoint.indexOf("api"));
    const socket = socketIOClient(host);
    socket.on("upload stage", data => {
        this.setState({upload_stage: data.upload_stage, progress: data.progress})
        data.upload_stage === 4 && this.setState({client_folder: ""})
    })
}

另外我想知道这是否是跟踪上传进度的正确方法?

标签: javascriptnode.jsreactjsexpresssocket.io

解决方案


推荐阅读