springboot 整合emqx订阅消息_maven

 

首先是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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.5.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.baidu.websocket</groupId>
	<artifactId>websocket</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>websocket</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-websocket</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
			<version>RELEASE</version>
		</dependency>
     <!-- 进行页面跳转 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>jquery</artifactId>
			<version>3.1.0</version>
		</dependency>
		
				<!-- 热部署 -->
		<!-- devtools可以实现页面热部署(即页面修改后会立即生效,
			这个可以直接在application.properties文件中配置spring.thymeleaf.cache=false来实现) -->
		<!-- 实现类文件热部署(类文件修改后不会立即生效),实现对属性文件的热部署。 -->
		<!-- 即devtools会监听classpath下的文件变动,并且会立即重启应用(发生在保存时机),
			注意:因为其采用的虚拟机机制,该项重启是很快的 -->
		<!-- (1)base classloader (Base类加载器):加载不改变的Class,例如:第三方提供的jar包。 -->
		<!-- (2)restart classloader(Restart类加载器):加载正在开发的Class。 -->
		<!-- 为什么重启很快,因为重启的时候只是加载了在开发的Class,没有重新加载第三方的jar包。 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<!-- optional=true, 依赖不会传递, 该项目依赖devtools; 
				之后依赖boot项目的项目如果想要使用devtools, 需要重新引入 -->
			<optional>true</optional>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

 接下来是配置文件sockjs的配置文件

package com.baidu.websocket.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
 
/**
 * 配置WebSocket
 */
@Configuration
//注解开启使用STOMP协议来传输基于代理(message broker)的消息,这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{

	@Override
	//注册STOMP协议的节点(endpoint),并映射指定的url
      public void registerStompEndpoints(StompEndpointRegistry registry) {
      //注册一个STOMP的endpoint,并指定使用SockJS协议
      registry.addEndpoint("/endpointOyzc").setAllowedOrigins("*").withSockJS();
  }

  @Override
  //配置消息代理(Message Broker)
  public void configureMessageBroker(MessageBrokerRegistry registry) {
  	 //点对点应配置一个/user消息代理,广播式应配置一个/topic消息代理,群发(mass),单独聊天(alone)
      registry.enableSimpleBroker("/topic","/user","/mass","/alone");
      //点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/
      registry.setUserDestinationPrefix("/user");

  }

}

 接下来是Controller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import com.baidu.websocket.model.ChatRoomRequest;
import com.baidu.websocket.model.ChatRoomResponse;

@Controller
public class qunfacontroller {

	
	@Autowired
    private SimpMessagingTemplate template;
	
    //websocket前端向后端发送的地址
    @MessageMapping("/qunfamassage")
    //websocket后端向前端发送的地址
    @SendTo("/topic/getResponse")
    public ChatRoomResponse mass(ChatRoomRequest chatRoomRequest){
        //方法用于群发测试
        System.out.println("姓名是 = " + chatRoomRequest.getName());
        System.out.println("消息是 = " + chatRoomRequest.getChatValue());
        ChatRoomResponse response=new ChatRoomResponse();
        response.setName(chatRoomRequest.getName());
        response.setChatValue(chatRoomRequest.getChatValue());
        return response;
    }
}

 接下来是ChatRoomResponse类

public class ChatRoomResponse {
    private String userId;
    private String name;
    private String chatValue;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getChatValue() {
        return chatValue;
    }

    public void setChatValue(String chatValue) {
        this.chatValue = chatValue;
    }
}

接下来是ChatRoomRequest类

public class ChatRoomRequest {
    private String userId;
    private String name;
    private String chatValue;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getChatValue() {
        return chatValue;
    }

    public void setChatValue(String chatValue) {
        this.chatValue = chatValue;
    }
}

接下来写前端

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>这是一个群发的Message</title>

<style type="text/css">
* {
	margin: 0;
	padding: 0;
}

#top {
	text-align: center;
	margin-top: 10px;
}

