我正在尝试使用webstomp-client
js从客户端向二进制服务器发送二进制数据。在客户端,我可以验证所发送的数据主体确实是字节数组缓冲区。
但是,当在我的websocket控制器中收到此消息时(通过我的方法调用中的Message类),有效负载是二进制文件,它是[Object ArrayBuffer]
的字符串转换
这是websocket配置的代码
@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfig2
implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic/", "/queue/");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/connect")
.setHandshakeHandler(new DefaultHandshakeHandler() {
public boolean beforeHandshake(
ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Map attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest
= (ServletServerHttpRequest) request;
HttpSession session = servletRequest
.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
}
return true;
}}).setAllowedOrigins("*") ;
}
}
这是我的控制器
@MessageMapping("/files")
@SendToUser("/queue/reply")
public String processFileFromClient(Message message, Principal principal) throws Exception {
// this payload is bytes that convert to "[Object ArrayBuffer]"
byte[] payload = (byte[]) message.getPayload();
return "Message Received" + message.toString();
}
这是我的客户
files.forEach((File) => {
reader.readAsArrayBuffer(File);
reader.onloadend = () => {};
reader.onload = (e) => {
console.log('file loaded');
arrayBuffer = e.target.result;
self.uploadWS.send('/ws/uploadFiles', arrayBuffer, { 'Content-Type': 'application/octet-stream' });
};
更新
我已经尝试将客户端的ArrayBuffer转换为Uint8Array,并且可以看到来自客户端的字节数组,但是,在服务器上转换回文件的过程中,我仍然遇到错误。
我已经确认文件没有损坏,并且我还设置了另一个不使用stomp的websocket配置,该配置能够在客户端js上使用websocket api并在自定义WebsocketHandler中处理BinaryMessage来处理文件...但是我宁愿使用stomp创建订阅通道来通过控制器分隔消息。
作为参考,这是不使用stomp的websocket配置
@Configuration
@EnableWebSocket
public class WebsocketConfig1 implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(fileHandler(),"/ws/upload").setAllowedOrigins("*");
}
@Bean
public WebSocketHandler myHandler() {
return new MyHandler();
}
@Bean
public WebSocketHandler fileHandler() {
return new FileHandler();
}
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(8192);
container.setMaxBinaryMessageBufferSize(999999999);
return container;
}
}
这是供参考,这是当我不使用脚踩和控制器时为文件创建的处理程序(它允许发送正确的二进制数据以允许数据的无错误转换)
@Override
public void handleBinaryMessage(WebSocketSession session, BinaryMessage msg){
try {
int payloadLength = msg.getPayloadLength();
session.sendMessage(new TextMessage("Receiving Data " + payloadLength));
File file = amazonClient.convertbyteArrayToFile(msg.getPayload().array(), "ExcelSpreadSheet");
FileMetadataSpreadsheet metadataSpreadsheet = metadataParser.parse(file);
session.sendMessage(new TextMessage("Metadata SpreadSheet Parsed"));
for(Map.Entry entrySet : metadataSpreadsheet.getMetadataMap().entrySet()){
session.sendMessage(new TextMessage(entrySet.getKey().toString() + entrySet.getValue().toString()));
}
} catch (Exception e) {
log.error(e.getMessage());
}
}
这是在客户端中从ArrayBuffer转换为Uint8Array的代码
files.forEach((File) => {
reader.readAsArrayBuffer(File);
reader.onloadend = () => {};
reader.onload = (e) => {
console.log('file loaded');
arrayBuffer = e.target.result;
const intArray = new Uint8Array(arrayBuffer);
self.uploadWS.send('/ws/uploadFiles', intArray, { 'Content-Type': 'application/octet-stream' });
};
});