Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send a file using websocket javascript client

I'm trying to send a file using websocket connection to my server: I've implemented the websocket server side using java Spring the client side is in javaScript for some reason each time i send a binary message from client side using "blob" or "arraybuffer. the server recognise the message as text message not as binary. what am i missing here?

Client Side

 <!DOCTYPE HTML>
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <title>Chat</title>
        </head>
    <body>
        <h2>File Upload</h2>
            Select file
        <input type="file" id="filename" />
        <br><br><br>
        <input type="button" value="Connect" onclick="WebSocketTest()" />
        <br><br><br>
        <input type="button" value="Upload" onclick="sendFile()" />

    <script>
    "use strict"
    var ws;
    function WebSocketTest()
    {
      if ("WebSocket" in window)
      {
         console.log("WebSocket is supported by your Browser!");
         // Let us open a web socket
         ws = new WebSocket("ws://xx.xx.xx.xx:yyyy/service/audioHandler");
         ws.onopen = function()
         {
            // Web Socket is connected, send data using send() 
            ws.send(JSON.stringify({userName:'xxxx',password:'sgdfgdfgdfgdfgdf'}));
            console.log("Message is sent...");
         };
         ws.onmessage = function (evt)
         {
            var received_msg = evt.data;
            console.log("Message is received...");
         };
         ws.onclose = function()
         {
            // websocket is closed.
            console.log("Connection is closed...");
         };
      }
      else
      {
         // The browser doesn't support WebSocket
         console.log("WebSocket NOT supported by your Browser!");
      }
    }

function sendFile() {
    var file = document.getElementById('filename').files[0];
    ws.binaryType = "arraybuffer";
    //ws.send('filename:'+file.name);
    var reader = new FileReader();
    var rawData = new ArrayBuffer();           
    console.log(file.name);
    reader.loadend = function() {
    }
    reader.onload = function(e) {
        rawData = e.target.result;
        ws.send(rawData);
        console.log("the File has been transferred.")
        //ws.send('end');
    }
    reader.readAsArrayBuffer(file);
}   
</script>
</body>
</html>

Server Side

public class WebSocketController extends BinaryWebSocketHandler {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private CallScopeStore callScopeStore;

    private static Logger logger = Logger.getLogger(AudioHandler.class);
    private static final String STOP_MESSAGE = "stop";

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
        try {
         //do something....
        } catch (Exception e) {
            logger.error(e, e);
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void handleTextMessage(final WebSocketSession session, TextMessage message) {
        try {
            //do something....
            }
        } catch (Exception e) {
            logger.error(e, e);
            throw new RuntimeException(e);

        }
    }
}
like image 653
snabel Avatar asked Jan 15 '15 08:01

snabel


People also ask

Can I send files in WebSocket?

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.

Can a WebSocket server send message to client?

The Message event takes place usually when the server sends some data. Messages sent by the server to the client can include plain text messages, binary data, or images. Whenever data is sent, the onmessage function is fired. This event acts as a client's ear to the server.

How do you use WebSockets in Javascript?

To open a websocket connection, we need to create new WebSocket using the special protocol ws in the url: let socket = new WebSocket("ws://javascript.info"); There's also encrypted wss:// protocol. It's like HTTPS for websockets.


2 Answers

You have to send the file as a blob.

ws = new WebSocket("ws://xx.xx.xx.xx:yyyy/service/audioHandler");
ws.binaryData = "blob";
ws.send(message); // Blob object

Probably you can find an error as you mention: "CloseStatus[code=1009, reason=No async message support and buffer too small. Buffer size: [8,192], Message size: [7,816,684]]". That happens because your WebSocket Engine need to be configured to allow binary message with the size you want. For example, in your WebSocketConfig:

@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxTextMessageBufferSize(500000);
    container.setMaxBinaryMessageBufferSize(500000);
    return container;
}

As you can see, you can set the maximun size allowed for your text and binary messages, just specify a size bigger than 7,816,684 (the file you was trying to send). By default, your buffer size is [8,192] so if you send a file with a smaller size than your buffer size, there shouldn't be problems. For more information, you can check websocket spring documentation.

like image 200
robert08 Avatar answered Sep 28 '22 07:09

robert08


@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxTextMessageBufferSize(500000);
    container.setMaxBinaryMessageBufferSize(500000);
    return container;
}

WebSocketMessageBroker invalid. @robert08

@Configuration
@EnableWebSocketMessageBroker
public class MyWebSocketMessageBrokerConfigurer implements WebSocketMessageBrokerConfigurer {


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/portfolio").setAllowedOrigins("*");
    }


    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.setPathMatcher(new AntPathMatcher("."));
        config.setApplicationDestinationPrefixes("/app");
        config.enableSimpleBroker("/topic", "/queue");
    }


    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration webSocketTransportRegistration) {
        webSocketTransportRegistration
                .setMessageSizeLimit(1024 * 1024)
                .setSendBufferSizeLimit(1024 * 1024 );

    }


}
like image 37
Yi Li Avatar answered Sep 28 '22 06:09

Yi Li