Spring boot 整合rabbit mq 实现订单 并通过websocket 异步通知前端
首先引入rabbit和websocket的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- 消息队列 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
rabbit 的配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
rabbit 消息默认转json的配置
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
spring bean 注册 交换机 队列 以及队列和交换机绑定等
这里使用点对点的模式连接
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class rabbitconfigeq {
/**
* orderDirctQueue
* 订单队列
* @return
*/
@Bean
public Queue orderDirctQueue(){
//durable:是否持久化,默认是false
return new Queue("OrderDirectQueue",true);
}
/**
* orderDirectExchange
* 订单直连交换机
* @return
*/
@Bean
public DirectExchange orderDirectExchange(){
return new DirectExchange("OrderDirectExchange",true,false);
}
/**
*
* @return
*/
@Bean
public Binding orderbindingDirect(){
return BindingBuilder.bind(orderDirctQueue()).to(orderDirectExchange()).with("OrderProducer");
}
}
控制器
@RequestMapping(value = "/c")
public R createorder(@RequestBody FaOrdersEntity faOrdersEntity){
boolean save = faOrdersService.save(faOrdersEntity);
if (true){
//向交换机发送一条消息
rabbitTemplate.convertAndSend("OrderDirectExchange","OrderProducer",faOrdersEntity);
return R.ok("排队中").put("data",faOrdersEntity);
}
return R.ok().put("","");
}
消费队列方法
//绑定队列 一个方法类有多个改方法可将此注解写到类上 方法可写@RabbitHandler 根据获取的参数值来的
@RabbitListener(queues = {"OrderDirectQueue"})
public void reciveMessage(FaOrdersEntity faOrdersEntity){
//调用websocket的静态发送方法异步通知前端抢购成功
Websocket.sendorderMessage(faOrdersEntity);
}
websocket
import io.renren.modules.generator.entity.FaOrdersEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@Component
@ServerEndpoint(value = "/socket/{uid}")
public class Websocket {
private static final Logger log = LoggerFactory.getLogger(Websocket.class);
//在线人数
private static int onlineCount = 0;
//
private static CopyOnWriteArraySet<Websocket> websocketSet = new CopyOnWriteArraySet<>();
//
private Session session;
private static Map<String,Websocket> sessionmap = new ConcurrentHashMap<>();
/**
* 成功建立连接
* @param session
* @param id
*/
@OnOpen
public void onOpen(Session session, @PathParam("uid") String id) throws IOException {
this.session = session;
websocketSet.add(this);
sessionmap.put(id+"socket",this);
addOnlineCount();
log.info("有一人加入了当前正在抢购的人数{{}}",onlineCount);
this.session.getBasicRemote().sendText("连接成功");
}
//订单发送给指定人
public static void sendorderMessage(FaOrdersEntity faOrdersEntity) {
System.out.println(sessionmap);
log.info("返回给用户的订单消息{{}}",faOrdersEntity);
try {
sessionmap.get(faOrdersEntity.getBuyUid()+"socket").sendMessage(faOrdersEntity);
}catch (Exception e){
e.printStackTrace();
}
}
@OnClose
public void onClose(){
websocketSet.remove(this);
subOnlineCount();
log.info("有一人推出了当前正在抢购的人数为{{}}"+getOnlineCount());
}
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发生错误");
error.printStackTrace();
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
//人数加一
public static synchronized void addOnlineCount() {
Websocket.onlineCount++;
}
//人数减一
public static synchronized void subOnlineCount() {
Websocket.onlineCount--;
}
}
前端不想写的话可以用这个网站测试websocket的连接
websocket测试连接地址