一、写在前面的问题和解决办法

1、问题背景:

RabbitMQ,用websock推送消息失败

2、问题描述:

服务器错误:Whoops! Lost connection to ws://localhost:15674/ws

3、解决办法:

网上查了好久说,加上这个jackson-core的jar包。我加啦啊!没有用啊!
我还换了版本试了还是报这个错。

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.0</version></dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.11.0</version></dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.11.0</version></dependency>

后来发现是因为没有启用Web STOMP插件,我真是愚蠢的humanbeing~

在RabbitMQ服务器的sbin目录下

rabbitmq-plugins enable rabbitmq_web_stomp


然后就成功啦~

O_OO_OO_OO_OO_OO_OO_O详细的学习笔记O_OO_OO_OO_OO_OO_OO_O

二、RabbitMQ学习笔记

最近在学习消息队列,参考的书籍是《分布式消息中间件实践》和网课(叫啥消息队列高手课,等我后面确认下),作为一个笔记狂魔,每次学习我都产出大量的笔记,那也不是每篇笔记都分享的,写这篇是因为在学习RabbitMQ的时候遇到了好多的问题,一一解决后,整理出来解决的过程和办法,还有一些自己的理解和总结。

(一)RabbitMQ的简单介绍

在学习了几款MQ产品以后,RabbitMQ给我的感觉就是,有点特别,与众不同。
(1)消息队列的模式
一般来说,消息队列有两种模式,一种是队列模式(点对点),一种是发布/订阅模式,
两个最大的区别就在于,一份消息能不能被消费多次的问题。
如果发布/订阅模式的订阅者只有一个,那就跟队列模式一样了。所以,发布/订阅模式是兼容队列模式的。

为啥好端端要说这个模式呢?
因为大多数消息队列都是发布/订阅模式,而RabbitMQ它却是为数不多的队列模式。
那它是不是就不能实现一份消息被消费多次啦?
那也不是的,它虽然是队列模式,但是它有个special的路由功能,也可以实现消息被消费多次的功能。

(2)
RabbitMQ是基于Erlang语言的,这个语言十分的小众,而且比较难懂。
对于学Java这些语言的我们来说,就像母语是英语的人去学汉语一样,比较难。
所以如果有啥问题可能不太好改。

(3)RabbitMQ是AMQP协议的一个开源实现。
这个AMQP是消息协议的一种,用我新买的ipad pro加二代pencil画了一下这个协议的图(我照着书上画的,嘻嘻)。

这个Exchange是消息处理中心Broker里的。
就是一个路由规则的含义,里面有Routing Key和Queue的映射关系。
我感觉这个Exchange就像是一个快递员,收到了生产者Publisher传过来的消息,就去查一下自己的规则表,看看这个消息发给哪个Queue。
如果找不到对应的Queue,就把消息扔回去给生产者,或者直接丢掉(直接丢掉就是一个很坏的快递员,哼╭(╯^╰)╮)
我又感觉这个Queue就像不同的菜鸟驿站的站点,嘻嘻。
如果消费者订阅了消息队列,消息队列收到消息就会尝试将消息传递给消费者,如果传递不成功,就把消息先存下来,等消费者来拿。(是不是真的很像菜鸟驿站)

然后我又感觉这个Exchange是个法师,如果看到一条消息对应了多个队列的话,它就会把这条消息复制成多个一毛一样的消息,发给不同的队列。(发现一个快递有好多人需要,就复刻了好多一模一样的)

哎呀,越写越多,想写的还没写呢。

(二)环境搭建

1、Erlang和RabbitMQ服务器
前面不是说啦RabbitMQ是基于Erlang语言的,所以要把RabbitMQ服务器启起来,还得下个Erlang。

需要注意的是,RabbitMQ和Erlang的版本要对应起来的,还不可以瞎下一个。
RabbitMQ和Erlang版本对应网站


Erlang下载网站
RabbitMQ下载网站

我选啦RabbitMQ 3.8.4 和Erlang 22.3
资源我也上传啦!没分的找我一下,我再分享百度云盘,这会儿有点懒。


安装了以后,要用的命令都在这个sbin里面,启动RabbitMQ服务器
到sbin目录下,执行命令

rabbitmq-server


然后在chrome浏览器输
http://localhost:15672/
然后有这个页面嘞

账号和密码都默认是guest.登录进去就是酱紫~

哇,虽然还没有做啥,只是顺利的跑出来这个页面,也是很开心呀~

(三)基于RabbitMQ的消息推送

