node.jstypescriptexpresssocket.ionode-streams

Unable to send streams via SocketIO NodeJS


as the title implies I am trying to send streams of data through SocketIO sockets.

I am writing a Node TS application that may need to send large files so the default Buffer object isn't enough.

So far I have this code:

Client Side

socket.emit("upload", file.stream(), (response:any) => {
    console.log(response);
})

Server side

socket.on("upload", (data, callback) => {
    console.log(data)
})

The connection between the client and server is working, however when uploading files the server receives and empty object instead of the stream. But there's no error appearing in neither the front end or back end codes.

Any ideas on how to send stream through SocketIO? I have looked into socket.io-stream but I haven't managed to make it work with ES modules.


Solution

  • I write an example for you with socket.io-stream:

    server.ts:

    import * as path from 'path';
    import * as http from 'http';
    import * as fs from 'fs';
    import { Server } from 'socket.io';
    import * as ss from 'socket.io-stream';
    
    const httpServer = http.createServer();
    const io = new Server(httpServer);
    
    io.on('connection', (socket) => {
      ss(socket).on('upload', (stream, data) => {
        const filename = path.basename(data.name);
        stream.pipe(fs.createWriteStream(`./${filename}`));
        stream.on('end', () => {
          socket.emit('completed', 'upload completed');
        });
      });
    });
    
    httpServer.listen(3000, () => {
      console.log('port:3000');
    });
    
    

    client.ts:

    import { io } from 'socket.io-client';
    import * as ss from 'socket.io-stream';
    import * as fs from 'fs';
    
    const socket = io('http://localhost:3000');
    const filePath = '../../../README.md'; //file path
    const file = fs.createReadStream(filePath);
    const stream = ss.createStream();
    
    ss(socket).emit('upload', stream, { name: filePath.split('/').pop() });
    file.pipe(stream);
    
    socket.on('completed', (message) => {
      console.log(message);
    });
    
    

    so, I think this example can help you.