1. 概述

RSocket 应用层协议支持Reactive Streams 语义, 例如:用RSocket作为HTTP的一种替代方案。在本教程中, 我们将看到RSocket 用在spring boot中,特别是spring boot 如何帮助抽象出更低级别的RSocket API。

2. 依赖

让我们从添加spring-boot-starter-rsocket 依赖开始:

org.springframework.boot

spring-boot-starter-rsocket

这个依赖会传递性的拉取RSocket 相关的依赖,比如:rsocket-core 和rsocket-transport-netty

3.示例的应用程序

现在继续我们的简单应用程序。为了突出RSocket 提供的交互模式,我打算创建一个交易应用程序, 交易应用程序包括客户端和服务器。

3.1. 服务器设置

首先,我们设置由springboot应用程序引导的RSocket server 服务器。 因为有spring-boot-starter-rsocket dependency 依赖,所以springboot会自动配置RSocket server 。 跟平常一样, 可以用属性驱动的方式修改RSocket server 默认配置值。例如:通过增加如下配置在application.properties 中,来修改RSocket 端口

spring.rsocket.server.port=7000

也可以根据需要进一步修改服务器的其他属性

3.2.设置客户端

接下来,我们来设置客户端,也是一个springboot应用程序。虽然springboot自动配置大部分RSocket相关的组件,但还要自定义一些对象来完成设置。

@Configuration

public class ClientConfiguration {

@Bean

public RSocket rSocket() {

return RSocketFactory

.connect()

.mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE)

.frameDecoder(PayloadDecoder.ZERO_COPY)

.transport(TcpClientTransport.create(7000))

.start()

.block();

}

@Bean

RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) {

return RSocketRequester.wrap(rSocket(), MimeTypeUtils.APPLICATION_JSON, rSocketStrategies);

}

}

这儿我们正在创建RSocket 客户端并且配置TCP端口为:7000。注意: 该服务端口我们在前面已经配置过。 接下来我们定义了一个RSocket的装饰器对象RSocketRequester 。 这个对象在我们跟RSocket server 交互时会为我们提供帮助。 定义这些对象配置后,我们还只是有了一个骨架。在接下来,我们将暴露不同的交互模式, 并看看springboot在这个地方提供帮助的。

4.springboot RSocket 中的Request/Response

我们从Request/Response 开始,HTTP 也使用这种通信方式,这也是最常见的、最相似的交互模式。 在这种交互模式里, 由客户端初始化通信并发送一个请求。之后,服务器端执行操作并返回一个响应给客户端--这时通信完成。 在我们的交易应用程序里, 一个客户端询问一个给定的股票的当前的市场数据。 作为回复,服务器会传递请求的数据。

4.1.服务器

在服务器这边,我们首先应该创建一个controller 来持有我们的处理器方法。 我们会使用@MessageMapping 注解来代替像SpringMVC中的@RequestMapping 或者@GetMapping 注解

@Controller

public class MarketDataRSocketController {

private final MarketDataRepository marketDataRepository;

public MarketDataRSocketController(MarketDataRepository marketDataRepository) {

this.marketDataRepository = marketDataRepository;

}

@MessageMapping("currentMarketData")

public Mono currentMarketData(MarketDataRequest marketDataRequest) {

return marketDataRepository.getOne(marketDataRequest.getStock());

}

}

来研究下我们的控制器。 我们将使用@Controller 注解来定义一个控制器来处理进入RSocket的请求。 另外,注解@MessageMapping 让我们定义我们感兴趣的路由和如何响应一个请求。 在这个示例中, 服务器监听路由currentMarketData , 并响应一个单一的结果Mono 给客户端。

4.2. 客户端

接下来, 我们的RSocket客户端应该询问一只股票的价格并得到一个单一的响应。 为了初始化请求, 我们该使用RSocketRequester 类,如下:

@RestController

public class MarketDataRestController {

private final RSocketRequester rSocketRequester;

public MarketDataRestController(RSocketRequester rSocketRequester) {

this.rSocketRequester = rSocketRequester;

}

@GetMapping(value = "/current/{stock}")

public Publisher current(@PathVariable("stock") String stock) {

return rSocketRequester

.route("currentMarketData")

.data(new MarketDataRequest(stock))

.retrieveMono(MarketData.class);

}

}

