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.
Hope this help someone.
According to socket.io document you can send either string, Buffer or mix both of them

On Client side:

```
function uploadFile(e, socket, to) {
  let file = e.target.files[0];

  if (!file) {
    return
  }
  if (file.size > 10000000) {
    alert('File should be smaller than 1MB')
    return
  }

  var reader = new FileReader();
  var rawData = new ArrayBuffer();

  reader.onload = function (e) {
    rawData = e.target.result;
    socket.emit("send_message", {
      type: 'attachment',
      data: rawData
    } , (result) => {
      alert("Server has received file!")
    });
    alert("the File has been transferred.")
  }

  reader.readAsArrayBuffer(file);
}

```

on server side:

```
socket.on('send_message', async (data, cb) => {
  if (data.type == 'attachment') {
      console.log('Found binary data')
      cb("Received file successfully.")
      return
    }
// Process other business...
});

```