其实上面写了辣么多,还没写到我真的想写的。
前面我也说啦,是学习的《分布式消息中间件实践》这本书。前面几个简单的例子,我就不写啦,对着书写一遍完全没得问题。
想写的是这个WebSocket通信的这节例子,啊,跑起来真的艰难,我一定要记录一下。

实现的功能我简单介绍一下,就是一个服务端,一个客户端网页,然后服务端向RabbitMQ推送一条消息的时候,客户端的网页就弹出来这条消息,即一个简单的广告推送功能。

1、服务端

(1)pom.xml

       <dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit</artifactId><version>2.0.2.RELEASE</version></dependency>

(2)生产者
写一个StompProducer.java类

package com.yolanda.rabbitmq.websocket;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;/*** @Author:Yolanda* @Date: 2020/6/17 18:16*/
public class StompProducer {public static void main(String[] args) throws Exception{ConnectionFactory factory = new ConnectionFactory();factory.setUsername("guest");factory.setPassword("guest");factory.setHost("localhost");factory.setVirtualHost("/");Connection conn = factory.newConnection();Channel channel = conn.createChannel();String exchangeName = "exchange-stomp";channel.exchangeDeclare(exchangeName, "topic");String routingKey = "shopping.discount";String message = "<a href=\"https://www.baidu.com\" target=\"_black\">我是广告</a>";channel.basicPublish(exchangeName, routingKey, null, message.getBytes());channel.close();conn.close();}
}

这个类的作用就是连上RabbitMQ并往里面发一条广告消息。

2、客户端

客户端Web网页页面接收消息
啊,这个书上的例子没说客户端写啥样啊,我用springboot写了一个

(1)目录结构

