了解Spring Stomp,这一篇就够了

前言

最近在公司的项目中使用了Spring Stomp,对Spring stomp 有了一定的了解,记录于此。

一句话介绍:Spring Stomp是Spring在Spring WebSocket的基础之上适配了stomp消息协议的组件/框架。
现在看到这一句话可能不知所云,看完本问后应该就可以理解了。

先对上面一句话的几个概念做一个简要说明:

  • Spring Websocket:这个应该都知道,是Spring针对长链协议(WebSocket)的一个组件;
  • Stomp:全称:Simple Text Oriented Message Protocol,即基于文本的简单消息协议;

接下来首先对Stomp做一个简单的介绍

Stomp

Stomp是一个消息协议,它可以工作在任何可靠的全双工通信协议(比如TCP、WebSocket)上,它一开始是为脚本语言服务的,目的是方便与RabbitMQ、ActiveMQ等消息中间件进行通信,它规定了通信时消息的格式,如下:

COMMAND
header1:value1
header2:value2

Body^@

第一行是一个命令:最常用的命令有SEND、SUBSCRIBE、CONNECT等。
接下来的多行是消息的头部(headers),每行一对键值对。

常用的头部信息:
destination: 其值为一个字符串,一般使用文件路径的格式,表示消息要发往的目的地(比如发往消息中间件的哪个主题、队列)

接下来一个空行:分割消息头和消息体
接下来是消息体(payload):消息要传递的具体内容

对于stomp大致了解这么多即可

Spring Stomp

简介

Spring WebSocket:Spring针对长链接协议的一个组件,使用Spring WebSocket可以让服务端开发人员方便快速的开发部署一个长链服务。
Spring Stomp:Spring Websocket确实方便了开发长链服务,不需要自己处理链接的建立、握手等底层问题,但是对于客户端与服务端要传递的消息,需要开发者自己定义一套自己的消息协议,以方便对消息的解析处理。而Spring Stomp正是在Spring WebSocket的基础上,进一步引入并支持了对Stomp这一消息协议的解析处理,并且做了很多其他方便开发者使用的功能。

Simple Broker

既然支持了Stomp协议,Spring Stomp首先实现了一个简单的消息中间件(类似于RabbitMQ、ActiveMQ),称为Simple in memory broker(后文简称为simple broker)。这个simple broker可以实现一些消息中间件的功能:

客户端A向服务端发送如下消息:

SUBSCRIBE
id:sub-1
destination:/topic/a

^@

simplebroker收到此条消息后,即将客户端A视作主题a下的一个订阅者。

客户端B向服务端发送如下消息:

SEND
destination:/topic/a
content-type:application/json
content-length:44

{"action":"BUY","ticker":"MMM","shares",44}^@

收到客户端B向主题a发送的消息,即获取当前主题a下的所有订阅者,将消息转发给这些订阅者们。

上面简单介绍了下消息中间件做的事儿。本来 spring stomp做这些已经够了,这比起springwebsocket已经极大的方便了开发,因为它维护了客户度的session,并且支持消息在各个session的转发路由,只需要客户端发送不同的stomp帧就行了;可是spring在此基础上就增加了更为重要的、更加方便开发者使用的功能,我称之为MessageMapping。接下来对这一点进行说明。

Message Mapping

上一节说,作为一个消息中间件,客户端发的消息到服务端被simple broker处理,其实,到达服务端的消息,除了被simple broker处理,spring还增加了另一种消息处理方法——将消息路由到某一个方法。是不是有点熟悉?没错,和SpringMVC处理Http请求类似,先来简要回顾一下springMvc处理Http request的方式:

请求到达服务端后,根据其url,路由到某一个controller的某一个被@RequestMapping注解修饰的方法,方法处理完后,返回response

上面这个方式我称为RequestMapping,这时候是不是懂了本节小标题MessageMapping的含义?其处理方式大致如下:

消息到达服务端后,根据其destination,路由到某一个controller的某一个被@MessageMapping注解修饰的方法。(方法处理完后的返回值后面会说到)

Flow of Message

上面两小节,一小节说消息被simplebroker处理,一小节又说消息被controller某个方法处理,这两者是什么关系?什么时候被simple broker处理,什么时候被controller处理?这就是本小节要说的——消息的流向。
消息在到达服务端后,spring定了一个规则:根据其header的destination属性的值,来确定该条消息被谁处理

  • 以topic、queue(可以自定义)开头、或者为空的,由simple broker处理(SimpleBrokerMessageHandler)
  • 以app(可以自定义)开头的,由controller处理(AnnotationMethodMessageHandler)
  • 以user(可以自定义)开头的,由UserDestinationMessageHandler处理

这只是对于从客户端来的消息,发到服务端后的第一步处理的路由,下面说一下第一步之后的处理:

  1. 对于以topic、queue开头的被simple broker处理的消息,后续处理自然是根据消息的destination将消息转发给订阅者
  2. 对于以app开头的消息,假设其destination为 /app/method1 ,经过AnnotationMethodMessageHandler,路由到具体的方法后:
    • 如果方法没有返回值,则方法处理完后,这个消息就走完了全流程
    • 如果方法有返回值,则返回值作为一个新的Message被发往simple broker,经由simple broker将消息转发给另一个(或多个,取决于destination,以topic开头则广播,以queue开头则单播)客户端用户。

      simple broke是怎么决定要把该新消息发往哪个客户端呢?也即新消息的destination是什么?

      • 默认情况下,其destination为:/topic/method1,即消息来时的子路径method1前面加上topic
      • 如果不想使用默认行为,则可以在方法上标记注解:@SendTo @SendToUser
  3. 对于以user开头的消息,其destination必须遵守格式:/user/{username}/queue/{diy string}。被UserDestinationMessageHandler处理后,最终也是交由simple broker,发往{username}指定的用户。

可以看到,以app、user开头的消息最终也会交由simple broker处理,进行消息的转发。

说明:对于消息的destination,不推荐直接以queue开头,queue在stomp中被用于表示一对一的消息,并且一般和/user绑定在一起:/user/queue。

小结

综上,对于Spring Stomp大致的结构做一个总结:
首先,其核心是一个Simple Broker,这个simple broker 可以维护客户端的session,接受消息并转发。围绕这个simple broker,spring stomp又定了一些规则、开发了一些MessageHandler,使得消息不仅可以直接发往broker,还可以先经由其他的MessageHandler(simple broker 也算作一种message handler)处理,生成新的消息,然后再发往broker,这使得开发者可以对消息进行干预和进一步的处理,并能控制、改变消息的转发路径。

在这里插入图片描述

本文先到这里,

  • 对springstomp从概念上有一个大的了解和认识,知道他是干什么的,
  • 引入一些概念及英文单词,方便对后续文章以及spring官方文档的理解,尤其是对官方文档,看了本篇文章,相信你再看到官网的图时会很好理解了。
    我觉得以上两点很重要!
    后续会对spring的使用 结合源码做一个介绍说明。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值