SpringBoot整合websocket


1、新增pom依賴

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

 

2配置bean

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

 

3websocket處理類

package com.oremouse.websocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

@Component
@ServerEndpoint("/websocket/{username}")
public class WebSocket {

    public static Logger logger = LoggerFactory.getLogger(WebSocket.class);
    /**
     * 在線人數
     */
    public static int onlineNumber = 0;

    /**
     * 以用戶的姓名為key,WebSocket為對象保存起來
     */
    private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
    /**
     * 會話
     */
    private Session session;
    /**
     * 用戶名稱
     */
    private String username;

    /**
     * 建立連接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {
        logger.info("現在來連接的客戶id:" + session.getId() + "用戶名:" + username);
        onlineNumber++;
        this.username = username;
        this.session = session;
        logger.info("有新連接加入! 當前在線人數" + onlineNumber);
        try {
            // messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息
            // 先給所有人發送通知,說我上線了
            Map<String, Object> map1 = new HashMap<String, Object>();
            map1.put("messageType", 1);
            map1.put("username", username);
            sendMessageAll(JSON.toJSONString(map1), username);

            // 把自己的信息加入到map當中去
            clients.put(username, this);
            // 給自己發一條消息:告訴自己現在都有誰在線
            Map<String, Object> map2 = new HashMap<String, Object>();
            map2.put("messageType", 3);
            // 移除掉自己
            Set<String> set = clients.keySet();
            map2.put("onlineUsers", set);
            sendMessageTo(JSON.toJSONString(map2), username);
        } catch (IOException e) {
            logger.info(username + "上線的時候通知所有人發生了錯誤");
        }

    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("服務端發生了錯誤" + error.getMessage());
        // error.printStackTrace();
    }

    /**
     * 連接關閉
     */
    @OnClose
    public void onClose() {
        onlineNumber--;
        // webSockets.remove(this);
        clients.remove(username);
        try {
            // messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息
            Map<String, Object> map1 = new HashMap<String, Object>();
            map1.put("messageType", 2);
            map1.put("onlineUsers", clients.keySet());
            map1.put("username", username);
            sendMessageAll(JSON.toJSONString(map1), username);
        } catch (IOException e) {
            logger.info(username + "下線的時候通知所有人發生了錯誤");
        }
        logger.info("有連接關閉! 當前在線人數" + onlineNumber);
    }

