Add getter for the length of a WebSocket message

This commit is contained in:
Rossen Stoyanchev 2014-03-20 16:35:58 -04:00
parent d4782647a4
commit ac968e94ed
7 changed files with 50 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -89,11 +89,9 @@ public abstract class AbstractWebSocketMessage<T> implements WebSocketMessage<T>
@Override
public String toString() {
return getClass().getSimpleName() + " payload= " + toStringPayload()
+ ", length=" + getPayloadSize() + ", last=" + isLast() + "]";
+ ", byteCount=" + getPayloadLength() + ", last=" + isLast() + "]";
}
protected abstract String toStringPayload();
protected abstract int getPayloadSize();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -83,7 +83,7 @@ public final class BinaryMessage extends AbstractWebSocketMessage<ByteBuffer> {
@Override
protected int getPayloadSize() {
public int getPayloadLength() {
return getPayload().remaining();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -44,13 +44,13 @@ public final class PingMessage extends AbstractWebSocketMessage<ByteBuffer> {
@Override
protected int getPayloadSize() {
return getPayload().remaining();
public int getPayloadLength() {
return (getPayload() != null) ? getPayload().remaining() : 0;
}
@Override
protected String toStringPayload() {
return getPayload().toString();
return (getPayload() != null) ? getPayload().toString() : null;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -44,7 +44,7 @@ public final class PongMessage extends AbstractWebSocketMessage<ByteBuffer> {
@Override
protected int getPayloadSize() {
public int getPayloadLength() {
return (getPayload() != null) ? getPayload().remaining() : 0;
}

View File

@ -16,6 +16,8 @@
package org.springframework.web.socket;
import java.nio.charset.Charset;
/**
* A text WebSocket message.
*
@ -24,6 +26,10 @@ package org.springframework.web.socket;
*/
public final class TextMessage extends AbstractWebSocketMessage<String> {
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final byte[] bytes;
/**
* Create a new text WebSocket message from the given CharSequence payload.
@ -31,6 +37,18 @@ public final class TextMessage extends AbstractWebSocketMessage<String> {
*/
public TextMessage(CharSequence payload) {
super(payload.toString(), true);
this.bytes = null;
}
/**
* Create a new text WebSocket message from the given byte[]. It is assumed the
* byte array can be encoded into an UTF-8 String.
*
* @param payload the non-null payload
*/
public TextMessage(byte[] payload) {
super(new String(payload, UTF_8));
this.bytes = payload;
}
/**
@ -43,17 +61,22 @@ public final class TextMessage extends AbstractWebSocketMessage<String> {
*/
public TextMessage(CharSequence payload, boolean isLast) {
super(payload.toString(), isLast);
this.bytes = null;
}
@Override
protected int getPayloadSize() {
return getPayload().length();
public int getPayloadLength() {
return asBytes().length;
}
public byte[] asBytes() {
return (this.bytes != null ? this.bytes : getPayload().getBytes(UTF_8));
}
@Override
protected String toStringPayload() {
return (getPayloadSize() > 10) ? getPayload().substring(0, 10) + ".." : getPayload();
return (getPayloadLength() > 10) ? getPayload().substring(0, 10) + ".." : getPayload();
}
}

View File

@ -29,6 +29,12 @@ public interface WebSocketMessage<T> {
*/
T getPayload();
/**
* Return the number of bytes contained in the message.
*/
int getPayloadLength();
/**
* When partial message support is available and requested via
* {@link org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()},

View File

@ -18,7 +18,6 @@ package org.springframework.web.socket.messaging;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.security.Principal;
import java.util.Arrays;
import java.util.List;
@ -56,13 +55,11 @@ import org.springframework.web.socket.WebSocketSession;
public class StompSubProtocolHandler implements SubProtocolHandler {
/**
* The name of the header set on the CONNECTED frame indicating the name of the user
* authenticated on the WebSocket session.
* The name of the header set on the CONNECTED frame indicating the name
* of the user authenticated on the WebSocket session.
*/
public static final String CONNECTED_USER_HEADER = "user-name";
private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
private static final Log logger = LogFactory.getLog(StompSubProtocolHandler.class);
@ -103,12 +100,12 @@ public class StompSubProtocolHandler implements SubProtocolHandler {
Throwable decodeFailure = null;
try {
Assert.isInstanceOf(TextMessage.class, webSocketMessage);
String payload = ((TextMessage) webSocketMessage).getPayload();
ByteBuffer byteBuffer = ByteBuffer.wrap(payload.getBytes(UTF8_CHARSET));
TextMessage textMessage = (TextMessage) webSocketMessage;
ByteBuffer byteBuffer = ByteBuffer.wrap(textMessage.asBytes());
message = this.stompDecoder.decode(byteBuffer);
if (message == null) {
decodeFailure = new IllegalStateException("Not a valid STOMP frame: " + payload);
decodeFailure = new IllegalStateException("Not a valid STOMP frame: " + textMessage.getPayload());
}
}
catch (Throwable ex) {
@ -150,9 +147,9 @@ public class StompSubProtocolHandler implements SubProtocolHandler {
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.ERROR);
headers.setMessage(error.getMessage());
Message<byte[]> message = MessageBuilder.withPayload(new byte[0]).setHeaders(headers).build();
String payload = new String(this.stompEncoder.encode(message), UTF8_CHARSET);
byte[] bytes = this.stompEncoder.encode(message);
try {
session.sendMessage(new TextMessage(payload));
session.sendMessage(new TextMessage(bytes));
}
catch (Throwable ex) {
// ignore
@ -203,7 +200,7 @@ public class StompSubProtocolHandler implements SubProtocolHandler {
byte[] bytes = this.stompEncoder.encode((Message<byte[]>) message);
synchronized(session) {
session.sendMessage(new TextMessage(new String(bytes, UTF8_CHARSET)));
session.sendMessage(new TextMessage(bytes));
}
}