current position:Home>Websocket + springboot message active push

Websocket + springboot message active push

2022-05-15 05:14:15houxian1103

General Statement

Usually in web When the front end informs the customer , One way is through Http/Https Polling to achieve , Another way is through WebSocket This light weight Tcp Connect to achieve , What we're introducing here is message push .

Http+WebSocket Principle analysis
 Insert picture description here

The realization of the plan

The front-end implementation webSocket The following two methods are for reference only :

  • The first is to use sockjs.
  • The second is to use h5 Standards for . Use Html5 The standard is more convenient and simple , So what we record is cooperation h5 How to use .
    The front-end code
    index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    Welcome<br/>
    <input id="text" type="text" /><button onclick="send()">Send</button>    <button onclick="closeWebSocket()">Close</button>
    <div id="message">
    </div>
</body>

<script type="text/javascript"> var websocket = null; // Determine whether the current browser supports it WebSocket if('WebSocket' in window){
       websocket = new WebSocket("ws://localhost:8080/socket/hou/7eb50aaf-fbdc-9281-2889-fe95a2faa98c"); }else{
       alert('Not support websocket') } // Callback method for connection error  websocket.onerror = function(){
       setMessageInnerHTML("error"); }; // Callback method for successful connection establishment  websocket.onopen = function(event){
       setMessageInnerHTML("open"); } // The callback method that receives the message  websocket.onmessage = function(event){
       setMessageInnerHTML(event.data); } // Call-back method for connection closure  websocket.onclose = function(){
       setMessageInnerHTML("close"); } // Listen for window closing events , When the window closes , Active close websocket Connect , Prevent Windows from closing before the connection has been disconnected ,server The end throws an exception . window.onbeforeunload = function(){
       websocket.close(); } // Displays the message on the web page  function setMessageInnerHTML(innerHTML){
       document.getElementById('message').innerHTML += innerHTML + '<br/>'; } // Close the connection  function closeWebSocket(){
       websocket.close(); } // Send a message  function send(){
       var message = document.getElementById('text').value; websocket.send(message); } </script>
</html>

The backend implementation

  • Package Introduction
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
  • Configuration class (WebSocketConfig)
    Use @ServerEndpoint found websocket endpoint [ Configure the endpoint class and its implementation :WebSocketServer] First, inject ServerEndpointExporter, This bean Will automatically register to use @ServerEndpoint Annotated Websocket endpoint. it is to be noted that , If you use independent servlet Containers , Instead of using it directly springboot Built in container , Don't inject ServerEndpointExporter, Because it will be provided and managed by the container itself .
  • Implementation of configuration class
package com.dianxin.msg.websocketconfig;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.websocket.server.ServerEndpointConfig;

public class MyEndpointConfigure extends ServerEndpointConfig.Configurator implements ApplicationContextAware {
    
    private static volatile BeanFactory context;
 
	@Override
	public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
    
		return context.getBean(clazz);
	}
 
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
		MyEndpointConfigure.context = applicationContext;
	}
}
package com.dianxin.msg.websocketconfig;

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

/** * websocket Configuration class  */
@Configuration
public class WebSocketConfig {
    
    /** *  The first configuration is due to the use of springboot Built in container , When developing by yourself, you need to configure , If you have a separate container, you need to comment it out , *  That means , If the project is marked as WAR package , Deploy to server , Use Tomcat Startup time , Need to be commented out ServerEndpointExporter To configure ; * @return */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
    
        return new ServerEndpointExporter();
    }

    /** * MyEndpointConfigure Configuration is because of my needs , Need to be in websocket Class injection service Layer or dao Layer interface , * MyEndpointConfigure Configuration is to solve websocket Problems that cannot be injected , If you don't need it, you don't need to configure  * @return */
    @Bean
    public MyEndpointConfigure newConfigure() {
    
        return new com.dianxin.msg.websocketconfig.MyEndpointConfigure();
    }
}

Service Layer implementation

package com.dianxin.msg.service;
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.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/** * @author houxian1103 * @Description: WebSocket Server code , Contains received messages , Push message and other interfaces  */
@Component
@ServerEndpoint(value = "/socket/{name}/{token}")
public class WebSocketServer {
    

    // Static variables , To record the current number of online connections . It should be designed to be thread safe .
    private static AtomicInteger online = new AtomicInteger();

    //concurrent Thread safety of package Set, Used to store the corresponding WebSocketServer object .
    private static Map<String,Session> sessionPools = new HashMap<>();

    /** *  Send message method  * @param session  The client and socket Established session  * @param message  news  * @throws IOException */
    public void sendMessage(Session session, String message) throws IOException{
    
        if(session != null){
    
            session.getBasicRemote().sendText(message);
        }
    }


    /** *  Connection establishment successful call  * @param session  The client and socket Established session  * @param userName  Client's userName */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "name") String userName, @PathParam(value = "token") String token){
    
        sessionPools.put(userName, session);
        addOnlineCount();
        System.out.println(userName + " Join in webSocket! The current number is " + online);
        try {
    
            sendMessage(session, " welcome " + userName + " Join the connection !");
        } catch (IOException e) {
    
            e.printStackTrace();
        }
    }

    /** *  Called when the connection is closed  * @param userName  The name of the client that closed the connection  */
    @OnClose
    public void onClose(@PathParam(value = "name") String userName){
    
        sessionPools.remove(userName);
        subOnlineCount();
        System.out.println(userName + " To break off webSocket Connect ! The current number is " + online);
    }

    /** *  Triggered when a client message is received ( Mass hair ) * @param message * @throws IOException */
    @OnMessage
    public void onMessage(String message) throws IOException{
    
        for (Session session: sessionPools.values()) {
    
            try {
    
                sendMessage(session, message);
            } catch(Exception e){
    
                e.printStackTrace();
                continue;
            }
        }
    }

    /** *  When something goes wrong  * @param session * @param throwable */
    @OnError
    public void onError(Session session, Throwable throwable){
    
        System.out.println(" An error occurred ");
        throwable.printStackTrace();
    }

    /** *  Send a message to the specified user  * @param userName  user name  * @param message  news  * @throws IOException */
    public void sendInfo(String userName, String message){
    
        Session session = sessionPools.get(userName);
        try {
    
            sendMessage(session, message);
        }catch (Exception e){
    
            e.printStackTrace();
        }
    }

    /** *  Get... By user name session Conversation object  * @param userName * @return */
    public Session getSession(String userName){
    
        Session session = sessionPools.get(userName);
        return session;
    }

    public static void addOnlineCount(){
    
        online.incrementAndGet();
    }

    public static void subOnlineCount() {
    
        online.decrementAndGet();
    }
}

Controller Layer implementation ( For testing )

package com.dianxin.msg.controller;


import com.dianxin.msg.service.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;


/** */
@RequestMapping("/webSocket")
@RestController
public class WebSocketController {
    


    @Autowired
    private WebSocketServer webSocketServer;

    /** *  Push messages to specified users  * @param userName  user name  * @param message  news  * @throws IOException */
    @RequestMapping(value = "/socket", method = RequestMethod.GET)
    public void testSocket1(@RequestParam String userName, @RequestParam String message){
    
        webSocketServer.sendInfo(userName, message);
    }


    /** *  Push messages to all users  * @param message  news  * @throws IOException */
    @RequestMapping(value = "/socket/all", method = RequestMethod.GET)
    public void pushAllSocket(@RequestParam String message){
    
        try {
    
            webSocketServer.onMessage(message);
        } catch (IOException e) {
    
            e.printStackTrace();
        }
    }
}

copyright notice
author[houxian1103],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/135/202205142227351896.html

Random recommended