将二进制数据 stompClient 发送到 Spring-websocket 控制器并使用
Sending binary data stompClient to Spring-websocket controller and consuming
我想将二进制数据从我的 stompClient 发送到 spring 控制器。
这是我的 JS
var socket = new SockJS('/test/binary');
var stompClient = Stomp.over(socket);
socket.binaryType = "arraybuffer";
var appModel = new ApplicationModel(stompClient);
ko.applyBindings(appModel);
appModel.connect();
appModel.pushNotification("Notifications.");
var ctx = canvas.get()[0].getContext('2d');
ctx.drawImage(img, 0, 0, 320, 240);
var data = canvas.get()[0].toDataURL('image/jpeg', 1.0);
newblob = dataURItoBlob(data);
stompClient.send("/app/vid", {}, newblob);
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
我试过发送 Blob,Uint8Array 消息已发送,但在服务器端我无法使用它。
我在控制器中的方法是:
@MessageMapping("/vid")
public void getVid(Message<byte[]> message, Principal principal) throws IOException {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
bOut.write(message.getPayload());
bOut.flush();
byte[] imageInByte = bOut.toByteArray();
bOut.close();
InputStream in = new ByteArrayInputStream(imageInByte);
BufferedImage bImageFromConvert = ImageIO.read(in);
ImageIO.write(bImageFromConvert, "jpeg", new File(
"E:/new-darksouls.jpg"));
template.convertAndSend("/topic/binarydemo2", message);
我使用了 ByteArrayMessageConverter、StringMessageConverter、MappingJackson2MessageConverter 和我编写的 Base64JavaObjectMessageConverter:
public class Base64JavaObjectMessageConverter extends AbstractMessageConverter {
public Base64JavaObjectMessageConverter() {
super(MimeTypeUtils.APPLICATION_OCTET_STREAM);
}
@Override
protected boolean supports(Class<?> clazz) {
return true;
}
@Override
public Object convertFromInternal(Message<?> message, Class<?> targetClass) {
byte[] messageBytes =Base64Utils.decode( (byte[])message.getPayload() );
return SerializationUtils.deserialize( messageBytes );
}
@Override
public Object convertToInternal(Object payload, MessageHeaders headers) {
byte[] messageBytes = SerializationUtils.serialize( payload );
return Base64Utils.encode( messageBytes);
}
}
我只能将 byte[] 作为字符串发送,从中删除 'base64' 等:
stompClient.send("/app/vid", {}, data.split(',')[1]);
在控制器中:
@MessageMapping("/vid")
public void getVid(String message, Principal principal) throws IOException {
byte[] bytearray = Base64.decode(message);
BufferedImage imag=ImageIO.read(new ByteArrayInputStream(bytearray));
ImageIO.write(imag, "jpg", new File("E:/new-darksouls.jpg"));
但这不是我想要达到的。我想这会影响性能。
我正在使用 Spring 4.2.0.RC1 WebSockets,StompJS
我在不同的帖子上读到,可以从后端发送到客户端,也可以从客户端发送到后端,但我无法重现它。如果我能得到一个具体的例子,如何在客户端构建和发送 Uint8Array 或 blob,以及如何在服务器端处理它,我将不胜感激。
感谢您的宝贵时间和帮助
SockJS 不支持发送二进制数据。您可以通过普通 WebSocket 使用 STOMP 发送二进制消息。
在服务器端,请参阅 StompSubProtocolHandler,它检查传入消息是二进制还是文本,因此可以处理其中任何一种。从那里它并不重要,即从 STOMP 的角度来看,body 是一个字节数组,content-type/content-length headers 确定 body 包含什么以及它应该如何解释。在发送端,StompSubProtocolHandler 也可以发送二进制或文本,目前如果 content-type 是 application/octet-stream 并且只要不使用 SockJS,它就使用二进制。
所以简而言之,在 WebSocket 上它应该可以工作,但在使用 SockJS 作为传输时就不行了。
我想将二进制数据从我的 stompClient 发送到 spring 控制器。 这是我的 JS
var socket = new SockJS('/test/binary');
var stompClient = Stomp.over(socket);
socket.binaryType = "arraybuffer";
var appModel = new ApplicationModel(stompClient);
ko.applyBindings(appModel);
appModel.connect();
appModel.pushNotification("Notifications.");
var ctx = canvas.get()[0].getContext('2d');
ctx.drawImage(img, 0, 0, 320, 240);
var data = canvas.get()[0].toDataURL('image/jpeg', 1.0);
newblob = dataURItoBlob(data);
stompClient.send("/app/vid", {}, newblob);
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
我试过发送 Blob,Uint8Array 消息已发送,但在服务器端我无法使用它。 我在控制器中的方法是:
@MessageMapping("/vid")
public void getVid(Message<byte[]> message, Principal principal) throws IOException {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
bOut.write(message.getPayload());
bOut.flush();
byte[] imageInByte = bOut.toByteArray();
bOut.close();
InputStream in = new ByteArrayInputStream(imageInByte);
BufferedImage bImageFromConvert = ImageIO.read(in);
ImageIO.write(bImageFromConvert, "jpeg", new File(
"E:/new-darksouls.jpg"));
template.convertAndSend("/topic/binarydemo2", message);
我使用了 ByteArrayMessageConverter、StringMessageConverter、MappingJackson2MessageConverter 和我编写的 Base64JavaObjectMessageConverter:
public class Base64JavaObjectMessageConverter extends AbstractMessageConverter {
public Base64JavaObjectMessageConverter() {
super(MimeTypeUtils.APPLICATION_OCTET_STREAM);
}
@Override
protected boolean supports(Class<?> clazz) {
return true;
}
@Override
public Object convertFromInternal(Message<?> message, Class<?> targetClass) {
byte[] messageBytes =Base64Utils.decode( (byte[])message.getPayload() );
return SerializationUtils.deserialize( messageBytes );
}
@Override
public Object convertToInternal(Object payload, MessageHeaders headers) {
byte[] messageBytes = SerializationUtils.serialize( payload );
return Base64Utils.encode( messageBytes);
}
}
我只能将 byte[] 作为字符串发送,从中删除 'base64' 等:
stompClient.send("/app/vid", {}, data.split(',')[1]);
在控制器中:
@MessageMapping("/vid")
public void getVid(String message, Principal principal) throws IOException {
byte[] bytearray = Base64.decode(message);
BufferedImage imag=ImageIO.read(new ByteArrayInputStream(bytearray));
ImageIO.write(imag, "jpg", new File("E:/new-darksouls.jpg"));
但这不是我想要达到的。我想这会影响性能。
我正在使用 Spring 4.2.0.RC1 WebSockets,StompJS 我在不同的帖子上读到,可以从后端发送到客户端,也可以从客户端发送到后端,但我无法重现它。如果我能得到一个具体的例子,如何在客户端构建和发送 Uint8Array 或 blob,以及如何在服务器端处理它,我将不胜感激。
感谢您的宝贵时间和帮助
SockJS 不支持发送二进制数据。您可以通过普通 WebSocket 使用 STOMP 发送二进制消息。
在服务器端,请参阅 StompSubProtocolHandler,它检查传入消息是二进制还是文本,因此可以处理其中任何一种。从那里它并不重要,即从 STOMP 的角度来看,body 是一个字节数组,content-type/content-length headers 确定 body 包含什么以及它应该如何解释。在发送端,StompSubProtocolHandler 也可以发送二进制或文本,目前如果 content-type 是 application/octet-stream 并且只要不使用 SockJS,它就使用二进制。
所以简而言之,在 WebSocket 上它应该可以工作,但在使用 SockJS 作为传输时就不行了。