【问题标题】:Spring WebSockets and SockJS - can't make fallback options workSpring WebSockets 和 SockJS - 无法使后备选项起作用
【发布时间】:2014-10-11 10:12:07
【问题描述】:

我正在研究 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. 收到回复消息

只要我使用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: Unexpected character ('%' (code 37)): 需要一个有效值(数字、字符串、数组、对象、'true'、'false' 或 'null')

这是一个堆栈跟踪:

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

【问题讨论】:

    标签: spring websocket sockjs


    【解决方案1】:

    经过一番探索,我发现服务器收到的消息看起来像%5B%22loki2302%22%5D=,它是URI编码的["loki2302"]=

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

    【讨论】:

    猜你喜欢
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 2015-12-16
    • 2016-01-27
    • 2016-07-26
    • 1970-01-01
    相关资源
    最近更新 更多