注意:在示例中,RSocket 客户端也是一个REST 风格的controller ,以此来访问我们的RSocket 服务器。因此,我们使用@RestController 和@GetMapping 注解来定义我们的请求/响应端点。 在端点方法中, 我们使用的是类RSocketRequester 并指定了路由。 事实上,这个是服务器端RSocket 所期望的路由,然后我们传递请求数据。最后,当调用retrieveMono() 方法时,springboot会帮我们初始化一个请求/响应交互。

5.Spring Boot RSocket 中的Fire And Forget 模式

接下来我们将查看Fire And Forget 交互模式。正如名字提示的一样,客户端发送一个请求给服务器,但是不期望服务器的返回响应回来。 在我们的交易程序中, 一些客户端会作为数据资源服务,并且推送市场数据给服务器端。

5.1.服务器端

我们来创建另外一个端点在我们的服务器应用程序中,如下:

@MessageMapping("collectMarketData")

public Mono collectMarketData(MarketData marketData) {

marketDataRepository.add(marketData);

return Mono.empty();

}

我们又一次定义了一个新的@MessageMapping 路由为collectMarketData 。此外, Spring Boot自动转换传入的负载为一个MarketData 实例。 但是,这儿最大的不同是我们返回一个Mono ,因为客户端不需要服务器的返回。

5.2. 客户端

来看看我们如何初始化我们的fire-and-forget 模式的请求。 我们将创建另外一个REST风格的端点,如下:

@GetMapping(value = "/collect")

public Publisher collect() {

return rSocketRequester

.route("collectMarketData")

.data(getMarketData())

.send();

}

这儿我们指定路由和负载将是一个MarketData 实例。 由于我们使用send() 方法来代替retrieveMono() ,所有交互模式变成了fire-and-forget 模式。

6.Spring Boot RSocket 中的Request Stream

请求流是一种更复杂的交互模式, 这个模式中客户端发送一个请求,但是在一段时间内从服务器端获取到多个响应。 为了模拟这种交互模式, 客户端会询问给定股票的所有市场数据。

6.1.服务器端

我们从服务器端开始。 我们将添加另外一个消息映射方法,如下:

@MessageMapping("feedMarketData")

public Flux feedMarketData(MarketDataRequest marketDataRequest) {

return marketDataRepository.getAll(marketDataRequest.getStock());

}

正如所见, 这个处理器方法跟其他的处理器方法非常类似。 不同的部分是我们返回一个Flux 来代替Mono 。 最后我们的RSocket服务器会返回多个响应给客户端。

6.2.客户端

在客户端这边, 我们该创建一个端点来初始化请求/响应通信,如下:

