SSMフレームワークの下で、websocketはリアルタイムのデータベース変更情報を取得し、それをフォアグラウンドに表示します(アイデア)

インターネットでたくさんのWebSocketブログを読んでみましたが、基本的には上記の操作で失敗しました。情報が不完全だったり、プロジェクト環境が異なっていたりするのが原因です。この問題を解決するために一生懸命探索してみて、ようやく自分のやりたいことに気づきました。望ましい効果。最初にプロジェクト環境についてお話します。プロジェクトではSSMフレームワークを使用し、次にアノテーションを使用して Bean 注入します。開発ツールはアイデアであり、tomcatのバージョンは7.0.84で、Jdkのバージョンは1.8.0_152です。tomcatは8以上である必要があるとインターネット上で言われていますが、使用したtomcat7.0.84でも目的の機能を実現できますが、tomcatの最小バージョンについては調べていません。次に、プログラムについて説明しましょう。


最初のステップ:HTMLページのプログラム。直接貼り付けて、対応するフィールドを変更できます。注意ブラウザのバージョンが低すぎるは、WebSocketをサポートされていないのを

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>测试websocket</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <style type="text/css">
        * {
            margin: 0px;
            padding: 0px;
        }
    </style>
    <script type="text/javascript">
        var websocket = null;
        //判断当前浏览器是否支持WebSocket
        if ('WebSocket' in window) {
            //建立连接,这里的/websocket ,是Servlet中注解中的那个值,一定对应哈
            websocket = new WebSocket("ws://localhost:8086/项目名称/websocket");//这里的项目名称,有的人进行了设置,有的人没有进行设置,还是根据自己的项目情况来
          
        }
        else {
            alert('当前浏览器不支持websocket');
        }
        //连接发生错误的回调方法
        websocket.onerror = function () {
            document.write("WebSocket连接发生错误<br>")
        };
        //连接成功建立的回调方法
        websocket.onopen = function () {
            document.write("WebSocket连接成功<br>");
        }
        //接收到消息的回调方法
        websocket.onmessage = function (event) {
            //我在编写逻辑时,如果后端数据库发生变化,就给前端传送的数据设置为1,
            if(event.data=="1"){
                //这里就可以在前端进行相应的功能展示,我这里就只用打印一句话进行表示了
                document.write("数据更新啦<br>");
                
            }
        }
        //连接关闭的回调方法
        websocket.onclose = function () {
            document.write("WebSocket连接关闭<br>");
        }
        //监听窗口关闭事件,当窗口关闭时,主动去关闭WebSocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function () {
            closeWebSocket();
        }
        //关闭WebSocket连接
        function closeWebSocket() {
            websocket.close();
        }
    </script>
</head>
<body>
</body>
</html>

ステップ2:pom.xmlを設定する

<!--		下面的是websocket的依赖-开始处 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-websocket</artifactId>
		</dependency>
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>7.0</version>
			 <scope>provided</scope>
		</dependency>
<!--		上面的是websocket的依赖-结尾处-->

ステップ3:Daoレイヤー

/**
     * 下面的方法是测试websocket下数据库中商品总数的变化
     * @return
     */
    Integer WebsocketSumFood();

ステップ4:マッパー

<!--    websocket查询商品总数-->
    <select id="WebsocketSumFood" resultType="Integer" >
        select count(*) from t_product
    </select>

ステップ5:サービス層

/**
     * 测试食品修改下websocket的使用
     * @return
     */
    int WebsocketSumFood();

ステップ6:サービス実装レイヤー

/**
     * websocket下测试食品总数修改的变化
     * @return
     */
    @Override
    public int WebsocketSumFood() {
        return foodDao.WebsocketSumFood();
    }

ステップ7:WebSocketConfigクラスを作成する

import org.apache.catalina.session.StandardSessionFacade;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;

/**
 * @Author: Wxz
 * @Date: 2020/9/1 11:49
 */
