如何使用和自定义MessageConversion(Spring websocket客户端)

时间:2017-01-12 03:52:23

标签: spring spring-mvc websocket stomp

我用spring编写了一个Web套接字服务器和一个客户端。代码如下。向服务器发送消息的代码工作,但sesssion.subscribe方法无法从服务器接收消息。我搜索了许多文件并检查了我的代码。我不知道为什么它不起作用。

这是我的客户代码:

public class Test {

    public static void main(String[] args) {

        Thread thread = new Thread(new WebsocketThread());
        thread.start();
        Thread.sleep(5000);
    }
}

class MyStompSessionHandler extends StompSessionHandlerAdapter {

    @Override
    public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
        session.send("/app/messages", "{'payload3':2222}".getBytes());
        session.subscribe("/user/queue/position-updates", new StompFrameHandler() {

            @Override
            public Type getPayloadType(StompHeaders headers) {
                return String.class;
            }

            @Override
            public void handleFrame(StompHeaders headers, Object payload) {
                System.out.println("test:" + payload);
            }

        });
    }
}

class WebsocketThread implements Runnable{
    @Override
    public void run() {
        List<Transport> transports = new ArrayList<>(1);
        transports.add(new WebSocketTransport( new StandardWebSocketClient()) );
        WebSocketClient webSocketClient = new SockJsClient(transports);
        WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);

        String url = "ws://127.0.0.1:8860/orders";
        StompSessionHandler sessionHandler = new MyStompSessionHandler();
        ListenableFuture<StompSession> future = stompClient.connect(url, sessionHandler);
    }
}

这是我的服务器代码:

@Controller
public class TestController {

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/messages")
    public void sendUserMsg(String messages) throws IOException {
        System.out.println("webSocket:" + messages);
        simpMessagingTemplate.convertAndSend("/queue/position-updates", "This is return message");
    }
}

这是例外:

org.springframework.messaging.converter.MessageConversionException:没有合适的转换器,payloadType = class java.lang.String,handlerType = class com.example.hello.MyStompSessionHandler     在org.springframework.messaging.simp.stomp.DefaultStompSession.invokeHandler(DefaultStompSession.java:419)     在org.springframework.messaging.simp.stomp.DefaultStompSession.handleMessage(DefaultStompSession.java:373)     在org.springframework.web.socket.messaging.WebSocketStompClient $ WebSocketTcpConnectionHandlerAdapter.handleMessage(WebSocketStompClient.java:342)     在org.springframework.web.socket.sockjs.client.AbstractClientSockJsSession.handleMessageFrame(AbstractClientSockJsSession.java:267)     在org.springframework.web.socket.sockjs.client.AbstractClientSockJsSession.handleFrame(AbstractClientSockJsSession.java:200)     at org.springframework.web.socket.sockjs.client.WebSocketTransport $ ClientSockJsWebSocketHandler.handleTextMessage(WebSocketTransport.java:162)     在org.springframework.web.socket.handler.AbstractWebSocketHandler.handleMessage(AbstractWebSocketHandler.java:43)     在org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:110)     在org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access $ 000(StandardWebSocketHandlerAdapter.java:42)     at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter $ 3.onMessage(StandardWebSocketHandlerAdapter.java:81)     at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter $ 3.onMessage(StandardWebSocketHandlerAdapter.java:78)     at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:399)     at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:500)     在org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:295)     在org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)     在org.apache.tomcat.websocket.WsFrameClient.processSocketRead(WsFrameClient.java:73)     在org.apache.tomcat.websocket.WsFrameClient.access $ 300(WsFrameClient.java:31)     在org.apache.tomcat.websocket.WsFrameClient $ WsFrameClientCompletionHandler.completed(WsFrameClient.java:131)     在org.apache.tomcat.websocket.WsFrameClient $ WsFrameClientCompletionHandler.completed(WsFrameClient.java:114)     at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)     at sun.nio.ch.Invoker $ 2.run(Invoker.java:218)     at sun.nio.ch.AsynchronousChannelGroupImpl $ 1.run(AsynchronousChannelGroupImpl.java:112)     在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)     在java.lang.Thread.run(Thread.java:745)

4 个答案:

答案 0 :(得分:0)

您似乎没有在Web套接字配置中配置任何org.springframework.messaging.converter.MessageConverter。  如果你的类路径上有jackson jar,那么它将自动被选中以进行json转换。对于其他转换器,您需要在WebSocket配置文件中进行配置。

 @Configuration
 @EnableWebSocketMessageBroker
 @ComponentScan(SpringScanPackageNames)
  public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 
@Override
public boolean configureMessageConverters(List<MessageConverter> arg0) {

    StringMessageConverter strConvertor = new StringMessageConverter();
    arg0.add(strConvertor);
    return true;
}
// Other config

答案 1 :(得分:0)

我有一个类似的问题(尽管我正在发送自定义对象),而对我有用的只是将Jackson2Message消息转换器设置为

predict: types.pb.o types.grpc.pb.o tensor_shape.pb.o tensor_shape.grpc.pb.o resource_handle.pb.o resource_handle.grpc.pb.o model.pb.o model.grpc.pb.o tensor.pb.o tensor.grpc.pb.o predict.pb.o predict.grpc.pb.o prediction_service.pb.o prediction_service.grpc.pb.o predict.o
    $(CXX) $^ $(LDFLAGS) -o $@

我在https://github.com/Noozen/spring-boot-websocket-client#the-java-client

上找到了有用的信息(和示例)

答案 2 :(得分:-1)

将一个StringMessageConverter添加到Client,它可以工作。

WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
stompClient.setMessageConverter(new StringMessageConverter());

但是如何自定义我们自己的MessageConverter?有没有文章?

答案 3 :(得分:-1)

向客户端添加一个SimpleMessageConverter,它可以正常工作。

stompClient.setMessageConverter(new SimpleMessageConverter());