SpringBoot使用websocket

一、整合websocket

<!-- 引入websocket依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

开启websocket功能

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

websocket配置类

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

@Configuration
public class WebSocketConfig {
    /**
     * ServerEndpointExporter 作用
     *
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

websocket核心类

package com.winmine.WebSocket.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.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/webSocket/{sid}")
@Component
public class WebSocketServer {
   //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
   private static AtomicInteger onlineNum = new AtomicInteger();

   //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
   private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

   //发送消息
   public void sendMessage(Session session, String message) throws IOException {
       if(session != null){
           synchronized (session) {
//                System.out.println("发送数据:" + message);
               session.getBasicRemote().sendText(message);
           }
       }
   }
   //给指定用户发送信息
   public void sendInfo(String userName, String message){
       Session session = sessionPools.get(userName);
       try {
           sendMessage(session, message);
       }catch (Exception e){
           e.printStackTrace();
       }
   }

   //建立连接成功调用
   @OnOpen
   public void onOpen(Session session, @PathParam(value = "sid") String userName){
       sessionPools.put(userName, session);
       addOnlineCount();
       System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);
       try {
           sendMessage(session, "欢迎" + userName + "加入连接!");
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   //关闭连接时调用
   @OnClose
   public void onClose(@PathParam(value = "sid") String userName){
       sessionPools.remove(userName);
       subOnlineCount();
       System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);
   }

   //收到客户端信息
   @OnMessage
   public void onMessage(String message) throws IOException{
       message = "客户端:" + message + ",已收到";
       System.out.println(message);
       for (Session session: sessionPools.values()) {
           try {
               sendMessage(session, message);
           } catch(Exception e){
               e.printStackTrace();
               continue;
           }
       }
   }

   //错误时调用
   @OnError
   public void onError(Session session, Throwable throwable){
       System.out.println("发生错误");
       throwable.printStackTrace();
   }

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

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

}

在Controller中跳转页面

import com.winmine.WebSocket.service.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
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.util.HashMap;
import java.util.Map;

@Controller
public class SocketController {

    @Autowired
    private WebSocketServer webSocketServer;

    @RequestMapping("/index")
    public String index() {
        return "index";
    }

    @GetMapping("/webSocket")
    public ModelAndView socket() {
        ModelAndView mav=new ModelAndView("/webSocket");
//        mav.addObject("userId", userId);
        return mav;
    }


}

前端代码在webSocket.html中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket</title>

</head>
<body>
<h3>hello socket</h3>
<p>【userId】:<div><input id="userId" name="userId" type="text" value="10"></div>
<p>【toUserId】:<div><input id="toUserId" name="toUserId" type="text" value="20"></div>
<p>【toUserId】:<div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
<p>操作:<div><a onclick="openSocket()">开启socket</a></div>
<p>【操作】:<div><a onclick="sendMessage()">发送消息</a></div>
</body>
<script>
    

    var socket;
    function openSocket() {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        }else{
            console.log("您的浏览器支持WebSocket");
            //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
            var userId = document.getElementById('userId').value;
            // var socketUrl="ws://127.0.0.1:22599/webSocket/"+userId;
            var socketUrl="ws://192.168.0.231:22599/webSocket/"+userId;
            console.log(socketUrl);
            if(socket!=null){
                socket.close();
                socket=null;
            }
            socket = new WebSocket(socketUrl);
            //打开事件
            socket.onopen = function() {
                console.log("websocket已打开");
                //socket.send("这是来自客户端的消息" + location.href + new Date());
            };
            //获得消息事件
            socket.onmessage = function(msg) {
                var serverMsg = "收到服务端信息:" + msg.data;
                console.log(serverMsg);
                //发现消息进入    开始处理前端触发逻辑
            };
            //关闭事件
            socket.onclose = function() {
                console.log("websocket已关闭");
            };
            //发生了错误事件
            socket.onerror = function() {
                console.log("websocket发生了错误");
            }
        }
    }
    function sendMessage() {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        }else {
            // console.log("您的浏览器支持WebSocket");
            var toUserId = document.getElementById('toUserId').value;
            var contentText = document.getElementById('contentText').value;
            var msg = '{"toUserId":"'+toUserId+'","contentText":"'+contentText+'"}';
            console.log(msg);
            socket.send(msg);
        }
    }

    </script>
</html>

websocket服务端及客户端源码 https://files.cnblogs.com/files/weidaijie/ws.rar?t=1668479276

源码地址

参考链接:https://www.cnblogs.com/JohanChan/p/12522001.html
https://www.kancloud.cn/hanxt/springboot2/1185843

posted @ 2021-02-20 10:45  离人怎挽_wdj  阅读(125)  评论(0编辑  收藏  举报