Spring WebSockets和SockJS - 不能使后备选项工作

时间:2014-10-11 10:12:07

标签: spring websocket sockjs

我正在查看Spring的新WebSockets / SockJS功能,并尝试强制回退到其中一个非WebSocket传输。无法使其发挥作用。以下是详细信息。

这是我的配置(只有一个配置类):

@Configuration
@EnableWebSocket
@EnableAutoConfiguration
public class Config implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(dummyHandler(), "/hello").withSockJS();
    }

    @Bean
    public DummyServerWebSocketHandler dummyHandler() {
        return new DummyServerWebSocketHandler();
    }
}

DummyServerWebSocketHandler非常简单:它是带有一些日志记录的回显服务。然后,我的测试是:

  1. 使用SockJS客户端
  2. 进行连接
  3. 发送消息
  4. 收到回复信息
  5. 只要我使用WebSocketTransport

    ,此方案就可以正常运行
    SockJsClient sockJsClient = new SockJsClient(Arrays.<Transport>asList(
        new WebSocketTransport(new StandardWebSocketClient())));
    
    WebSocketConnectionManager webSocketConnectionManager = new WebSocketConnectionManager(
        sockJsClient,
        new DummyClientWebSocketHandler(messageExchanger),
        "ws://localhost:8080/hello");
    webSocketConnectionManager.start();
    

    日志是:

    o.s.w.s.c.WebSocketConnectionManager     : Connecting to WebSocket at ws://localhost:8080/hello
    me.loki2302.DummyServerWebSocketHandler  : /127.0.0.1:50847 connected
    tHandlerTest$DummyClientWebSocketHandler : connected to localhost/127.0.0.1:8080
    o.s.w.s.c.WebSocketConnectionManager     : Successfully connected
    me.loki2302.DummyServerWebSocketHandler  : /127.0.0.1:50847 says: loki2302
    tHandlerTest$DummyClientWebSocketHandler : localhost/127.0.0.1:8080 says: hello loki2302!
    me.loki2302.DummyServerWebSocketHandler  : /127.0.0.1:50847 disconnected
    tHandlerTest$DummyClientWebSocketHandler : localhost/127.0.0.1:8080 disconnected
    

    然后我将sockJsClient构造更改为:

    SockJsClient sockJsClient = new SockJsClient(Arrays.<Transport>asList(
        new RestTemplateXhrTransport()));
    

    这是唯一的改变。日志是:

    o.s.w.s.c.WebSocketConnectionManager     : Connecting to WebSocket at ws://localhost:8080/hello
    me.loki2302.DummyServerWebSocketHandler  : /127.0.0.1:50919 connected
    tHandlerTest$DummyClientWebSocketHandler : connected to localhost/127.0.0.1:8080
    s.w.s.s.t.h.XhrReceivingTransportHandler : Failed to read message
    

    抛出的异常是:

      

    com.fasterxml.jackson.core.JsonParseException:意外字符(&#39;%&#39;(代码37)):预期有效值(数字,字符串,数组,对象,&#39; true&# 39;,&#39; false&#39;或&#39; null&#39;)

    这是一个堆栈跟踪:

    com.fasterxml.jackson.core.JsonParseException: Unexpected character ('%' (code 37)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
     at [Source: java.io.ByteArrayInputStream@ef6a283; line: 1, column: 2]
        at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1419)
        at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:508)
        at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:437)
        at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2363)
        at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:794)
        at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:690)
        at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3090)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3036)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2192)
        at org.springframework.web.socket.sockjs.frame.Jackson2SockJsMessageCodec.decodeInputStream(Jackson2SockJsMessageCodec.java:55)
        at org.springframework.web.socket.sockjs.transport.handler.XhrReceivingTransportHandler.readMessages(XhrReceivingTransportHandler.java:41)
        at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpReceivingTransportHandler.handleRequestInternal(AbstractHttpReceivingTransportHandler.java:56)
        at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpReceivingTransportHandler.handleRequest(AbstractHttpReceivingTransportHandler.java:48)
        at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:256)
        at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:328)
        at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:90)
        at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
    

    首先,我不确定它是否应该像这样工作。然后,如果它应该工作,有什么我想念的吗?

    我正在使用org.springframework.boot:spring-boot-starter-websocket:1.2.0.M1

1 个答案:

答案 0 :(得分:3)

经过一些探索后,我发现服务器收到的邮件看起来像%5B%22loki2302%22%5D=,这是URI编码的["loki2302"]=

一旦我将RestTemplate的默认SimpleClientHttpRequestFactory替换为HttpComponentsClientHttpRequestFactory,问题就消失了,服务器收到的请求现在只是["loki2302"]