前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC 教程 - SockJS

SpringMVC 教程 - SockJS

作者头像
代码拾遗
发布2018-07-24 15:54:38
1.9K1
发布2018-07-24 15:54:38
举报
文章被收录于专栏:代码拾遗代码拾遗

在公网上,一些代理可能会阻止WebSocket交互,有的代理会配置不传递Upgrade头,有的会断开空闲的连接。 可以使用仿真来解决这个问题,例如:首先尝试使用WebSocket连接,失败后是用基于HTTP的技术,模仿WebSocket的交互,并且暴露相同的API。 Spring使用了SockJS协议来支持。

概览

SockJS的目标是使用WebSocket的API,当WebSocket不可用的时候使用非WebSocket的选项,而无需修改代码。 SockJS包括:

  • SockJS 协议
  • SockJS JavaScript 客户端
  • SockJS服务端实现,spring-wesocket 模块中实现了这个。
  • spring-websocket 提供了SockJS的Java客户端

SockJS是设计在浏览器中使用的。查询SockJS Client来查看SockJS支持的浏览器。支持三种方式传输数据:WebSocket,HTTP Streaming,HTTP长轮询。 当SockJS发送 GET /info 请求的时候,服务端需要决定使用哪种传输格式,首先会检查WebSocket,如果不行则使用HTTP Streaming,如果还是不行就使用HTTP的长轮询。

URL 的格式如下:

代码语言:javascript
复制
http://host:port/myApp/myEndpoint/{server-id}/{session-id}/{transport}
  • {server-id} 集群中路由请求的时候使用
  • {session-id} SockJS相关的session
  • {transport} 使用的transport类型,例如,WebSocket

WebSocket 只需要一个HTTP请求用来握手,剩下的都只需要单个链接即可完成交互 HTTP 需要更多的请求。例如:Ajax/XHR streaming 依赖于一个长时间运行的server到client的请求。长轮询则每次都会进行请求查询。 SockJS简化了消息帧,例如:server发送 o 表示(open),如果25秒没有消息发送 h 表示 heartbeat 心跳。c 表示close等。

打开SockJS

Java配置:

代码语言:javascript
复制
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler").withSockJS();
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}

XML 配置:

代码语言:javascript
复制
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <websocket:handlers>
        <websocket:mapping path="/myHandler" handler="myHandler"/>
        <websocket:sockjs/>
    </websocket:handlers>

    <bean id="myHandler" class="org.springframework.samples.MyHandler"/>

</beans>

在浏览器中直接使用socket-client

如果使用了iframe,那么需要在http 响应头设置 X-Frame-Options为:SAMEORIGIN,ALLOW-FROM。 Java 配置:

代码语言:javascript
复制
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/portfolio").withSockJS()
                .setClientLibraryUrl("http://localhost:8080/myapp/js/sockjs-client.js");
    }

    // ...

}
心跳

SockJS协议要求服务端发送心跳信息,防止代理挂起链接。SockJS配置heartbeatTime来设置心跳的频率。没有其他消息发送的时候,默认心跳时间为25秒。25秒的设置是依据IETF recommendation的推荐设置。 Spring SockJS 同样也可以配置TaskScheduler管理心跳任务。

客户端断开连接

HTTP Streaming和长轮询模式要求请求比之前持续的时间更长。在Servlet容器中,Servlet 3 异步特性可以支持这个功能。但是Servlet API在客户端断开连接的时候并没有发送消息。当像一个已经关闭的链接写入响应的时候,Servlet 容器会抛出异常。

SockJS 跨域

SockJS使用CORS来支持跨域问题。CORS头是自动加的,所以如果已经在SpringMVC配置了的话就可以完全跳过这部分。 SockJS 支持的头:

  • Access-Control-Allow-Origin:请求头的Origin
  • Access-Control-Allow-Credentials: 一直是true
  • Access-Control-Request-Headers:来自请求头的相同的头
  • Access-Control-Allow-Methods:支持协议的方法
  • Access-Control-Max-Age: 31536000(一年)
SockJs 客户端

SockJS提供了Java客户端可以不使用浏览器就可以访问服务器。这样在公网上两台服务器双向通信的时候非常的方便。例如代理可能会组织使用WebSocket。同样,SockJS的Java客户端也很适合做测试,例如测试同时访问最多用户数。 SockJS的Java客户端支持websocket,xhr-streaming,xhr-polling传输协议。 示例如下:

代码语言:javascript
复制
List<Transport> transports = new ArrayList<>(2);
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
transports.add(new RestTemplateXhrTransport());

SockJsClient sockJsClient = new SockJsClient(transports);
sockJsClient.doHandshake(new MyWebSocketHandler(), "ws://example.com:8080/sockjs");

配置:

代码语言:javascript
复制
@Configuration
public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/sockjs").withSockJS()
            .setStreamBytesLimit(512 * 1024)
            .setHttpMessageCacheSize(1000)
            .setDisconnectDelay(30 * 1000);
    }

    // ...
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 代码拾遗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概览
  • 打开SockJS
  • 心跳
  • 客户端断开连接
  • SockJS 跨域
  • SockJs 客户端
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档