2015-06-16 8 views
2

Я хочу отправить двоичные данные из моего stompClient в контроллер пружины. это мой JSОтправка двоичных данных stompClient в контроллер Spring-websocket и потребление

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

} 

Я только могу отправить байт [], как удаление строки и т.д. '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 на клиенте и как справиться с ним на стороне сервера.

Спасибо за ваше время и помочь

+0

Не удается управлять. Я подключаюсь с помощью 'var socket = new Stomp.client ('ws: // server: port/spring-websocket-portfolio/portfolio'); var ws = Stomp.client (url); ws.binaryType = "arraybuffer"; 'Если я создаю Uint8Array и отправлю его, я получаю строку с типом объекта, который я отправил в контроллер. Сторона сервера конфигурации Websocket '@Override \t public void registerStompEndpoints (реестр StompEndpointRegistry) { \t \t registry.addEndpoint ("/portfolio "). WithSockJS(); \t \t \t} ' –

ответ

0

SockJS не поддерживает отправку двоичных данных. Вы можете отправлять двоичные сообщения с помощью STOMP через простой WebSocket.

На стороне сервера см. StompSubProtocolHandler, который проверяет, являются ли входящие сообщения двоичными или текстовыми и, следовательно, может обрабатывать либо. Оттуда это не имеет большого значения, то есть с точки зрения STOMP тело представляет собой массив байтов, а заголовки содержимого/длины содержимого определяют, что содержит тело, и как его следует проинформировать. На отправляющей стороне StompSubProtocolHandler может также отправлять либо двоичный, либо текстовый, и в данный момент он использует двоичный файл, если тип содержимого - это приложение/октет-поток, и пока SockJS не используется.

Так что вкратце над WebSocket он должен работать, но не при использовании SockJS в качестве транспорта.

+0

Кстати это стоит комментировать здесь на билет SockJS для бинарной поддержки сообщений ... https://github.com/sockjs/sockjs-protocol/issues/74. –

+0

Это не так сложно смешивать WebSocket и sockjs в одном приложении. Я попробую и посмотрю, что он даст. –

+0

Это не должно быть сложно. Если вы хотите, вы можете настроить конечную точку STOMP/SockJS на стороне сервера (например, по адресу URL/foo).Затем вы можете получить прямой websocket через «/ foo/websocket». Это встроено в протокол SockJS, поэтому вы можете получить доступ к необработанному веб-узлу на конечной точке SockJS, например, от другого, не-браузерного клиента. –

Смежные вопросы