springboot websocket achieve integration of an object to the front end transmission browser sends a message to trigger operation of the manual

There is such a work to be shown, we used in the project code cache to the front inside the browser IndexedDB, when the system administrator changes the code in the background we need to update the code of how to do front-end cache began to want to use version way to deal with, but then every time you use need to call to get the version API version to determine whether there is a change to native code before whether to update the code, so a lot of pressure on the server. Then consider http slow news round way, and finally understand that this is simply an artifact WebSocket, the future can also be used to extend the live chat function in the project.

What is WebSocket

We know that HTTP protocol is first by the browser sends a request to the server, the server responds to this request, then the data is sent to the browser. If you need to send a message to the server browser is HTML5 WebSocket how do the new agreement, so that you can establish a full-duplex communication between the browser and unlimited server, either party may take the initiative sends a message to the other party.

SpringBoot-Websocket-Demo

Project Introduction

  • springboot 2.1.6.RELEASE

  • spring-boot-starter-websocket

  • This project is mainly to test integrated springboot websocket objects to realize sending a distal browser sends a message to trigger a manual operation.

Github code has been uploaded to the portal https://github.com/devmuyuer/SpringBoot-Websocket-Demo

Code Description

  • 1. Create a new project spingboot

  • 2. Add WebSocket dependent
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  • 3.WebSocketConfig
    open WebSocket support
package com.example.socket;

/**
 * @author muyuer [email protected]
 * @version 1.0
 * @date 2019-07-22 18:16
 */

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

/**
 * 开启WebSocket支持
 * @author zhengkai
 */
@Configuration
public class WebSocketConfig {

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

}
  • 4.WebSocketServer
    a WebSocket protocol using ws, WebSocketServer ws where a similar protocol Controller
package com.example.socket;

import cn.hutool.json.JSONUtil;
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.CopyOnWriteArraySet;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

/**
 * @author muyuer [email protected]
 * @version 1.0
 * @date 2019-07-22 18:17
 */
@ServerEndpoint("/web/socket/{sid}")
@Component
public class WebSocketServer {

    static Log log=LogFactory.get(WebSocketServer.class);
    /**
     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static int onlineCount = 0;
    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     */
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

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

    /**
     * 接收sid
      */
    private String sid="";
    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session,@PathParam("sid") String sid) {
        this.session = session;
        //加入set中
        webSocketSet.add(this);
        //在线数加1
        addOnlineCount();
        log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());
        this.sid=sid;
        try {
            sendMessage("连接成功");
        } catch (IOException e) {
            log.error("websocket IO异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        subOnlineCount();
        log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到来自窗口"+sid+"的信息:"+message);
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }
    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
    /**
     * 实现服务器主动推送
     */
    public void sendMessage(SocketMessage message) throws IOException {
        this.session.getBasicRemote().sendText(JSONUtil.toJsonStr(message));
    }


    /**
     * 群发自定义消息
     * */
    public static void sendInfo(SocketMessage message,@PathParam("sid") String sid) throws IOException {
        log.info("推送消息到窗口"+sid+",推送内容:"+message);
        for (WebSocketServer item : webSocketSet) {
            try {
                if(sid==null) {
                    item.sendMessage(message);
                }else if(item.sid.equals(sid)){
                    item.sendMessage(message);
                }
            } catch (IOException e) {
                continue;
            }
        }
    }

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

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

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}
  • 5.WebSocketController
    test callable WebSocketServer.sendInfo api used in the project (newMessage, cid); push message
package com.example.socket;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.util.Date;

/**
 * @author muyuer [email protected]
 * @version 1.0
 * @date 2019-07-22 18:19
 */
@Controller
@RequestMapping("/web/socket")
public class WebSocketController {

    /**
     * 页面请求
     * @param cid
     * @return
     */
    @GetMapping("/{cid}")
    public ModelAndView socket(@PathVariable String cid) {
        ModelAndView mav=new ModelAndView("/socket");
        mav.addObject("cid", cid);
        return mav;
    }

    /**
     * 推送数据接口
     * @param cid
     * @param message
     * @return
     */
    @ResponseBody
    @RequestMapping("/send/")
    public String pushToWeb(String cid,String message) {
        try {
            SocketMessage newMessage = new SocketMessage(message, new Date());
            WebSocketServer.sendInfo(newMessage,cid);
        } catch (IOException e) {
            e.printStackTrace();
            return cid+"#"+e.getMessage();
        }
        return cid;
    }
}

-6 front end calling code

<!DOCTYPE HTML>
<html>
<head>
    <title>My WebSocket</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;

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        websocket = new WebSocket("ws://localhost:8083/web/socket/20");
    }
    else{
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(event){
        setMessageInnerHTML("open");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

test

  • 1.f9 run the project, the project is port 8083 can modify the configuration file
  • 2. First, open the address in the browser to http: // localhost: 8083 / establish a connection
  • 3. Access the address http: // localhost:? 8083 / web / socket / send cid = 20 & message = hello push messages cid client to establish a connection id is the html "ws: // localhost: 8083 / web / socket / 20 "the id 20

Reference material

Guess you like

Origin www.cnblogs.com/DevMuYuer/p/11236157.html