SpringCloud (si la version du microservice est prise à titre d'exemple) intègre WebSocket pour implémenter le message push entre le front et le back-end

Scènes

SpringBoot + Vue intègre WebSocket pour implémenter le push de messages front-end et back-end:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114392573

Si vous suivez la version du microservice pour vous apprendre à créer un environnement localement et à exécuter les projets frontaux et principaux:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/109363303

Dans ce qui précède, le processus d'utilisation de WebSocket sur la base de SpringBoot + Vue et le processus de création d'un projet avec SpringCloud (version du microservice Ruoyi) sont introduits, si vous utilisez WebSocket dans SpringCloud.

Noter:

Blog:
https://blog.csdn.net/badao_liumang_qizhi
Suivez le
compte public
Programmeurs dominateurs Obtenez des livres électroniques, des tutoriels et des téléchargements gratuits liés à la programmation.

atteindre

Tout d'abord, ajoutez la dépendance WebSocket sous le service qui doit intégrer WebSocket

        <!-- WebSocket-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

Ici est placé sous le service des tâches chronométrées

 

Créez ensuite un nouveau répertoire de configuration sous le chemin du package de projet et créez une nouvelle classe de configuration WebSocketConfig dans ce répertoire

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

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

Créez ensuite un nouveau répertoire websocket sous le package et créez une nouvelle classe d'entité client WebSocketClient dans ce répertoire pour stocker l'URI de la session connectée

import javax.websocket.Session;

public class WebSocketClient {
    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    //连接的uri
    private String uri;

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }
}

Créez ensuite une nouvelle classe de service WebSocketService dans ce répertoire

import org.apache.commons.lang.StringUtils;
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.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/websocket/{userName}")
@Component
public class WebSocketService {

    private static final Logger log = LoggerFactory.getLogger(WebSocketService.class);

    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, WebSocketClient> webSocketMap = new ConcurrentHashMap<>();


    /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
    private Session session;
    /**接收userName*/
    private String userName="";
    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session, @PathParam("userName") String userName) {
        if(!webSocketMap.containsKey(userName))
        {
            addOnlineCount(); // 在线数 +1
        }
        this.session = session;
        this.userName= userName;
        WebSocketClient client = new WebSocketClient();
        client.setSession(session);
        client.setUri(session.getRequestURI().toString());
        webSocketMap.put(userName, client);

        log.info("----------------------------------------------------------------------------");
        log.info("用户连接:"+userName+",当前在线人数为:" + getOnlineCount());
        try {
            sendMessage("来自后台的反馈:连接成功");
        } catch (IOException e) {
            log.error("用户:"+userName+",网络异常!!!!!!");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userName)){
            webSocketMap.remove(userName);
            if(webSocketMap.size()>0)
            {
                //从set中删除
                subOnlineCount();
            }
        }
        log.info("----------------------------------------------------------------------------");
        log.info(userName+"用户退出,当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到用户消息:"+userName+",报文:"+message);
        //可以群发消息
        //消息保存到数据库、redis
        if(StringUtils.isNotBlank(message)){

        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:"+this.userName+",原因:"+error.getMessage());
        error.printStackTrace();
    }

    /**
     * 连接服务器成功后主动推送
     */
    public void sendMessage(String message) throws IOException {
        synchronized (session){
            this.session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 向指定客户端发送消息
     * @param userName
     * @param message
     */
    public static void sendMessage(String userName,String message){
        try {
            WebSocketClient webSocketClient = webSocketMap.get(userName);
            if(webSocketClient!=null){
                webSocketClient.getSession().getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }


    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketService.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketService.onlineCount--;
    }

    public static void setOnlineCount(int onlineCount) {
        WebSocketService.onlineCount = onlineCount;
    }


    public static ConcurrentHashMap<String, WebSocketClient> getWebSocketMap() {
        return webSocketMap;
    }

    public static void setWebSocketMap(ConcurrentHashMap<String, WebSocketClient> webSocketMap) {
        WebSocketService.webSocketMap = webSocketMap;
    }

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

Notez que le WebSocketClient introduit ici est nouvellement créé ci-dessus

Trouvez le fichier de configuration de la passerelle, voici pour utiliser Nacos comme centre de configuration. Lâchez le chemin Websocket pour l'authentification des autorisations

Voici l'ajout ci-dessous ignore-whites à la fin de ruoyi-gateway-dev.xml

    - /schedule/websocket/**

 

Voici pour mettre le websocket sous le service de la tâche chronométrée, l'itinéraire de ce service est également dans le fichier de configuration de la passerelle

 

Ensuite pour simplification et démonstration, nous appelons ici directement le service du port sous le service de tâche chronométrée sans passer par la passerelle lors de l'utilisation de la connexion websocket.

Pour tester le push, vous devez utiliser l'outil de test client websocket, qui peut être résolu par vous-même, ou utiliser l'outil suivant

https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/15630118

Ici, 9203 est utilisé directement comme adresse du service de tâche chronométrée spécifique, et non comme port de la passerelle, puis l'adresse connectée est

ws: // localhost: 9203 / websocket / badao

Badao est le paramètre UserName transmis. Après avoir entré l'adresse, cliquez sur Se connecter, vous pouvez voir que la connexion a réussi

 

Et cliquez sur envoyer des données

 

Il sera également reçu en arrière-plan.

Créez ensuite une interface de test en arrière-plan

@RestController
@RequestMapping("/schedule/websocket")
public class WebSocketTestController {

    @GetMapping("/push")
    public void push(SysJobLog sysJobLog)
    {
        WebSocketService.sendMessage("badao","badao");
    }
}

Après avoir appelé cette interface, le client recevra également les données envoyées

 

Voici comment utiliser l'outil client pour tester le websocket, puis le websocket d'intégration de Vue front-end est le même que le processus d'intégration du blog ci-dessus.

Acho que você gosta

Origin blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114480731
Recomendado
Clasificación