@Configuration
public class WebSocketConfig extends Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        /*如果没有监听器,那么这里获取到的HttpSession是null*/
        StandardSessionFacade ssf = (StandardSessionFacade) request.getHttpSession();
        if (ssf != null) {
            HttpSession httpSession = (HttpSession) request.getHttpSession();
            //关键操作
            sec.getUserProperties().put("sessionId", httpSession.getId());
        }
    }


    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

8番目のステップ:モニタリングクラスの記述


import org.springframework.stereotype.Component;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @Author: Wxz
 * @Date: 2020/9/1 14:59
 */
@Component
public class RequestListener implements ServletRequestListener {
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        //将所有request请求都携带上httpSession
        HttpSession httpSession = ((HttpServletRequest) sre.getServletRequest()).getSession();
    }

    public RequestListener() {
    }

    @Override
    public void requestDestroyed(ServletRequestEvent arg0) {
    }
}

ステップ9:スレッドクラスMyThreadを記述する

package com.example.orderserver.foodwebsocket;

import com.example.orderserver.service.foodManage.FoodService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @Author: Wxz
 * @Date: 2020/9/1 10:29
 */
@Component
public class MyThread implements Runnable{
    //普通类获取service对象,否则会报空指针
    @Autowired
    private FoodService foodService;
    public static MyThread testUtils;
    //下面的注解一定要有哈
    @PostConstruct
    public void init() {
        testUtils = this;
    }
    //原始数量
    private int sum;
    //数据库变化后的数量
    private int new_sum;
    //设置循环状态
    private boolean stopMe = true;
    public void stopMe() {
        stopMe = false;
    }


    @Override
    public void run() {
        sum=testUtils.foodService.WebsocketSumFood();
        WebSocketServlet wbs=new WebSocketServlet();
        while(stopMe){
            new_sum=testUtils.foodService.WebsocketSumFood();
            if(sum!=new_sum){
                sum=new_sum;
                wbs.onMessage(sum);
            }
            try {
                //每10秒检查一下数据库
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

10番目のステップ:WebSocketServletを作成する

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author: Wxz
 * @Date: 2020/9/1 10:30
 */

@ServerEndpoint("/websocket")
@Component
public class WebSocketServlet {
    MyThread thread1=new MyThread();
    //开启线程
    Thread thread=new Thread(thread1);
    //用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServlet> webSocketSet = new CopyOnWriteArraySet<WebSocketServlet>();
    private  javax.websocket.Session session=null;

    /**
     * @ClassName: onOpen
     * @Description: 开启连接的操作
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) throws IOException{
        //获取WebsocketConfig.java中配置的“sessionId”信息值
        String httpSessionId = (String) config.getUserProperties().get("sessionId");
        this.session=session;
        webSocketSet.add(this);
        //开启一个线程对数据库中的数据进行轮询
        thread.start();

    }

    /**
     * @ClassName: onClose
     * @Description: 连接关闭的操作
     */
    @OnClose
    public void onClose(){
        thread1.stopMe();
        webSocketSet.remove(this);
    }

    /**
     * 告知前端数据库发生变化,调用sendMessage()方法
     * @param count
     */
    @OnMessage
    public void onMessage(int count) {
        System.out.println("发生变化"+count);
        try {
            sendMessage();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 出错操作
     * @param error
     */
    @OnError
    public void onError(Throwable error){
        error.printStackTrace();
    }

    /**
     * 此方法是被调用的方法,所以没注解,这里才是真正处理逻辑的地方,可以给前台传输你想要传输的内容,我只是用1进行代替了。
     * @throws IOException
     * 发送自定义信号,“1”表示告诉前台,数据库发生改变了,需要刷新
     */
    public void sendMessage() throws IOException{
        //群发消息
        for(WebSocketServlet item: webSocketSet){
            item.session.getBasicRemote().sendText("1");
        }
    }
}

ステップ11:プロジェクトを開始し、データベースを変更します。

ステップ12:ブラウザーを確認します。

これまでのところ、欲しい効果は出ていますし、皆さんとコミュニケーションできてうれしいです!

 

 

おすすめ

転載: blog.csdn.net/xgysimida/article/details/108345694