springBoot project+websocket+vue realizes two-way communication

Table of Contents

1. Understand the WebSocket protocol

WebSocket features

Real time communication:

Two-way communication:

Long connection:

Cross-domain communication:

2. Back-end code implementation

Introduce maven dependencies

WebSocketConfig

WebSocketConfig function:

WebSocketConfig.java code

MyWebSocket

@annotation explanation

MyWebSocket function:

MyWebSocket.java code

3. Test whether the server is connected normally

1. Open the websocket test gadget

2. Enter the access address in the test gadget and click Connect, as shown below

?edit

4. Front-end code implementation

5. Effect display? Editing


1. Understand the WebSocket protocol

WebSocket is a full-duplex, long-connection communication protocol designed to provide real-time communication capabilities. Before using WebSocket, it is recommended to learn the basic knowledge of the WebSocket protocol.

WebSocket Features

Real-time communication:

WebSocket provides a mechanism for real-time communication between clients and servers. Unlike the traditional HTTP request-response model, WebSocket allows the server to actively push messages to the client without requiring the client to initiate a request. This enables real-time applications such as live chat, real-time data updates, and more.

Two-way communication:

WebSocket enables two-way communication, and the client and server can send and receive messages at the same time. Whether on the client or server side, messages can be sent for real-time updates, notifications, and responses. This makes it easier for developers to build interactive and responsive applications.

Long connection:

The traditional HTTP request-response model uses short connections, that is, each request requires a new connection to be established and closed. In contrast, WebSocket uses long-lived connections, which means that a single connection can remain valid and transmit multiple messages. This reduces the overhead of connection establishment and closing and reduces network traffic and latency, thereby improving application efficiency and performance.

Cross-domain communication:

The WebSocket protocol supports cross-domain communication, that is, communication between different domain names or different ports. This allows developers to build distributed systems, place different modules or services on different hosts, and perform real-time communication and data exchange through WebSocket.

Second, back-end code implementation

Introduce maven dependencies

<!-- socket startup dependencies -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    <version>2.7.0</version>
</dependency>

WebSocketConfig

WebSocketConfig function:

Enable WebSocket support and inject this class into the Spring container. Specifically, it registers a ServerEndpointExporter Bean in the Spring configuration file, which is used to scan all WebSocket services with @ServerEndpoint annotations and register them in the WebSocket container. This allows you to use WebSocket in Spring Boot applications to achieve real-time communication and data transmission.

WebSocketConfig.java code

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

/**
 * Enable WebSocket support and inject this class into the spring container
 * @description: WebSocket configuration
 * @author: Gobi Lao Sun
 * @create: 2023/11/08 10:28
 */
@Configuration
public class WebSocketConfig {

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

}

MyWebSocket

@annotation explanation

The @ServerEndpoint("/websocket") annotation indicates that the class is identified as a WebSocket server endpoint through which the client can make a WebSocket connection. /websocket is the URL path for the client connection.

The @EnableScheduling annotation indicates enabling Spring’s scheduled task scheduling function. The @Scheduled annotation used in this class can take effect.

The @Component annotation indicates that the class is identified as a Spring component, which is automatically managed and injected by Spring.

Together, the class marked with these annotations is an implementation class of the WebSocket server. It also supports scheduled task scheduling and is automatically managed and injected by Spring. The client can establish a connection with the WebSocket server by accessing the /websocket path.

MyWebSocket function:

The @ServerEndpoint annotation is used to declare the address of the websocket server. When receiving a message from the client, it will enter the onMessage method to process the message. At the same time, when the client connects or closes the connection, it will enter the corresponding onOpen and onClose methods. In addition, a static variable onlineCount is used to represent the number of currently connected WebSockets, and a webSocketSet of type CopyOnWriteArraySet is used to save all connected WebSocket instances. When joining a connection, call addOnlineCount() to increase the online number record. When exiting the connection, call subOnlineCount() to decrease the online number record. Finally, the @Autowired annotation is used to inject the bean of IProTriaxialDataService to handle business logic.

MyWebSocket.java code

import com.alibaba.fastjson2.JSONObject;
import com.unis.common.utils.StringUtils;
import com.unis.web.domain.ProTriaxialData;
import com.unis.web.service.IProTriaxialDataService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * socket communication class
 * @description: WebSocket configuration
 * @author: Gobi Lao Sun
 * @create: 2023/11/08 10:30
 */
@ServerEndpoint("/websocket")
@EnableScheduling
@Component
public class MyWebSocket {

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


    private static int onlineCount = 0;

    private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<>();

    private Session session;

    private Boolean isReceive = true;

    //Business injection
    private static IProTriaxialDataService proTriaxialDataService;

    @Autowired
    public void proTriaxialDataService(IProTriaxialDataService proTriaxialDataService){
        //WebScoketController is the class name of this class and needs to be replaced with your own class name
        MyWebSocket.proTriaxialDataService = proTriaxialDataService;
    }


    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);
        addOnlineCount();
        log.info("A new link has been added! Current number of people online: {}",getOnlineCount());
    }

    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        subOnlineCount();
        log.info("A link is closed! Current number of people online: {}",getOnlineCount());
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        log.info("socket received message{}",message);
        //Determine whether the front end has consumed the previous message
        if (StringUtils.isNotEmpty(message) & amp; & amp; message.equals("Consumed")){
            isReceive = true;
        } else {
            // The line is disconnected
            isReceive = false;
        }
    }

    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    @Scheduled(cron = "*/5 * * * * *")
    public void sendMessageScheduledTask()throws Exception{
        log.info("socket execution three data is pushed to the front end");
        try{
            if (isReceive){
                //Send every five seconds
                List<ProTriaxialData> proTriaxialData = proTriaxialDataService.selectProTriaxialDataByCreateTimeDesc();
                if (proTriaxialData!=null & amp; & amp; proTriaxialData.size()>0){
                    String message = JSONObject.toJSONString(proTriaxialData.get(0));
                    for (MyWebSocket item : webSocketSet) {
                        item.sendMessage(message);

                    }
                }
            }
            log.info("socket data sent successfully!");
        }catch (Exception e){
            log.info("socket data sending failed!");
            e.printStackTrace();
        }

    }


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

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

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

}

Third test whether the server is connected normally

1. Open the websocket test gadget

2. Enter the access address in the test gadget and click Connect , as shown below

ws://IP:PORT/websocket

Four. Front-end code implementation

created() {
      var ws = new WebSocket("ws://IP:PORT/websocket");

      //Callback function after successful connection
      ws.onopen = function (params) {
        console.log('Client connection successful')
        //Send message to server
        ws.send('Authentication successful!')
      };
      //Callback function when receiving information from the server
      ws.onmessage = function (e) {
        console.log('Received server response', e.data)
        this.proTriaxialData = e.data;
        console.log( this.proTriaxialData);
      };
      //Callback function after the connection is closed
      ws.onclose = function(evt) {
        console.log("Close client connection");
      };
      //Callback function after connection failure
      ws.onerror = function (evt) {
        console.log("Connection failed");
      };
      //Listen to the window closing event. When the window is closed, actively close the websocket connection to prevent the window from closing before the connection is disconnected, in which case the server will throw an exception.
      window.onbeforeunload = function() {
        ws.close();
      }

      console.log(ws)
    }

5. Effect Display

It ends here~