    /**
     * 收到客戶端的消息
     *
     * @param message 消息
     * @param session 會話
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            logger.info("來自客戶端消息:" + message + "客戶端的id是:" + session.getId());
            JSONObject jsonObject = JSON.parseObject(message);
            String textMessage = jsonObject.getString("message");
            String fromusername = jsonObject.getString("username");
            String tousername = jsonObject.getString("to");
            // 如果不是發給所有,那么就發給某一個人
            // messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息
            Map<String, Object> map1 = new HashMap<String, Object>();
            map1.put("messageType", 4);
            map1.put("textMessage", textMessage);
            map1.put("fromusername", fromusername);
            if (tousername.equals("All")) {
                map1.put("tousername", "所有人");
                sendMessageAll(JSON.toJSONString(map1), fromusername);
            } else {
                map1.put("tousername", tousername);
                sendMessageTo(JSON.toJSONString(map1), tousername);
            }
        } catch (Exception e) {
            logger.info("發生了錯誤了");
        }

    }

    public void sendMessageTo(String message, String ToUserName) throws IOException {
        for (WebSocket item : clients.values()) {
            if (item.username.equals(ToUserName)) {
                item.session.getAsyncRemote().sendText(message);
                break;
            }
        }
    }

    public void sendMessageAll(String message, String FromUserName) throws IOException {
        for (WebSocket item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

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

}

 

4、頁面跳轉controller

     @RequestMapping("/websocket/{name}")
        public String testWebSocket(@PathVariable String name,Model model){
            try{
                model.addAttribute("username",name);
                return "websocket";
            }
            catch (Exception e){
                return "error";
            }
     }

 

5、頁面

<!DOCTYPE html>
<html>
<head>
    <title>websocket</title>
    <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js"></script>
    <script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
    <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
</head>
 
<body>
    <br/>
    <div style="margin: auto;text-align: center">
        <select id="onLineUser">
            <option>--所有--</option>
        </select>
        <input id="text" type="text" />
        <button  id="sendMsgBtn"  >發送消息</button>
    </div>
    <br>
    <div style="margin-right: 10px;text-align: right">
        <button id="closeBtn" >關閉連接</button>
    </div>
    <hr/>
    <div id="message" style="text-align: center;"></div>
    <input  type="text" th:value="${username}" id="username" style="display: none" />
</body>
 
 
<script type="text/javascript">
    var webSocket;
    var commWebSocket;
    if ("WebSocket" in window)
    {
        webSocket = new WebSocket("ws://localhost:8086/websocket/"+document.getElementById('username').value);
 
        //連通之后的回調事件
        webSocket.onopen = function()
        {
            //webSocket.send( document.getElementById('username').value+"已經上線了");
            console.log("已經連通了websocket");
            setMessageInnerHTML("已經連通了websocket");
        };
 
        //接收后台服務端的消息
        webSocket.onmessage = function (evt)
        {
            var received_msg = evt.data;
            console.log("數據已接收:" +received_msg);
            var obj = JSON.parse(received_msg);
            console.log("可以解析成json:"+obj.messageType);
            //1代表上線 2代表下線 3代表在線名單 4代表普通消息
            if(obj.messageType==1){
                //把名稱放入到selection當中供選擇
                var onlineName = obj.username;
                var option = "<option>"+onlineName+"</option>";
                $("#onLineUser").append(option);
                setMessageInnerHTML(onlineName+"上線了");
            }
            else if(obj.messageType==2){
                $("#onLineUser").empty();
                var onlineName = obj.onlineUsers;
                var offlineName = obj.username;
                var option = "<option>"+"--所有--"+"</option>";
                for(var i=0;i<onlineName.length;i++){
                    if(!(onlineName[i]==document.getElementById('username').value)){
                        option+="<option>"+onlineName[i]+"</option>"
                    }
                }
                $("#onLineUser").append(option);
 
                setMessageInnerHTML(offlineName+"下線了");
            }
            else if(obj.messageType==3){
                var onlineName = obj.onlineUsers;
                var option = null;
                for(var i=0;i<onlineName.length;i++){
                    if(!(onlineName[i]==document.getElementById('username').value)){
                        option+="<option>"+onlineName[i]+"</option>"
                    }
                }
                $("#onLineUser").append(option);
                console.log("獲取了在線的名單"+onlineName.toString());
            }
            else{
                setMessageInnerHTML(obj.fromusername+""+obj.tousername+"說:"+obj.textMessage);
            }
        };
 
        //連接關閉的回調事件
        webSocket.onclose = function()
        {
            console.log("連接已關閉...");
            setMessageInnerHTML("連接已經關閉....");
        };
    }
    else{
        // 瀏覽器不支持 WebSocket
        alert("您的瀏覽器不支持 WebSocket!");
    }
    //將消息顯示在網頁上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }
 
    $("#sendMsgBtn").click(function(){
        
        var selectText = $("#onLineUser").find("option:selected").text();
        if(selectText=="--所有--"){
            selectText = "All";
        }
        else{
            setMessageInnerHTML(document.getElementById('username').value+""+selectText+"說:"+ $("#text").val());
        }
        var message = {
            "message":document.getElementById('text').value,
            "username":document.getElementById('username').value,
            "to":selectText
        };
        webSocket.send(JSON.stringify(message));
        $("#text").val("");
        
    });

    $("#closeBtn").click(function(){
         webSocket.close();
    });
    
</script>
</html>

 

示例:

 

 

 

 

參考:

https://blog.csdn.net/qq_38455201/article/details/80374712

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM