Nodejs:如何给socket.io和Node.js做的即时通信系统加上点对点文件传输功能?

Nodejs:如何给socket.io和Node.js做的即时通信系统加上点对点文件传输功能?

很显然,利用socet.io和node.js可以 很方便要构建出一个 即时通信系统,但基本上网络上的例子都是传输文本消息,如果我们传输文件呢? (会加上mongodb数据库),如何做?求思路

8 回复

当然可以。要在基于Socket.IO和Node.js的即时通信系统中实现点对点文件传输功能,我们需要处理以下几个关键步骤:

  1. 前端部分:使用HTML5的FileReader API来读取用户选择的文件,并将其转换为二进制数据。
  2. 后端部分:使用Socket.IO来传输这些二进制数据。
  3. 接收端:接收到文件数据后,使用Node.js创建一个文件并写入这些数据。

示例代码

前端代码(HTML + JavaScript)

<!DOCTYPE html>
<html>
<head>
    <title>File Transfer Example</title>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io();

        function sendFile(file) {
            var reader = new FileReader();
            reader.onload = function(event) {
                socket.emit('file', { name: file.name, data: event.target.result });
            };
            reader.readAsArrayBuffer(file);
        }

        document.getElementById('fileInput').addEventListener('change', function(event) {
            sendFile(event.target.files[0]);
        });
    </script>
</head>
<body>
    <input type="file" id="fileInput">
</body>
</html>

后端代码(Node.js + Socket.IO

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

io.on('connection', (socket) => {
    socket.on('file', (data) => {
        const fs = require('fs');
        const filePath = `./uploads/${data.name}`;

        // 创建或覆盖文件
        const fileStream = fs.createWriteStream(filePath);

        // 将ArrayBuffer转换为Buffer
        const buffer = Buffer.from(data.data);

        fileStream.write(buffer);
        fileStream.end();

        console.log(`File received and saved as ${filePath}`);
    });
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 前端部分

    • 使用<input type="file">允许用户选择文件。
    • 使用FileReader读取文件内容,并将其转换为ArrayBuffer格式。
    • 通过Socket.IO将文件名和二进制数据发送到服务器。
  2. 后端部分

    • 监听客户端的连接事件。
    • 当接收到文件数据时,使用Node.js的fs模块创建一个文件流,并将接收到的数据写入文件。

这样,我们就可以实现一个简单的点对点文件传输系统。如果需要更复杂的逻辑(如断点续传、进度条等),可以进一步扩展这个基础实现。


1、最简单的方式是客户端先把文件先上传到又拍云、七牛云,这样的云存储服务上。然后发送返回的http连接给其他客户端。 2、图片base64后发送。

  • WebRTC DataChannel 或者
  • Flash

首先要确定支持哪些平台,哪种浏览器。

那就用第二中,图片base64后,分段发送,接收后在把几段拼成一张图。 或者你直接把一张图片分成若干个数据块,然后一个一个发送。 服务端收到后边存边转发。

socket.io根本不是点对点,是服务器转发的,底层走的还是tcp,p2p一般用的是udp协议。

新版的socketio支持二进制传输,非文本文件也能传. 我还没试过,你可以看看官方文档

点对点有见过纯服务端实现么…异想天开, 充其量只能pipe

要在基于Socket.IO和Node.js的即时通信系统中添加点对点文件传输功能,你可以使用Socket.IO的Blob/Binary数据传输功能。以下是一个简化的实现思路和示例代码。

实现思路

  1. 前端: 将文件转换为二进制格式。
  2. Socket.IO: 发送文件数据到目标用户。
  3. 后端: 将文件数据转发给接收方。
  4. 接收方前端: 接收文件数据并保存为文件。

示例代码

Node.js 后端 (server.js)

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

io.on('connection', (socket) => {
    console.log('New client connected');

    socket.on('file-upload', (data, filename) => {
        // 转发文件数据到目标客户端
        socket.broadcast.to(data.target).emit('file-receive', data.data, filename);
    });

    socket.on('disconnect', () => {
        console.log('Client disconnected');
    });
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

客户端 (client.js)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>File Transfer Example</title>
    <script src="/socket.io/socket.io.js"></script>
</head>
<body>
    <input type="file" id="fileInput">
    <button onclick="sendFile()">Send File</button>

    <script>
        const socket = io();

        function sendFile() {
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];

            if (!file) return;

            const reader = new FileReader();
            reader.onload = (e) => {
                socket.emit('file-upload', { data: e.target.result, target: 'target-client-id' }, file.name);
            };
            reader.readAsArrayBuffer(file);
        }
    </script>
</body>
</html>

解释

  1. 服务端 (server.js): 当接收到文件数据时,将文件数据广播给指定的目标客户端。
  2. 客户端 (client.js): 用户选择文件后,使用 FileReader 读取文件内容,并通过 Socket.IO 发送到服务器,最终由服务器转发到目标客户端。

注意事项

  • 在实际应用中,需要处理错误和进度更新。
  • 文件大小可能会影响性能,需考虑分块传输或增加超时机制。
  • 你需要确保客户端ID正确地被传递和识别。

这样就可以实现基本的点对点文件传输功能。

回到顶部