当前位置: 代码网 > it编程>编程语言>Java > 【Java】SpringBoot快速整合WebSocket实现客户端服务端相互推送信息

【Java】SpringBoot快速整合WebSocket实现客户端服务端相互推送信息

2024年08月03日 Java 我要评论
SpringBoot快速整合WebSocket,内涵详细代码加测试(跑不起来来打我)

目录

什么是websocket?

websocket可以用来做什么?

websocket操作类

一:测试客户端向服务端推送消息

1.启动springboot项目

2.打开网站

3.进行测试消息推送

4.后端进行查看测试结果

二:测试服务端向客户端推送消息

1.接口代码

2.使用postman进行调用

3.查看测试结果


什么是websocket?

        websocket是一种在单个tcp连接上进行全双工通信的协议。websocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。而http请求只能从客户端请求服务端才能得到响应。在websocket api中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

websocket可以用来做什么?

        利用双向数据传输的特点可以用来完成很多功能,不需要前端轮询,浪费资源。例如:
聊天功能、数据实时更新和视频弹幕等

websocket协议
本协议有两部分:握手和数据传输。
握手是基于http协议的。

来自客户端的握手看起来像如下形式:

来自服务器的握手看起来像如下形式

springboot快速整合websocket代码案例:

下面我就使用springboot快速整合websocket实现服务端与客户端的相互推送消息;

代码层级结构


maven依赖

     <!--websocket的依赖-->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-websocket</artifactid>
        </dependency>

websocket配置类

package com.example.springboot_websocket_demo01;

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
     */
    @bean
    public serverendpointexporter serverendpointexporter() {
        return new serverendpointexporter();
    }
    
}

websocket操作类

通过该类websocket可以进行群推送以及单点推送

package com.example.springboot_websocket_demo01;

import jakarta.websocket.*;
import jakarta.websocket.server.pathparam;
import jakarta.websocket.server.serverendpoint;
import lombok.extern.slf4j.slf4j;
import org.springframework.stereotype.component;

import java.util.concurrent.concurrenthashmap;
import java.util.concurrent.copyonwritearrayset;

@component
@slf4j
@serverendpoint("/websocket/{userid}")  // 接口路径 ws://localhost:8087/websocket/userid;
public class websocket {

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private session session;
    /**
     * 用户id
     */
    private string userid;

    //concurrent包的线程安全set,用来存放每个客户端对应的mywebsocket对象。
    //虽然@component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
    //  注:底下websocket是当前类名
    private static copyonwritearrayset<websocket> websockets = new copyonwritearrayset<>();
    // 用来存在线连接用户信息
    private static concurrenthashmap<string, session> sessionpool = new concurrenthashmap<string, session>();

    /**
     * 链接成功调用的方法
     */
    @onopen
    public void onopen(session session, @pathparam(value = "userid") string userid) {
        try {
            this.session = session;
            this.userid = userid;
            websockets.add(this);
            sessionpool.put(userid, session);
            log.info("【websocket消息】有新的连接,总数为:" + websockets.size());
        } catch (exception e) {
        }
    }

    /**
     * 链接关闭调用的方法
     */
    @onclose
    public void onclose() {
        try {
            websockets.remove(this);
            sessionpool.remove(this.userid);
            log.info("【websocket消息】连接断开,总数为:" + websockets.size());
        } catch (exception e) {
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     */
    @onmessage
    public void onmessage(string message) {
        log.info("【websocket消息】收到客户端消息:" + message);
    }

    /**
     * 发送错误时的处理
     *
     * @param session
     * @param error
     */
    @onerror
    public void onerror(session session, throwable error) {
        log.error("用户错误,原因:" + error.getmessage());
        error.printstacktrace();
    }

    // 此为广播消息
    public void sendallmessage(string message) {
        log.info("【websocket消息】广播消息:" + message);
        for (websocket websocket : websockets) {
            try {
                if (websocket.session.isopen()) {
                    websocket.session.getasyncremote().sendtext(message);
                }
            } catch (exception e) {
                e.printstacktrace();
            }
        }
    }

    // 此为单点消息
    public void sendonemessage(string userid, string message) {
        session session = sessionpool.get(userid);
        if (session != null && session.isopen()) {
            try {
                log.info("【websocket消息】 单点消息:" + message);
                session.getasyncremote().sendtext(message);
            } catch (exception e) {
                e.printstacktrace();
            }
        }
    }

    // 此为单点消息(多人)
    public void sendmoremessage(string[] userids, string message) {
        for (string userid : userids) {
            session session = sessionpool.get(userid);
            if (session != null && session.isopen()) {
                try {
                    log.info("【websocket消息】 单点消息:" + message);
                    session.getasyncremote().sendtext(message);
                } catch (exception e) {
                    e.printstacktrace();
                }
            }
        }

    }

}

注意:websocketconfig和websocket必须放在同一层级下,否则websocket扫描不到serverendpoint注解。

一:测试客户端向服务端推送消息

1.启动springboot项目

2.打开网站

websocket测试 devtest.run

输入

ws://127.0.0.1:8080/websocket/100

进行连接,测试是否连接成功

3.进行测试消息推送

4.后端进行查看测试结果

测试成功,说明客户端可以使用websocket对服务端推送消息。

二:测试服务端向客户端推送消息

1.接口代码

package com.example.springboot_websocket_demo01;

import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.postmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

@restcontroller
@requestmapping("/api")
public class yourcontroller {

    @autowired
    private websocket websocket;

    @postmapping("/sendnotification")
    public void sendnotification() {
        try {
            // 创建业务消息信息
            string message = "postman调用接口访问后端服务器存储数据并使用websocket将消息推送给前端客户端";

            // 全体发送
            websocket.sendallmessage(message);

            // 单个用户发送 (userid为用户id)
            string userid = "1";

            string message1 = "【websocket消息】 单点消息:只发送给id为"+userid+"的用户。";
            websocket.sendonemessage(userid, message1);

            // 多个用户发送 (userids为多个用户id,逗号‘,’分隔)
            string[] userids = {"1", "2"};
            string message2 = "【websocket消息】 单点消息:只发送给id为"+userids.tostring()+"的用户。";
            websocket.sendmoremessage(userids, message2);
        } catch (exception e) {
            // 输出异常信息
            e.printstacktrace();
        }
    }

}

2.使用postman进行调用

用来模仿客户端发送消息到后端服务器然后返回给客户端。(其实也可以直接在websocket类中的onmessage中直接进行操作,调用sendallmessage等其他方法进行测试);

3.查看测试结果

websocket测试 devtest.run

正常结果为

还有很多测试方法,自己可以去思考,以上对于springboot整合websocket来说可以算是一个简单的入门案例了。

(0)

相关文章:

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

发表评论

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