(2)pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.0.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.yolanda.rabbitmq</groupId><artifactId>cha3webclient</artifactId><version>0.0.1-SNAPSHOT</version><name>cha3webclient</name><description>Demo project for Spring Boot</description><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.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins><resources><resource><includes><include>static/**</include></includes></resource></resources></build></project>

哎呀,就是新建一个springboot的web项目,自带的那些依赖,然后要配上这段

        <resources><resource><includes><include>static/**</include></includes></resource></resources>

不配这个的话,在html里引用,那些静态资源读不到的

(3)新建的index.html


<html lang="en">
<head><meta charset="UTF-8"><title>rabbitMQ消息类型</title><link rel="stylesheet" type="text/css" href="default.css"><link rel="stylesheet" type="text/css" href="jquery.notify.css"><script type="text/javascript" src="stomp.js"></script>"<script type="text/javascript" src="jquery.min.js"></script><script type="text/javascript" src="jquery.notify.js"></script>
</head><script type="text/javascript">$(function () {// $.notifySetup({sound: 'jquery.notify.wav'});var client = Stomp.client("ws://localhost:15674/ws");var onConnect = function () {client.subscribe("/exchange/exchange-stomp/shopping.discount", function (message) {$("<p>" + message.body + "</p>").notify({stay: 10000});});};var onError = function (msg) {$("<p>服务器错误:" + msg + "</p>").notify("error");};client.connect("guest", "guest", onConnect, onError);client.heartbeat.incoming = 5000;client.heartbeat.outgoing = 5000;});</script>
<body></body>
</html>

(4)springboot的启动类Cha3webclientApplication.java,默认的没改过。

package com.yolanda.rabbitmq.cha3webclient;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Cha3webclientApplication {public static void main(String[] args) {SpringApplication.run(Cha3webclientApplication.class, args);}}

(5)验证效果~
这个顺序还是有点讲究的。

Step1.启动rabbitMQ服务器(前面说过了),到sbin目录下

rabbitmq-server

Step2.启用Web STOMP插件(前面也说过了),到sbin目录下

rabbitmq-plugins enable rabbitmq_web_stomp

Step3.客户端用springboot跑起来
Chrome输入localhost:8080

啥也没有,不要着急

Step4.运行一下刚才写的生产者StompProducer.java类

看吧,客户端网页收到服务端生产者推送过来的广告消息啦~

本文所有涉及的服务端,包括静态资源和客户端代码链接在这里
Git完整代码

消息队列实践一之RabbitMQ消息推送(解决服务器错误:Whoops! Lost connection to ws://localhost:15674/ws)相关推荐

  1. 信息推送分发服务器系统,消息事件的分发方法、分发平台、系统及服务器专利_专利查询 - 天眼查...

    1.一种消息事件的分发方法,其特征在于,包括:如果监测到消息发布服务发布的消息事件,获取预先存储的配置信息:其中,所述配置信息包括所述消息发布服务,以及所述消息发布服务对应的至少一个消息订阅服务:根据 ...

  2. RabbitMQ:什么是消息队列MQ?为什么使用消息队列MQ?入门MQ先学哪种?(一)

    0. 引言 MQ(Message Queue):消息队列,如今在各类业务场景中已经被广泛使用,特别在并发量日益增涨的业务和微服务架构中,消息队列能够帮助我们解决很多传统方式所不能解决的问题. 所以今天 ...

  3. c++ createtoolhelp32snapshot取进程路径_Linux进程间通信(上)之管道、消息队列实践

    1.进程间通信简述 进程间通信的几种方式:无名管道.有名管道.消息队列.共享内存.信号.信号量.套接字(socket). 进程间通信是不同进程直接进行的一些接触,这种接触有简单,有复杂.机制不同,复杂 ...

  4. 浅谈消息队列及常见的分布式消息队列中间件

    背景 分布式消息队列中间件是是大型分布式系统不可缺少的中间件,通过消息队列,应用程序可以在不知道彼此位置的情况下独立处理消息,或者在处理消息前不需要等待接收此消息.所以消息队列主要解决应用耦合.异步消 ...

  5. Java架构之消息队列 (一):消息队列的概述

    消息队列系列分享大纲: 一.消息队列的概述 二.消息队列之RabbitMQ的使用 三.消息队列之Kafka的使用 四.消息队列之RabbitMQ的原理详解 五.消息队列之Kafka的原理详解 六.消息 ...

  6. python消息队列中间件_常见的消息队列中间件介绍

    题目 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka.ActiveMQ.RabbitMQ.RocketMQ 都有什么区别,以及适合哪些场景? 什么是消息队列 在正式介绍和对比Kafka. ...

  7. 消息队列的使用场景_消息队列MQ的特点、选型及应用场景

    一.什么是消息队列 消息队列(Message Queue,简称MQ),指保存消息的一个容器,本质是个队列. 消息(Message)是指在应用之间传送的数据,消息可以非常简单,比如只包含文本字符串,也可 ...

  8. springboot使用redis实现消息队列功能,redis使用list和stream实现消息队列功能,redis实现消息队列的风险点分析

    文章目录 写在前面 基于list的消息队列解决方案 使用list基本实现消息队列 阻塞式消费,避免性能损失 替换while(true) 实现消息幂等 保证消息可靠性 基于stream的消息队列解决方案 ...

  9. php微信小程序物流进度推送,微信小程序 消息推送php服务器验证实例详解

    微信小程序 消息推送php服务器验证实例详解 设置页面("设置">>"开发设置"): 1.设置服务器域名 注意http和https协议的不同. 2. ...

最新文章

  1. 赶考在线执业药师,7-8月提分策略,化繁为简
  2. SQL实现分组查询取前几条记录
  3. 【USACO 3.1】Score Inflation(完全背包)
  4. 浏览器获取设备信息_一条命令获取 IE 浏览器保存网站的账号和密码信息
  5. 网络(13)-SYN flood及其应对方法
  6. python用什么来写模块-使用C语言编写Python模块-引子【转】
  7. python 下载及安装-CentOS下python的下载及安装
  8. Dubbo框架协议总结
  9. 计算机终端保密检查 玩游戏,计算机终端保密检查系统
  10. java网络编程Socket客户端给服务器端通信
  11. 可以真正带你理清同步阻塞与同步非阻塞与异步阻塞与异步非阻塞的文章
  12. windows DNS缓存查看与清理
  13. 天黑请闭眼--杀吧专用(C#版 附源码)
  14. 软件测试面试题:常见的性能测试方法有哪些?以及每类测试方法的目的是什么?
  15. 中测康苑——企业文化
  16. FPGA基础----TLP包格式以及组包方法(1)
  17. 新时达服务器说明书_新时达调试指导说明
  18. GitHub 前 CTO:全面微服务是最大的架构错误!网友:这不是刚改完吗...
  19. 10.COM进程外组件和列集、散集
  20. 计算机语言space什么意思,space是什么意思

热门文章

  1. Samsung ADV:Samsung Tire(AC)
  2. -- 7、查询学过“张三“老师授课的同学的信息
  3. Matlab文件读写
  4. 汽车行驶记录仪-汽车安全也开始信息化了
  5. C++:多态与虚函数,纯虚函数
  6. 中国科学院上海光机所战前教育(COI课题组编)
  7. java新浪云服务器有什么jar包_新浪云部署java web程序 注意事项
  8. 《墨攻》还真不是盖的!!
  9. 小说阅读器 免费源码 高颜值 功能齐全
  10. 实证研究的步骤_环环相扣!牢记这些步骤,论文变轻松