springboot使用WebSocket

1、导包

java 复制代码
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-websocket</artifactId>
	<version>5.2.8.RELEASE</version>
</dependency>
<!--工具类 -->
	<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>5.4.1</version>
</dependency>

2、新建一个websocket包,包中新建两个类,代码如下

java 复制代码
package com.example.it.springboot.websocket;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
//websocket包需要与启动类同级别
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter()
    {
        return new ServerEndpointExporter();
    }
}
java 复制代码
package com.example.it.springboot.websocket;

import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import cn.hutool.json.JSONUtil;
import java.io.IOException;
import java.net.http.WebSocket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/***
 * 监听websocket地址  /myWs
 */
@ServerEndpoint("/myWs")
@Component
@Slf4j
@EnableScheduling
public class WsServerEndpoint {

    static Map<String, Session> map = new ConcurrentHashMap<String,Session>();

    //新增一个方法用于主动向客户端发送消息
    public static void sendMessage(Object message, String userId) {
        Session session = map.get(userId);
        if (session != null) {
            try {
                session.getBasicRemote().sendText(JSONUtil.toJsonStr(message));
                System.out.println("【websocket消息】发送消息成功,用户="+userId+",消息内容"+message.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /***
     * 连接建立时执行的操作
     * @param session
     */
    @OnOpen
    public void onOpen(Session session)
    {
        map.put(session.getId(),session);
        log.info("session.getId()="+session.getId());
        log.info("session="+session);
        log.info("websocket is open");
    }

    /***
     * 收到客户端消息执行的操作
     * @param text
     */
    @OnMessage
    public String OnMessage(String text)
    {
        log.info("收到了一条信息:  "+text);
        return "已收到你的信息" ;
    }

    /***
     * 连接关闭时执行的操作
     * @param session
     */
    @OnClose
    public void OnClose(Session session)
    {
        map.remove(session.getId());
        log.info("websocket is close");
    }

    /***
     * 向客户端发送信息
     */
    @Scheduled(fixedRate = 2000)
    public void sendMsg() throws IOException {
        for (String key : map.keySet())
        {
            //map.get(key).getBasicRemote().sendText("定时发送,你好");
        }
    }
}

3、新建一个websocket.html

java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>wsClient</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <style>
        .btn-group{
            display: inline-block;
        }
    </style>
</head>
<body>
<input type='text' value='ws://localhost:8080/myWs' class="form-control" style='width:390px;display:inline'
       id='wsaddr' />
<div class="btn-group" >
    <button type="button" class="btn btn-default" onclick='addsocket();'>连接</button>
    <button type="button" class="btn btn-default" onclick='closesocket();'>断开</button>
    <button type="button" class="btn btn-default" onclick='$("#wsaddr").val("")'>清空</button>
    <button type="button" class="btn btn-default" onclick='restore()'>还原</button>
</div>
<div id="output" style="border:1px solid #ccc;height:365px;overflow: auto;margin: 20px 0;"></div>
    <input type="text" id='message' class="form-control" style='width:810px' placeholder="待发信息" onkeydown="en(event);">
    <span class="input-group-btn">
        <button class="btn btn-default" type="button" onclick="doSend();">发送</button>
    </span>
</div>

<script>
    /*组织时间*/
    function formatDate(now) {
        var year = now.getFullYear();
        var month = now.getMonth() + 1;
        var date = now.getDate();
        var hour = now.getHours();
        var minute = now.getMinutes();
        var second = now.getSeconds();
        return year + "-" + (month = month < 10 ? ("0" + month) : month) + "-" + (date = date < 10 ? ("0" + date) : date) +
            " " + (hour = hour < 10 ? ("0" + hour) : hour) + ":" + (minute = minute < 10 ? ("0" + minute) : minute) + ":" + (
                second = second < 10 ? ("0" + second) : second);
    }
    var output;
    var websocket;

    function init() {
        output = document.getElementById("output");
    }

    /*连接按钮*/
    function addsocket() {
        var wsaddr = $("#wsaddr").val();
        if (wsaddr == '') {
            alert("请填写websocket的地址");
            return false;
        }
        StartWebSocket(wsaddr);
    }

    /*断开按钮*/
    function closesocket() {
        websocket.close();
    }

    /*还原按钮*/
    function restore(){
        $("#wsaddr").val('ws://localhost:8080/myWs');
    }

    function en(event) {
        var evt = evt ? evt : (window.event ? window.event : null);
        if (evt.keyCode == 13) {
            doSend()
        }
    }

    /*发送按钮*/
    function doSend() {
        var message = $("#message").val();
        if (message == '') {
            alert("请先填写发送信息");
            $("#message").focus();
            return false;
        }
        if (typeof websocket === "undefined") {
            alert("websocket还没有连接,或者连接失败,请检测");
            return false;
        }
        if (websocket.readyState == 3) {
            alert("websocket已经关闭,请重新连接");
            return false;
        }
        console.log(websocket);
        $("#message").val('');
        writeToScreen('<span style="color:green">你发送的信息&nbsp;' + formatDate(new Date()) + '</span><br/>' + message);
        websocket.send(message);
    }

    /*书写内容*/
    function StartWebSocket(wsUri) {
        websocket = new WebSocket(wsUri);
        websocket.onopen = function(evt) {
            onOpen(evt)
        };
        websocket.onclose = function(evt) {
            onClose(evt)
        };
        websocket.onmessage = function(evt) {
            onMessage(evt)
        };
        websocket.onerror = function(evt) {
            onError(evt)
        };
    }

    function onOpen(evt) {
        writeToScreen("<span style='color:red'>连接成功,现在你可以发送信息啦!!!</span>");
    }

    function onClose(evt) {
        writeToScreen("<span style='color:red'>websocket连接已断开!!!</span>");
        websocket.close();
    }

    function onMessage(evt) {
        writeToScreen('<span style="color:blue">服务端回应&nbsp;' + formatDate(new Date()) + '</span><br/><span class="bubble">' +
            evt.data + '</span>');
    }

    function onError(evt) {
        writeToScreen('<span style="color: red;">发生错误:</span> ' + evt.data);
    }

    function writeToScreen(message) {
        var div = "<div class='newmessage'>" + message + "</div>";
        var d = $("#output");
        var d = d[0];
        var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
        $("#output").append(div);
        if (doScroll) {
            d.scrollTop = d.scrollHeight - d.clientHeight;
        }
    }


</script>
</body>
</html>

4、新建一个后台发送测试类

java 复制代码
package com.example.it.springboot.controller;

import com.example.it.springboot.websocket.WsServerEndpoint;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.IOException;

@Controller
public class TestController {
    private WsServerEndpoint wsServerEndpoint;
    //localhost:8080/hello
    @GetMapping("/hello")
    public String setHello2() {
        System.out.println("Hello ???");
        wsServerEndpoint.sendMessage("我发了一个测试","0");
        return "Hello";
    }
}

5、访问websocket.html,进行测试,

参考链接

相关推荐
海兰5 分钟前
【第28篇】可观测性实战:LangFuse 方案详解
人工智能·spring boot·alibaba·spring ai
0xDevNull25 分钟前
Linux 中 Nginx 代理 Redis 的详细教程
redis·后端
GetcharZp41 分钟前
告别 Nginx 手动配置!这款 Go 语言开发的云原生网关,才是容器化时代的真香神器!
后端
RuoyiOffice1 小时前
SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解
spring boot·后端·vue·anti-design-vue·ruoyioffice·假期·人力
xmjd msup1 小时前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
Vane11 小时前
从零开发一个AI插件,经历了什么?
人工智能·后端
952362 小时前
SpringBoot统一功能处理
java·spring boot·后端
rleS IONS2 小时前
SpringBoot中自定义Starter
java·spring boot·后端
DevilSeagull2 小时前
MySQL(2) 客户端工具和建库
开发语言·数据库·后端·mysql·服务
TeDi TIVE3 小时前
springboot和springframework版本依赖关系
java·spring boot·后端