首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用大于1mb的socket.io和nodejs实现房间间文件共享系统?

如何使用大于1mb的socket.io和nodejs实现房间间文件共享系统?
EN

Stack Overflow用户
提问于 2021-03-10 07:18:18
回答 2查看 386关注 0票数 0

我想要实现socket.io房间到房间的文件共享系统,这样用户就可以将图像发送到各自的房间,所有用户都能看到它。我已经尝试过使用base64编码方法将发送者图像文件发送到特定的房间,但是它只能发送大约700 to到800 to的文件。

Is there any easier way of doing this and can support larger files above 1mb and it should be able to load images progressively?

I am using ejs template engine, nodejs, socket.io, javascript.

Console.log("please help me guys if you any idea about this, I tried many things but none of them are working and I have read the socket.io documentation but didn't get any clue about it

,我也尝试过二进制流,但是没有运气,请帮助我的一些代码样本

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-03-10 07:31:21

您可能会发现,客户端可能更容易将文件上传到您的http服务器,然后让您的http服务器通过socket.io向房间中的所有其他客户端发送一条消息,其中客户端可以使用http下载文件。socket.io不是一个流协议,它是一个基于数据包或消息的协议,所以要发送大的东西,必须将其分解成消息,然后在客户端上重新组装。这是可以做到的,但这只是额外的非标准工作,http上传和下载已经知道如何做。

以下是步骤:

  1. 客户端通过http post将文件上传到服务器,其中以房间名称作为表单中的字段。
  2. server接收上传的文件,指定一个唯一的ID,并将其存储在磁盘上的服务器上的一个临时位置。当文件上传完成时,服务器通过received.
  3. Server通知房间中的所有其他客户端该文件已上载并准备好下载,并向他们发送包含uniqueID的下载URL。
  4. 每个客户端都通过http向每个客户端发送下载文件的请求。
  5. server可以跟踪所有客户端现在是否已经完成下载,或者只是在完成后删除该文件。基于文件时间戳的一段时间(只是清理磁盘空间),并在定期计时器上执行一些定期清理功能.

您可以创建一个处理所有下载的单一路由:

代码语言:javascript
复制
const downloadRoot = "/temp/filexfer";

app.get("/download/:id", (req, res) => {
    const fullPath = path.resolve(path.join(downloadRoot, req.params.id));
    // detect any leading . or any double .. that might jump outside
    // the downloadRoot and get to other parts of the server
    if (!fullPath.startsWith(downloadRoot)) {
         console.log(`Unsafe download request ${fullPath}`);
         res.sendStatus(500);
         return;
    } 
    res.download(fullPath);
});

清理算法可能如下所示:

代码语言:javascript
复制
const fsp = require('fs').promises;
const path = require('path');
const oneHour = 1000 * 60 * 60;

// run cleanup once per hour
let cleanupTimer = setInterval(async () => {
    let oneHourOld = Date.now() - oneHour;
    try {
        let files = await fsp.readdir(downloadRoot, {withFileTypes: true});
        for (let f of files) {
             if (f.isFile()) {
                 let fullName = path.join(downloadRoot, f.name);
                 let info = await fsp.stat(fullName);
                 // if file modification time is older than one hour, remove it
                 if (info.mtimeMs <= oneHourOld) {
                     fsp.unlink(fullName).catch(err => {
                         // log error, but continue
                         console.log(`Can't remove temp download file ${fullName}`, err);
                     });
                 }
             }
        }
    } catch(e) {
        console.log(e);
    }
    
}, oneHour);

// unref the timer so it doesn't stop node.js from exiting naturally
cleanupTimer.unref();
票数 2
EN

Stack Overflow用户

发布于 2021-03-10 14:07:01

做这类事情有很多方法,这在很大程度上取决于你想要支持什么样的体系结构。

通过socket.io或任何其他web套接字发送大文件都可以。它确实需要在你的网络应用上进行大量的切割和重组,但它会工作的。

WebRTC是共享任意类型文件的另一种方式,它不会给服务器带来负担,这是很好的。(这是一个关于it的教程https://ably.com/tutorials/web-rtc-file-transfer)

这两种方法的问题是,它们都是短暂的共享,是新用户到房间将不会得到图像,除非您的服务器再次传输数据。

我的建议是将文件直接上传到s3,然后共享一个可以在每个客户端上解析的链接。这将减轻服务器负担,并减少后端服务器中的存储需求。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66560022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档