通过WebSocket传输RSocket
默认情况下,RSocket通信是通过TCP套接字进行的。但在有些情况下,TCP协议并不是可行的方案。我们可以考虑以下两种情况:
-
客户端是用JavaScript编写的,在用户的Web浏览器中运行;
-
客户端必须穿过网关或防火墙边界才能到达服务器,而防火墙不允许通过任意端口进行通信。
此外,WebSocket本身缺乏对路由的支持,需要我们在应用层定义路由配置的细节。通过将RSocket构建在WebSocket之上,WebSocket能够从RSocket内置的路由支持中受益。
在这种情况下,RSocket可以通过WebSocket传输。WebSocket通信会使用HTTP实现,这是所有网络浏览器的主要通信手段,并且通常会被允许穿越防火墙。
要从TCP传输切换到WebSocket传输,我们只需要在服务器和客户端做一些小的改动。首先,由于WebSocket是通过HTTP传输的,需要确保服务器端的应用支持处理HTTP请求。简单地说,需要在项目的构建文件中添加以下WebFlux starter依赖(如果还没有添加):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
还需要通过设置 spring.rsocket.server.transport 属性来表明希望在服务器端配置中使用 WebSocket 进行传输。此外,需要通过设置spring.rsocket.server.mapping-path属性以配置RSocket通信时所使用的HTTP路径。在application.yml中,服务器的配置如下所示:
spring:
rsocket:
server:
transport: websocket
mapping-path: /rsocket
与通过特定端口进行通信的TCP传输不同,WebSocket传输会使用HTTP路径。因此,我们不需要像在TCP上运行的RSocket那样设置spring.rsocket.server.port属性。
以上是在服务器端为RSocket启用WebSocket传输要做的一些特殊工作,其他工作与TCP方式完全相同。
对于客户端,只需进行一个小改动。我们需要通过调用RSocketRequester.Builder上的websocket()方法来创建一个基于WebSocket的requester,以取代基于TCP的requester,如下所示:
RSocketRequester requester = requesterBuilder.websocket(
URI.create("ws://localhost:8080/rsocket"));
requester
.route("greeting")
.data("Hello RSocket!")
.retrieveMono(String.class)
.subscribe(response -> log.info("Got a response: {}", response));
这就是在WebSocket上传输RSocket所需的全部改动!