#left {
	width: 700px;
	height: 600px;
	float: left;
	background: #dddddd;
	border: 1px solid #a1a1a1;;
	border-radius: 25px;
	margin-left: 30px;
	margin-top: 30px;
}

#right {
	width: 700px;
	height: 600px;
	float: right;
	background: #dddddd;
	border: 1px solid #a1a1a1;;
	border-radius: 25px;
	margin-right: 30px;
	margin-top: 30px;
}

#selectuser {
	text-align: center;
	margin-top: 10px;
}

#sendChatValue {
	width: 90%;
	height: 400px;
	margin-top: 20px;
	margin-right: 20px;
	margin-left: 20px;
	margin-bottom: 20px;
}

#input {
	text-align: center;
}

#message {
	margin-top: 20px;
	margin-left: 20px;
}

input {
	font-size: 15px;
	height: 30px;
	width: 50px;
	border-radius: 4px;
	border: 2px solid #c8cccf;
	color: #6a6f77;
}

select {
	font-size: 15px;
	height: 30px;
	border-radius: 4px;
	border: 2px solid #c8cccf;
	color: #6a6f77;
}
</style>
</head>
<body>
	<!-- 头部 -->
	<div id="top">
		<h1>这是一个群发的Message</h1>
	</div>

	<div id="left">
		<div id="selectuser">
			<select id="selectName">
				<option value="1">请选择发送用户</option>
				<option value="张三">张三</option>
				<option value="李四">李四</option>
				<option value="王五">王五</option>
				<option value="小六">小六</option>
			</select>
		</div>
		<div>
			<textarea name="sendChatValue" id="sendChatValue"
				class="sendChatValue"></textarea>
			<div id="input">
				<input type="button" name="sendMessage" id="sendMessage"
					class="btn btn-default" onclick="sendMassMessage()" value="发送">
			</div>
		</div>
	</div>

	<div id="right">
		<div id="message"></div>
	</div>
	<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.slim.js"></script>
	<script type="text/javascript" src="js/qunfa.js" charset="utf-8"></script>
	<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
	<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
</body>
</html>

 接下来写qunfa.js

var stompClient = null;

//加载完浏览器后  调用connect(),打开双通道
$(function(){
    //打开双通道
    connect()
})

//强制关闭浏览器  调用websocket.close(),进行正常关闭
window.onunload = function() {
    disconnect()
}

//打开双通道
function connect(){
    var socket = new SockJS('/endpointOyzc'); //连接SockJS的endpoint名称为"endpointAric"
    stompClient = Stomp.over(socket);//使用STMOP子协议的WebSocket客户端
    stompClient.connect({},function(frame){//连接WebSocket服务端

        console.log('Connected:' + frame);
        //广播接收信息
        console.log('开始接受消息...');
        stompTopic();
        console.log('消息接受完毕');

    });
}

//关闭双通道
function disconnect(){
    if(stompClient != null) {
        stompClient.disconnect();
    }
    console.log("Disconnected");
}


//广播(一对多)
function stompTopic(){
	   console.log('进入广播接受模式...');
    //通过stompClient.subscribe订阅/topic/getResponse 目标(destination)发送的消息(广播接收信息)
    stompClient.subscribe('/topic/getResponse',function(response){
        var message=JSON.parse(response.body);
        //展示广播的接收的内容接收
        var response = $("#message");
        response.append("<p>发消息的人是:<span style='color:#F00'>"+message.name+"   </span>发送的信息是:<span style='color:#F00'>"+message.chatValue+"</span></p>");
    });
}


//群发消息
function sendMassMessage(){
    var postValue={};
    var chatValue=$("#sendChatValue");
    var userName=$("#selectName").val();
    postValue.name=userName;
    postValue.chatValue=chatValue.val();
    if(userName==1||userName==null){
        alert("请选择你是谁!");
        return;
    }
    if(chatValue==""||userName==null){
        alert("不能发送空消息!");
        return;
    }
    stompClient.send("/qunfamassage",{},JSON.stringify(postValue));
    chatValue.val("");
    console.log('消息已发出');
}