- 业务服务器想要推送消息时,不管是群里还是资料,可以连接任意服务器,只要推送给STOMP代理即可。STOMP代理会自行推送消息。
- 这样如果推送服务压力大时,可以任意扩容。
因此,在一些需要快速开发的项目中,后端使用了springboot,而且使用了STOMP协议,那么这个方案是一个不错的选择。
二、为什么使用RabbitMQ?
支持STOMP协议的中间件还有activemq
,但是rabbitmq相对来说更加强大,使用的人更多。
三、架构图
这个架构图和内存的broker类似,区别在于,左下角有一个专门存储消息的容器。这个容器就是RabbitMQ。当然,由这个架构图看来,在原有的功能上配置RabbitMQ只需要修改部分代码即可。
四、安装RabbitMQ
网上安装RabbitMQ的资料很多,这里我就不在陈述。如果安装Windows版本的RabbitMQ可以参考。我在测试时,用的是相对新一点的版本。
安装成功之后启用插件,注:这是两个命令,一个一个执行。
rabbitmq-plugins enable rabbitmq_stomp
rabbitmq-plugins enable rabbitmq_web_stomp
正常的RabbitMQ启用stomp协议之后,看下图
五、代码配置RabbitMQ
5.1、服务器端
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>websocket-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.42.Final</version>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>0.8.11.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置类WebSocketConfig.java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer
{
// 启用一个简单的基于内存的消息代理
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
//通过/topic 开头的主题可以进行订阅
config.enableSimpleBroker("/topic");
//send命令时需要带上/app前缀
config.setApplicationDestinationPrefixes("/app");
//配置RabbitMQ代理
// 配置支持的topic
config.enableStompBrokerRelay("/topic/","/queue/","exchange")
.setRelayHost("localhost") //地址
.setRelayPort(61613) //端口
.setClientLogin("guest") // 账号密码
.setClientPasscode("guest")
.setVirtualHost("/");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//连接前缀
registry.addEndpoint("/gs-guide-websocket")
.setAllowedOrigins("\*") // 跨域处理
.withSockJS(); //支持socketJs
}
}
控制器类
@Slf4j
@RestController
public class TestController
{
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@GetMapping ("/queue")
public void queue(HelloMessage message) throws Exception {
simpMessagingTemplate.convertAndSend ("/queue/user"+message.getUserId (),
new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"));
}
@GetMapping ("/topic")
public void topic(HelloMessage message) throws Exception {
simpMessagingTemplate.convertAndSend ("/topic/user"+message.getUserId (),
new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"));
}
}
5.2、H5端
var stompClient = null;
var userId = null;
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
}
else {
$("#conversation").hide();
}
$("#greetings").html("");
}
## 结局:总结+分享
看完美团、字节、腾讯这三家的一二三面试问题,是不是感觉问的特别多,可能咱们真的又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。
开篇有提及我可是足足背下了**Java互联网工程师面试1000题**,多少还是有点用的呢,换汤不换药,不管面试官怎么问你,抓住本质即可!能读到此处的都是真爱
* **Java互联网工程师面试1000题**
![image.png](https://img-blog.csdnimg.cn/img_convert/86932137d5fe53b5efa25943d6c6eaff.webp?x-oss-process=image/format,png)
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的 《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
* **程序员代码面试指南--IT名企算法与数据结构题目最优解**
![image.png](https://img-blog.csdnimg.cn/img_convert/e679468bfb8a51eddabac4d5c98264a7.webp?x-oss-process=image/format,png)
* 其余像设计模式,建议可以看看下面这4份PDF(已经整理)
![image.png](https://img-blog.csdnimg.cn/img_convert/5a18ee62d361b48700e53edccc501cbf.webp?x-oss-process=image/format,png)
* 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。
![image.png](https://img-blog.csdnimg.cn/img_convert/3aba00a1b7cba9157a75f9737812e9bc.webp?x-oss-process=image/format,png)
以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!
mg-naTjHebR-1719181353161)]
* 其余像设计模式,建议可以看看下面这4份PDF(已经整理)
[外链图片转存中...(img-ilkMY9g6-1719181353162)]
* 更多的Java面试学习笔记如下,关于面试这一块,我额外细分出Java基础-中级-高级开发的面试+解析,以及调优笔记等等等。。。
[外链图片转存中...(img-jsoC04Mp-1719181353162)]
以上所提及的全部Java面试学习的PDF及笔记,如若皆是你所需要的,那么都可发送给你!