Use RabbitMQ, WebSocker, stopm to simply realize the chat room function

Take a look at the humble chat room first

let's chat
The technologies needed to realize this function are: SpringBoot, RabbitMQ, WebSocker, stopm, sockjs, docker, bootstrap, ajax.

First pull the RabbitMQ image in Docker, run the RabbitMQ image first, enter the RabbitMQ container, and enable the RabbitMQ plug-in to support the stopm protocol.

rabbitmq-plugins enable rabbitmq_web_stomp rabbitmq_stomp rabbitmq_web_stomp_examples

There is a cross-domain problem here. If it is not set, messages cannot cross domains, and messages cannot be sent under different domain names. When playing by yourself, it is recommended to allow all cross-domains. In the project, you can specify domain names to allow cross-domain messages.

Add management.cors.allow_origins.1 = * in rabbitmq.conf. The star indicates that all cross domains are allowed. The configuration file is in the container /etc/rabbitmq/ directory, and the content of the file is not allowed to be modified in the container. It is also necessary to configure the mount here, and create the /usr/rabbitmq/conf directory in the host directory , copy the configuration file and plug-in configuration in the container to this directory:

Plugin configuration name: enabled_plugins
Plugin content:

[rabbitmq_management,rabbitmq_stomp,rabbitmq_web_stomp,rabbitmq_web_stomp_examples].

Configuration file name: rabbitmq.conf
Configuration content:

loopback_users.guest = false
listeners.tcp.default = 5672
management.tcp.port = 15672
management.cors.allow_origins.1 = *

Delete the previously running container and start the image again. Some parameters need to be mounted at startup

docker run -d -p 15672:15672 5672:5672 15674:15674 15670:15670 -v /usr/rabbitmq/conf:/etc/rabbitmq --name myrabbitmq rabbitmq:3.7.26

Access port 15670, and if you see the following content, it means that you have set up and started successfully!
insert image description here

Create a SpringBoot project (sender), dependencies:

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

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

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

Configuration information:

# 应用服务 WEB 访问端口
server.port=8081
server.servlet.context-path=/
# 连接RabbitMQ配置
spring.rabbitmq.host=192.168.2.113
spring.rabbitmq.port=5672
spring.rabbitmq.username=root
spring.rabbitmq.password=123456

Front page:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>带码人聊天室1</title>
    <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.css}"/>
    <script language="javascript" type="text/javascript" th:src="@{/js/jquery-3.5.0.js}"></script>
    <script th:src="@{/js/jquery.js}"></script>
    <script type="text/javascript">
        $(function () {
    
    
            $("#mess").focus(function () {
    
    
                $("#tip").text("")
            });
            $("#but").click(function () {
    
    
                var message = $("#mess").val();

                if (message==""){
    
    
                    alert("please input!")
                    return;
                }
                $.ajax({
    
    
                    url:basepath+"/send",
                    data:{
    
    
                        message:message
                    },
                    success:function (data) {
    
    
                        $("#tip").text(data)
                        $("#mess").val("");
                        let date = new Date();
                        let dateHours = date.getHours();               //获取小时
                        let dateMinutes = date.getMinutes();           //获取分钟
                        let dateSeconds = date.getSeconds();           //获取秒
                        $("#message").append("myself >"+dateHours+"时"+dateMinutes+"分"+dateSeconds+"秒:",message + "<br/>");
                    }
                })
            });
        })
        //按enter键触发送按钮
        $(window).keydown(function (e) {
    
    
            if (e.keyCode == 13) {
    
    
                $("#but").click()
            }
        });

<div th:include="commons/common :: html"></div>

<div class="row">
    <div class="col-md-2 col-md-offset-5">
        <h1>welcome (´▽`ʃ♡ƪ)</h1>
        <input  type="text" id="mess" placeholder="send you want"> <button class="btn btn-success" type="button" id="but">send</button>
        <div><span id="tip" style="color: green"></span></div>
        <hr>
      </div>
    <div id="log"></div>
</div>

</body>
</html>

Send message service class:

//加入spring容器
@Component
public class SendService {
    
    

    @Autowired
    AmqpTemplate amqpTemplate;

    public void send(String exchange,String routingKey,String message){
    
    
        amqpTemplate.convertAndSend(exchange,routingKey,message);
        System.out.println("消息发送成功");
    }

}

Control layer:

@Controller
public class SendController {
    
    

    @Autowired
    ApplicationContext applicationContext;

    @RequestMapping("/send")
    @ResponseBody
    public Object index(String message){
    
    
        SendService sendService = (SendService) applicationContext.getBean("sendService");
        sendService.send("myEx-direct","chen",message);
        return "发送成功";
    }
}

This is mainly to obtain the sent information at the front end, pass the information parameters to the back-end control layer through an asynchronous request, and the control layer calls the service for sending messages, and sends the information to the queue of the message middleware

Create a SpringBoot project again (receiver):
front-end page:
sockjs.js and stomp.js must be introduced here

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试接收</title>
    <script th:src="@{/js/jquery.js}"></script>
    <script th:src="@{/js/sockjs.js}"></script>
    <script th:src="@{/js/stomp.js}"></script>
    <script>
        //初始化 ws 对象,使用的是rabbitmq_stomp的端口【15674】
        var ws = new WebSocket('ws://192.168.2.113:15674/ws');
        // 获得Stomp client对象
        var client = Stomp.over(ws);
        //发送频率
        client.heartbeat.outgoing = 0;
        //接收频率
        client.heartbeat.incoming = 0;
        //关闭控制台调试数据:client.debug = null
        client.debug = function (str) {
    
    
            $("#debug").append(str + "<br/>");
        };
        // 定义连接成功回调函数
        var on_connect = function (x) {
    
    
            //接收myqueue队列的数据
            //注意 /queue/是必须的,后面填写你自己创建的队列名称
            client.subscribe("/queue/myqueue", function (data) {
    
    
                var msg = data.body;
                $("#log").text("收到数据");
                console.log(data);
                $("#message").append(msg + "<br/>");
                //如果后面带了参数 ack  就是指定要手动确认消息,没带就是自动确认
                data.ack();
            }, {
    
    ack: 'client'});
        };
        // 定义错误时回调函数
        var on_error = function () {
    
    
            $("#log").val("error")
        };
        // 连接RabbitMQ
        client.connect('root', '123456', on_connect, on_error, '/');
    </script>
</head>
<body>
<h1 th:text="ok"></h1>
<h1>debug</h1>
<div id="debug"></div>
<hr>
<h1>data</h1>
<div id="message"></div>
<hr>
<h1>接收消息情况</h1>
<div id="log"></div>
</body>
</html>

Log in to the RabbitMQ client, bind the switch to the queue through the (RoutingKey) routing key, start two projects, the sender sends information, and the receiver can receive information in real time.

Summary:
This only realizes the single-side sending of messages. To realize the initial chat room function (that is, copy the codes of the two parties to each other), it is necessary to create another queue, let the sender monitor the messages of the receiver queue, and receive The party also monitors the information of the sender queue, thus realizing the function of a simple chat room.

Guess you like

Origin blog.csdn.net/m0_46803792/article/details/107609747