当前位置: 代码网 > it编程>编程语言>Java > Springboot使用WebSocket发送消息

Springboot使用WebSocket发送消息

2024年08月06日 Java 我要评论
调用WebSocketHandlerRegistry 的addHandler方法传递处理器和路径。再调用WebSocketHandlerRegistry 的setAllowedOrigins方法传递星号,允许跨域访问。在MyWsHandler中,handleTextMessage方法使用的是单播发送消息,如果要给客户端/浏览器端发送广播消息该如何发送呢,只需遍历所有客户端/浏览器端的Session即可,通过Session广播消息。setAllowedOrigins()方法设置允许源,传递星号,否则跨域。

1. 创建springboot项目,引入spring-boot-starter-websocket依赖

 <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-websocket</artifactid>
 </dependency>

完整项目依赖

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.5.9</version>
        <relativepath/> <!-- lookup parent from repository -->
    </parent>
    <groupid>com.mutest</groupid>
    <artifactid>websocket-demo</artifactid>
    <version>0.0.1-snapshot</version>
    <name>websocket-demo</name>
    <description>websocket demo</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter</artifactid>
        </dependency>

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-websocket</artifactid>
        </dependency>
        <dependency>
            <groupid>org.projectlombok</groupid>
            <artifactid>lombok</artifactid>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>

</project>

2. 对websocket进行配置config
registerwebsockethandlers()方法参数是websockethandlerregistry 。调用websockethandlerregistry 的addhandler方法传递处理器和路径。处理器参数是上一步创建的textwebsockethandler 的子类。路径是客户端调用时跟在端口后的路径。再调用websockethandlerregistry 的setallowedorigins方法传递星号,允许跨域访问。

@configuration
@enablewebsocket
public class websocketconfig implements websocketconfigurer {
    @autowired
    private mywshandler mywshandler;

    @override
    public void registerwebsockethandlers(websockethandlerregistry registry) {
        registry
                .addhandler(mywshandler, "myws")
                //允许跨域
                .setallowedorigins("*");
    }
}

websockethandlerregistry
addhandler()方法第一个传输传递处理器,第一个参数传递路径
setallowedorigins()方法设置允许源,传递星号,否则跨域。

3.定义处理器mywshandler

@component
@slf4j
public class mywshandler extends abstractwebsockethandler {

    @override
    public void afterconnectionestablished(websocketsession session) {
        log.info("建立ws连接");
        wssessionmanager.add(session.getid(), session);
    }

    @override
    protected void handletextmessage(websocketsession session, textmessage message) throws exception {
        // 接收客户端/浏览器端的消息 message.getpayload()消息体
        string payload = message.getpayload();
        log.info("server 接收到客户端/浏览器端的消息 " + payload);
        log.info("发送文本消息");
        //服务端准备给客户端/浏览器端发送消息
        session.sendmessage(new textmessage("server 发送给的消息 " + payload + ",发送时间:" + localdatetime.now().tostring()));
    }

    @override
    protected void handlebinarymessage(websocketsession session, binarymessage message) throws exception {
        log.info("发送二进制消息");
    }

    @override
    public void handletransporterror(websocketsession session, throwable exception) throws exception {
        log.error("异常处理");
        wssessionmanager.removeandclose(session.getid());
    }

    @override
    public void afterconnectionclosed(websocketsession session, closestatus status) throws exception {
        log.info("关闭ws连接");
        wssessionmanager.removeandclose(session.getid());
    }
}

4. 单播/多播发送消息
在mywshandler中,handletextmessage方法使用的是单播发送消息,如果要给客户端/浏览器端发送广播消息该如何发送呢,只需遍历所有客户端/浏览器端的session即可,通过session广播消息。

@service
@slf4j
public class wsservice {
    /**
     * 发送消息
     *
     * @param session 连接信息
     * @param text    消息
     */
    public void sendmsg(websocketsession session, string text) throws ioexception {
        session.sendmessage(new textmessage(text));
    }

    /**
     * 广播消息
     *
     * @param text 消息
     */
    public void broadcastmsg(string text) throws ioexception {
        for (websocketsession session : wssessionmanager.session_pool.values()) {
            session.sendmessage(new textmessage(text));
        }
    }
}

5. 设置定时任务发送广播消息

@slf4j
@component
public class messagejob {
    @autowired
    wsservice wsservice;

    /**
     * 每5s发送
     */
    @scheduled(cron = "0/5 * * * * *")
    public void run() {
        try {
            log.info("推送消息===>" + localdatetime.now().tostring());
            wsservice.broadcastmsg("自动生成消息 " + localdatetime.now().tostring());
        } catch (ioexception e) {
            e.printstacktrace();
        }
    }
}

6. 管理客户端/浏览器端的session工具类

@slf4j
public class wssessionmanager {
    /**
     * 保存连接 session 的地方
     */
    public static concurrenthashmap<string, websocketsession> session_pool = new concurrenthashmap<>();

    /**
     * 添加 session
     *
     * @param key key
     */
    public static void add(string key, websocketsession session) {
        // 添加 session
        session_pool.put(key, session);
    }

    /**
     * 删除 session,会返回删除的 session
     *
     * @param key key
     * @return websocketsession
     */
    public static websocketsession remove(string key) {
        // 删除 session
        return session_pool.remove(key);
    }

    /**
     * 删除并同步关闭连接
     *
     * @param key key
     */
    public static void removeandclose(string key) {
        websocketsession session = remove(key);
        if (session != null) {
            try {
                // 关闭连接
                session.close();
            } catch (ioexception e) {
                // todo: 关闭出现异常处理
                e.printstacktrace();
            }
        }
    }

    /**
     * 获得 session
     *
     * @param key key
     * @return websocketsession
     */
    public static websocketsession get(string key) {
        // 获得 session
        return session_pool.get(key);
    }
}

完整的项目结构:
在这里插入图片描述
7. 测试
这里,我们使用在线测试工具,测试网址为:https://wstool.js.org/
在这里插入图片描述
客户端发送消息:

在这里插入图片描述

服务端后台收到的消息:
在这里插入图片描述
模拟服务器多播发送消息给客户端,这里我使用两个不同的浏览器去连接服务端:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com