使用 websocket javascript 客户端发送文件

Posted

技术标签:

【中文标题】使用 websocket javascript 客户端发送文件【英文标题】:Send a file using websocket javascript client 【发布时间】:2015-01-15 08:10:00 【问题描述】:

我正在尝试使用 websocket 连接向我的服务器发送文件: 我已经使用 java Spring 实现了 websocket 服务器端 客户端在javascript中 出于某种原因,每次我使用“blob”或“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>

服务器端

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

        
    

【问题讨论】:

尝试发送Blob,现在您发送ArrayBuffer,可能需要覆盖MIME 类型的请求 我试过这个方法:function sendFileBlob() var file = document.getElementById('filename').files[0]; ws.binaryType = "blob"; ws.send(file); 并且连接因以下错误而关闭:CloseStatus[code=1009, reason=No async message support and buffer too small.缓冲区大小:[8,192],消息大小:[7,816,684]] 看来,我需要将文件作为块进行流式传输,你知道该怎么做吗? 如果你要创建一个活生生的例子,我会尝试 相关:***.com/questions/21730566/… 【参考方案1】:

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

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

您可能会发现您提到的错误:“CloseStatus[code=1009, reason=No async message support and buffer too small. Buffer size: [8,192], Message size: [7,816,684]]”。发生这种情况是因为您的 WebSocket 引擎需要配置为允许具有所需大小的二进制消息。例如,在您的 WebSocketConfig 中:

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

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

【讨论】:

【参考方案2】:
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() 
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxTextMessageBufferSize(500000);
    container.setMaxBinaryMessageBufferSize(500000);
    return container;

WebSocketMessageBroker 无效。 @罗伯特08

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

    



【讨论】:

以上是关于使用 websocket javascript 客户端发送文件的主要内容,如果未能解决你的问题,请参考以下文章

(二十)ATP应用测试平台——websocket实现微服务版在线客服聊天室实战案例

Django实现websocket完成实时通讯,聊天室,在线客服等

java是如何实现客服在线聊天功能的?

全新EasyRTC平台功能开发:如何基于websocket实现视频客服通信

Javascript - 在 Websocket 上使用承诺?

使用Websocket实现消息推送