最后我将我的websocket客户端连接到端点,但我无法提取消息有效负载。 我可以获取标题,但无法识别有效负载。
我的WebSocket客户端如下所示:
WebSocketTransport webSocketTransport = new WebSocketTransport(standardWebSocketClient);
SockJsClient sockJsClient = new SockJsClient(Arrays.asList(webSocketTransport));
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new StringMessageConverter());
StompSessionHandler sessionHandler = new MyStompSessionHandler();
ListenableFuture<StompSession> connect = stompClient.connect(URL, sessionHandler);
StompSession stompSession = connect.get();
System.out.println("sessionId: " + stompSession.getSessionId());
String path = "/queue/orders";
stompSession.subscribe(path, new MySimpleStompFrameHandler());
Stomp Frame Handler:
private class MySimpleStompFrameHandler implements StompFrameHandler {
@Override
public Type getPayloadType(StompHeaders stompHeaders) {
System.out.println("Headers " + stompHeaders.toString());
return String.class;
}
@Override
public void handleFrame(StompHeaders stompHeaders, Object payload) {
System.out.println("Msg " + payload.toString());
completableFuture.complete(payload.toString());
}
}
我在终端中写了标题但是handleFrame方法没有。 有什么想法吗?
编辑: 调试后我发现问题出在DefaultStompSession类中,该类使用了我的frameHandler实现
private void invokeHandler(StompFrameHandler handler, Message<byte[]> message, StompHeaders stompHeaders) {
if (message.getPayload().length == 0) {
handler.handleFrame(stompHeaders, null);
return;
}
Type type = handler.getPayloadType(stompHeaders);
Class<?> payloadType = ResolvableType.forType(type).resolve();
Object object = getMessageConverter().fromMessage(message, payloadType);
if (object == null) {
throw new MessageConversionException("No suitable converter, payloadType=" + payloadType +
", handlerType=" + handler.getClass());
}
handler.handleFrame(stompHeaders, object);
}
问题出在这一行Type type = handler.getPayloadType(stompHeaders);
之后,没有更多的事情被执行,我的程序刚刚结束,所以handleFrame()甚至没有被执行。
有什么问题?也许使用从getPayloadType返回的Type - 我选择String,因为我认为每条消息都可以表示为字符串。
答案 0 :(得分:0)
我有一个类似的问题。
问题是我指定了stompClient.setMessageConverter(new StringMessageConverter());
,而JSON作为有效负载传递了。
解决方案(针对我的问题):stompClient.setMessageConverter(new MappingJackson2MessageConverter());
如何找到解决方案:
触发异常时抛出(或记录)。对于您的情况,您应该在MyStompSessionHandler
中添加覆盖以下方法:
@Override
public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) {
throw new RuntimeException("Failure in WebSocket handling", exception);
}
在调试invokeHandler
时,请检查有效内容。如果您能够执行代码,则可以通过执行new String((byte[]) message.getPayload())
来实现。
答案 1 :(得分:0)
我的意思是,您需要扩展StompSessionHandlerAdapter
工具StompFrameHandler
。
我为您尝试过一些东西:
public class MySimpleStompFrameHandler extends StompSessionHandlerAdapter implements StompFrameHandler {
private Logger logger = LogManager.getLogger(MyStompSessionHandler.class);
@Override
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
System.out.println("Connected");
}
@Override
public void handleException(StompSession session, StompCommand command, StompHeaders
headers, byte[] payload, Throwable exception) {
logger.error("Got an exception", exception);
}
@Override
public Type getPayloadType(StompHeaders headers) {
return <payload_type>.class;
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
<payload_type> msg = (<payload_type>) payload;
System.out.println(msg);
logger.info("Received : " + msg);
}
}
payload_type
是您要转换流数据的用户定义的类
好去!
答案 2 :(得分:0)
我分享我的实现方式,希望对您有所帮助。 我没有设置messageconverter,而是对方法 handleFrame
进行了自定义实现<link to='path' />
<a href='path'
,然后处理发送的消息(在我的情况下为JSON字符串对象)
WebSocketClient client = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(client);
StompSessionHandler sessionHandler = new MyStompSessionHandler(prop);
WebSocketHttpHeaders webSocketHttpHeaders = new WebSocketHttpHeaders();
webSocketHttpHeaders.add("Authorization", "Bearer " + token);
StompSession session = stompClient.connect(endpoint, webSocketHttpHeaders, sessionHandler).get();
答案 3 :(得分:0)
需要定义MessageConverter,然后实现对象类型为JSON的getPayloadType方法
SockJsClient sockJsClient = new SockJsClient(transports);
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(**new MappingJackson2MessageConverter()**);
....
public class SockJsWebsocketSubscriptionHandler implements StompFrameHandler {
@Override
public Type getPayloadType(StompHeaders headers) {
return **HelloMessage.class;**
}
...
}