使用 websocket javascript 客户端发送文件

sna*_*bel 6 javascript java spring websocket

我正在尝试使用 websocket 连接将文件发送到我的服务器:我已经使用 java Spring 实现了 websocket 服务器端,每次我使用“blob”从客户端发送二进制消息时,出于某种原因,客户端在 javaScript 中或“arraybuffer。服务器将消息识别为文本消息而不是二进制消息。我在这里遗漏了什么?

客户端

 <!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>
Run Code Online (Sandbox Code Playgroud)

服务器端

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);

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

您必须将文件作为 blob 发送。

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

您可能会发现一个错误,如您提到的:“CloseStatus[code=1009,reason=没有异步消息支持且缓冲区太小。缓冲区大小:[8,192],消息大小:[7,816,684]]”。发生这种情况是因为您的 WebSocket 引擎需要配置为允许具有您想要的大小的二进制消息。例如,在您的 WebSocketConfig 中:

@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxTextMessageBufferSize(500000);
    container.setMaxBinaryMessageBufferSize(500000);
    return container;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,您可以设置文本和二进制消息允许的最大大小,只需指定大于 7,816,684(您尝试发送的文件)的大小即可。默认情况下,您的缓冲区大小为 [8,192],因此如果您发送的文件大小小于缓冲区大小,应该不会有问题。更多信息可以查看websocket spring 文档。