Java Spring boot 整合webSocket

先提供一个在线测试工具 http://www.websocket-test.com/

 

1、pom文件导出对应的依赖

 

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

 

 

2、创建一个类,标记为WebSocket服务

**
 * Created with IntelliJ IDEA.
 *
 * @Date: 2022/08/18/9:45
 * @Description:
 */

import org.springframework.stereotype.Component;

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 java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

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

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

    /**
     * 建立连接成功调用
     *
     * @param session:webSocket 信息
     * @param userName:用户名
     * @throws IOException
     * @throws InterruptedException
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "username") String userName) throws IOException, InterruptedException {
        sessionPools.put(userName, session);
        // 当前在线人数+1
        addOnlineCount();
        System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);
        System.out.println(session.getId());

        // 广播上线消息
        /*Message msg = new Message();
        msg.setDate(new Date());
        msg.setType("0");
        msg.setContent(userName);
        broadcast(JSON.toJSONString(msg,true));*/
        broadcast("ssssssssssssss");
    }

    /**
     * 关闭连接时调用
     *
     * @param userName:用户名称
     * @throws IOException
     */
    @OnClose
    public void onClose(@PathParam(value = "username") String userName) throws IOException {
        sessionPools.remove(userName);
        // 当前在线人数-1
        subOnlineCount();
        System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);
        // 广播下线消息(视需求而用)
        /*Message msg = new Message();
        msg.setDate(new Date());
        msg.setType("-2");
        msg.setContent(userName);
        broadcast(JSON.toJSONString(msg,true));*/
    }

    /**
     * 给指定用户发送信息
     *
     * @param userName:用户名称
     * @param message:要发送的内容
     */
    public static void sendInfo(String userName, String message) {
        Session session = sessionPools.get(userName);
        try {
            sendMessage(session, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 群发消息
     *
     * @param message:要发送的消息
     */
    public void broadcast(String message) {
        for (Session session : sessionPools.values()) {
            try {
                sendMessage(session, message);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    /**
     * 发送消息
     *
     * @param session:该用户的webSocket 信息
     * @param message:要发送的信息
     * @throws IOException
     */
    public static void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            synchronized (session) {
                System.out.println("发送数据:" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }

    /**
     * 收到客户端信息后,根据接收人的 username 把消息推下去或者群发
     * to = -1 群发消息
     *
     * @param message:信息内容
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println("server get: " + message);
//        Message msg=JSON.parseObject(message, Message.class);
//        msg.setDate(new Date());
//        if (msg.getType().equals("-1")) {
//            broadcast(JSON.toJSONString(msg,true));
//        } else {
//            sendInfo(msg.getType(), JSON.toJSONString(msg,true));
//        }
        sendInfo("DDDD","DDDD");
    }

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

    /**
     * 当前在线人数+1
     */
    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    /**
     * 当前在线人数-1
     */
    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

    public static AtomicInteger getOnlineNumber() {
        return onlineNum;
    }

    public static ConcurrentHashMap<String, Session> getSessionPools() {
        return sessionPools;
    }

}

添加配置类

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chenyongfu
 * @Date: 2022/08/18/10:03
 * @Description:
 */

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

/**
 *
 */
@Component
public class WebSocketConfig {

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

}

控制层

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 
 * @Date: 2022/08/18/11:19
 * @Description:
 */
@RestController
@RequestMapping("/WebSocket")
public class TEST {

    @GetMapping("/send")
    public void send(){
        WebSocketServer.sendInfo("DDDD","aaaaaaaa");
    }
}

 

3、启动项目使用Chrome浏览器进行调试

 

 

websocket = new WebSocket('ws://localhost:9100/webSocket/DDDD')
websocket.onmessage = function(ev) {
                var data = ev.data.replace(new RegExp("\n","gm"),"")
                console.log(data) ;}

 

访问控制层api即可发送消息到对应的user

 

参考资料:

https://blog.csdn.net/weixin_40836179/article/details/121513685

https://blog.csdn.net/fl8545/article/details/125553193

https://blog.csdn.net/qq_35253422/article/details/125913440

 
posted @ 2022-08-18 15:41  铁锅炖猫  阅读(187)  评论(0)    收藏  举报