Question: I'm developing a Web application to send images, videos, etc. to two monitors from an admin interface. I'm using ws in Node.js for the server side. I've implemented selecting images available on the server and external URLs and sending them to the clients, but I also wanted to be able to directly send images selected from the device with a file input. I managed to do it using base64 but I think it's pretty inefficient.

Currently I send a stringified JSON object containing the client to which the resource has to be sent, the kind of resource and the resource itself, parse it in the server and send it to the appropriate client. I know I can set the Websocket binaryType to blob and just send the File object, but then I'd have no way to tell the server which client it has to send it to. I tried using typeson and BSON to accomplish this, but it didn't work.

Are there any other ways to do it?

Answer: 
You can send raw binary data through the WebSocket.

It's quite easy to manage.

One option is to prepend a "magic byte" (an identifier that marks the message as non-JSON). For example, prepend binary messages with the `B` character.

All the server has to do is test the first character before collecting the binary data (if the magic byte isn't there, it's probably the normal JSON message).

A more serious implementation will attach a header after the magic byte (i.e., file name, total length, position of data being sent etc').

This allows the upload to be resumed on disconnections (send just the parts that weren't acknowledged as received.

Your server will need to split the data into `magic byte`, `header` and `binary_data` before processing. but it's easy enough to accomplish.
I am using pure WebSocket without io, where you cannot mix content - either String or Binary. Then my working solution is like this:

CLIENT:

```
    import { serialize } from 'bson';
    import { Buffer } from 'buffer';

    const reader = new FileReader();
    let rawData = new ArrayBuffer();
    ws = new WebSocket(...)
    reader.onload = (e) => {
      rawData = e.target.result;
      const bufferData = Buffer.from(rawData);
      const bsonData = serialize({  // whatever js Object you need
        file: bufferData,
        route: 'TRANSFER',
        action: 'FILE_UPLOAD',
      });
      ws.send(bsonData);
    }

```

Then on Node server side, the message is catched and parsed like this:

```
        const dataFromClient = deserialize(wsMessage, {promoteBuffers: true}) // edited
        fs.writeFile(
          path.join('../server', 'yourfiles', 'yourfile.txt'),
          dataFromClient.file, // edited
          'binary',
          (err) => {
            console.log('ERROR!!!!', err);
          }
        );

```

The killer is `promoteBuffer` option in deserialize function.