@GetMapping(value = "/feed/{stock}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

public Publisher feed(@PathVariable("stock") String stock) {

return rSocketRequester

.route("feedMarketData")

.data(new MarketDataRequest(stock))

.retrieveFlux(MarketData.class);

}

我们来研究下RSocket请求。 首先我们定义了路由和请求负载。 然后,我们定义了使用retrieveFlux() 调用的响应期望。这部分决定了交互模式。 另外注意:由于我们的客户端也是REST 风格的服务器,客户端也定义了响应媒介类型MediaType.TEXT_EVENT_STREAM_VALUE 。

7.异常的处理

现在让我们看看在服务器程序中,如何以声明式的方式处理异常。 当处理请求/响应式, 我可以简单的使用@MessageExceptionHandler 注解,如下:

@MessageExceptionHandler

public Mono handleException(Exception e) {

return Mono.just(MarketData.fromException(e));

}

这里我们给异常处理方法标记注解为@MessageExceptionHandler 。作为结果, 这个方法将处理所有类型的异常, 因为Exception 是所有其他类型的异常的超类。 我们也可以明确地创建更多的不同类型的,不同的异常处理方法。 这当然是请求/响应模式,并且我们返回的是Mono 。我们期望这里的响应类型跟我们的交互模式的返回类型相匹配。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持聚米学院。

java调用r实例,Spring Boot中使用RSocket的示例代码相关推荐

  1. java动态创建bean的意义_java相关:Spring Boot如何动态创建Bean示例代码

    java相关:Spring Boot如何动态创建Bean示例代码 发布于 2020-3-20| 复制链接 摘记: 前言本文主要给大家介绍了关于Spring Boot动态创建Bean的相关内容,分享出来 ...

  2. Java笔记-Log4j在Spring Boot中的使用

    在Java企业级开发中都需要日志记录相关的操作. Maven相关配置如下,首先要去除Spring Boot自带的日志,然后添加log4j2的日志: <dependency><grou ...

  3. spring boot中利用mybatis-generator插件生成代码

    使用Idea在spring boot中集成mybatis-generator,自动生成mapper.xml  model  dao 文件 一.配置 pom.xml 在pom.xml的<plugi ...

  4. java项目开发实例spring boot框架实现的理财记账财务管理系统

  5. Spring Boot中的RSocket入门

    Introduction RSocket是一种二进制协议,可用于字节流传输,例如TCP,WebSockets和Aeron. 它通过通过单个连接传递的异步消息来启用以下对称交互模型: 请求/响应(1个流 ...

  6. java 消息服务框架_Java消息服务 在 Spring Boot 中的使用

    原标题:Java消息服务 在 Spring Boot 中的使用 当前环境 Mac OS 10.11.x docker 1.12.1 JDK 1.8 SpringBoot 1.5 前言 基于之前一篇&q ...

  7. Spring Boot中使用MongoDB,使用 Repository以及使用MongoTemplate

    文章目录 Spring Boot中使用MongoDB MongoDB Repository使用实例 导入依赖 配置MongoDB 定义Model 定义Repository 进行使用 MongoTemp ...

  8. java mapper control_java spring boot中怎么编写mapper?怎么编写service和controller?

    上次已经为大家介绍过java spring boot中怎么加入依赖的主要内容了.今天再为大家介绍一些与之相关的内容,也就是java spring boot中怎么 编写mapper以及怎么编写servi ...

  9. Spring Boot 中使用@Async实现异步调用,加速任务执行!

    欢迎关注方志朋的博客,回复"666"获面试宝典 什么是"异步调用"?"异步调用"对应的是"同步调用",同步调用指程序按照 ...

最新文章

  1. Httprunner测试
  2. [GO] go使用etcd和watch方法进行实时的配置变更
  3. 数位dp 记忆化搜索java_hdu 5787 数位dp,记忆化搜索
  4. [Google Guava] 2.4-集合扩展工具类
  5. linux shell 提示符设置
  6. 什么是地理数据库geodatabase?
  7. 计算机专业单元测试卷答案,银保监会考试题库:计算机类模拟试题练习(六)答案...
  8. 车载导航系统中常用物理量和单位
  9. java spliterator_java 8 stream中的Spliterator简介
  10. 【Luogu1363】幻想迷宫
  11. 使用octave符号运算求解不定积分、微分方程等(兼容matlab)
  12. ORACLE 常用操作命令
  13. 分享股票量化交易程序化模型的设计思路
  14. 虚拟机桥接模式ping不通外网的解决办法
  15. 马斯克航天新壮举:用1分38秒炸毁火箭,实现载人舱逃逸
  16. win10计算机管理员的权限才能删除,Win10文件夹删除不了需要管理员权限怎么办?Win10文件夹删除不了需要管理员权限的解决方法...
  17. 单链表之首尾相连,成对输出
  18. iOS开发之Moya网络请求使用与封装
  19. Angular真有React开发人员讲得那么差劲?
  20. 【AE表达式】300多个人名正从宇宙中飞来……

热门文章

  1. 软考 | 2018年上半年 软件设计师 下午试卷
  2. 成都奔驰加装原厂无钥匙舒适进入 成都名车汇
  3. 江南大学2023年851真题回顾
  4. 计算机考研视频哪个机构的好,计算机考研考点教学视频哪个好
  5. 《安富莱嵌入式周报》第272期:2022.06.27--2022.07.03
  6. ARouter 基础使用详解
  7. 质数筛的应用——等差素数列
  8. Excel常用查找函数,vlookup、match+index/offset
  9. 基于android的农产品销售App平台【可微信小程序与android studio运行】
  10. 开发知识竞赛答题活动小程序过程中使用到的实用工具库介绍