消息服务应用1——java项目使用websocket

news2024/12/30 1:08:56

在当前微服务项目中,由于业务模块众多,消息服务的使用场景变得异常活跃。而WebSocket由于其自身的可靠性强,实时性好,带宽占用更小的优势,在实时通讯应用场景中独占鳌头,加上HTML5标准的普及流行,在前端和后端开发中应用异常广泛。

一.关于WebSocket

1.WebSocket是什么?

WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。简单来说,它就是html5中的一种新的协议,其实质就是对html的长连接的一种升级。

2.与HTTP比较
  • HTTP是短连接,WebSocket是长连接;
  • HTTP通信是单向的,基于请求响应模式,WebSocket支持双向通信;
  • HTTP和WebSocket底层都是TCP连接。
3.WebSocket优点
  • websocket连接只需要建立一次,在第一次连接的时候,客户端和服务器会交换必要的信息。
  • websocket是双向通信的,对比ajax请求还是长轮询,他们都是通过客户端发送请求,服务器响应的形式完成信息的交换,这种模式下服务器处于一种被动的角色。而websocket不存在这个问题,websocket的链接一旦建立,服务器和客户端都可以互推信息。

二. WebSocket使用

文案基于jdk1.8+maven3.8.1+springboot2.7.13而编写

1.引入websocket.jar包
        <!-- websocket模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
2.配置WebSocket
@Configuration
public class MyWebSocketConfig {

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

}
3.WebSocket连接,发送和接收信息
@ServerEndpoint("/websocket/test")
@Component
public class TestWebSocketInfo {

    /**
     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static int ONLINE_COUNT = 0;

    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的BigScreenWebSocket对象。
     */
    private static CopyOnWriteArraySet<TestWebSocketInfo> WEB_SOCKET_SET = new CopyOnWriteArraySet<>();
    /**
     * 存储新链接标识。
     */
    public static Map<String, Object> USER_SESSIONS = new HashMap<>(0);
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据。
     */
    private Session session;


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) throws Exception {
        this.session = session;
        // 生成唯一ID
        String uuid = String.valueOf(UUID.randomUUID());
        // 把唯一标识跟客户端绑定
        USER_SESSIONS.put(uuid, this.session);
        // 加入set中
        WEB_SOCKET_SET.add(this);
        synchronized (this) {
            // 使用加锁的方式保证请求串行计数
            TestWebSocketInfo.ONLINE_COUNT++;
        }
        //需要发送到业务数据
        onMessage(JSONObject.toJSONString("Hello,Websocket"));
        System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        // 从set中删除
        WEB_SOCKET_SET.remove(this);
        boolean removeFlag = WEB_SOCKET_SET.remove(this);
        // 使用加锁的方式保证请求串行计数
        if (removeFlag && BigScreenWebSocketInfo.ONLINE_COUNT > 0) {
            TestWebSocketInfo.ONLINE_COUNT--;
        }
        System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {
        sendMessage(message);
    }

    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        // 从set中删除
        USER_SESSIONS.remove(session);
        // 从set中删除
        boolean removeFlag = WEB_SOCKET_SET.remove(this);
        USER_SESSIONS.remove(session);
        // 使用加锁的方式保证请求串行计数
        if (removeFlag && BigScreenWebSocketInfo.ONLINE_COUNT > 0) {
            TestWebSocketInfo.ONLINE_COUNT--;
        }
        System.out.println("发生错误");
        error.printStackTrace();
    }


    public void sendMessage(String message) {
        try {
            for (TestWebSocketInfo item : WEB_SOCKET_SET) {
                // 判断链接是否关闭
                if (item.session.isOpen()) {
                    synchronized (item.session) {
                        item.session.getBasicRemote().sendText(message);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static synchronized int getOnlineCount() {
        return ONLINE_COUNT;
    }
}
4.功能测试

当服务端开发完成之后,可以使用https://wstool.js.org/该网址自主连接测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1621952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MultiHeadAttention在Tensorflow中的实现原理

前言 通过这篇文章&#xff0c;你可以学习到Tensorflow实现MultiHeadAttention的底层原理。 一、MultiHeadAttention的本质内涵 1.Self_Atention机制 MultiHeadAttention是Self_Atention的多头堆嵌&#xff0c;有必要对Self_Atention机制进行一次深入浅出的理解&#xff0c;这…

Docker 入门篇(一)-- 简介与安装教程(Windows和Linux)

一、Docker简介 Docker是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何Linux机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间没有任何接口&#xff08;类似iPhon…

记录海豚调度器删除工作流实例失败的解决办法(DolphinScheduler的WebUI删除失败)

本博客记录以下问题解决办法&#xff1a;使用dolphinscheduler的WebUI运行工作流后出现内存占用过高导致的任务阻塞问题&#xff0c;并且在删除工作流实例时总是报错无法删除 解决步骤 在前端页面无法删除&#xff0c;于是搜索资料&#xff0c;发现可以登录数据库进行工作流实…

【C语言 |预处理指令】预处理指令详解(包括编译与链接)

目录 一、编译与链接 1.翻译环境 -预处理 -编译 -汇编 -链接 2.执行环境 二、预定义符号 三、#define定义常量 四、#define定义宏 五、带有副作用的宏参数 六、宏替换的规则 七、 宏函数的对比 八、#和## 1.#运算符 2.##运算符 九、命名约定 十、#undef 十一、 命…

【服务器部署篇】Linux下Tomcat安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

Linux网络编程---Socket编程

一、网络套接字 一个文件描述符指向一个套接字(该套接字内部由内核借助两个缓冲区实现。) 在通信过程中&#xff0c;套接字一定是成对出现的 套接字通讯原理示意图&#xff1a; 二、预备知识 1. 网络字节序 内存中的多字节数据相对于内存地址有大端和小端之分 小端法&…

Ubuntu终端常用指令

cat cat 读取文件的内容 1、ls 一、 1、ll 显示当前目录下文件的详细信息,包括读写权限,文件大小,文件生成日期等(若想按照更改的时间先后排序,则需加-t参数,按时间降序(最新修改的时间排在最前)执行: $ ll -t, 按时间升序执行: $ ll -t | tac): ll 2、查看当前所处路径(完整…

Qt中常用对话框

Qt中的对话框&#xff08;QDialog&#xff09;是用户交互的重要组件&#xff0c;用于向用户提供特定的信息、请求输入、或进行决策。Qt提供了多种标准对话框以及用于自定义对话框的类。以下将详细介绍几种常用对话框的基本使用、使用技巧以及注意事项&#xff0c;并附带C示例代…

node.js 解析post请求 方法一

前提&#xff1a;依旧以前面发的node.js服务器动态资源处理代码 具体见 http://t.csdnimg.cn/TSNW9为模板&#xff0c;在这基础上进行修改。与动态资源处理代码不同的是&#xff0c;这次的用户信息我们借用表单来实现。post请求解析来获取和展示用户表单填写信息 1》代码难点&…

全彩屏负氧离子监测站的使用

TH-FZ5在繁忙的都市生活中&#xff0c;我们往往忽视了一个至关重要的问题——空气质量。随着工业化的进程加速&#xff0c;空气污染已成为影响人们健康的一大隐患。为了实时监测和了解身边的空气质量&#xff0c;全彩屏负氧离子监测站应运而生&#xff0c;成为了我们守护呼吸健…

企业集成平台建设方案(技术方案+功能设计)

企业集成平台建设方案及重点难点攻坚 基础支撑平台主要承担系统总体架构与各个应用子系统的交互&#xff0c;第三方系统与总体架构的交互。需要满足内部业务在该平台的基础上&#xff0c;实现平台对于子系统的可扩展性。基于以上分析对基础支撑平台&#xff0c;提出了以下要求&…

稀碎从零算法笔记Day59-LeetCode: 感染二叉树需要的总时间

题型&#xff1a;树、图、BFS、DFS 链接&#xff1a;2385. 感染二叉树需要的总时间 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一棵二叉树的根节点 root &#xff0c;二叉树中节点的值 互不相同 。另给你一个整数 start 。在第 0 分钟…

25计算机考研院校数据分析 | 北京航空航天大学

北京航空航天大学(Beihang University)&#xff0c;简称北航&#xff0c;由中华人民共和国工业和信息化部直属&#xff0c;中央直管副部级建制&#xff0c;位列“双一流”、"211工程”、"985工程”&#xff0c;入选“珠峰计划”、"2011计划”、“111计划”、&qu…

STM32标准库ADC和DMA知识点总结

目录 前言 一、ADC模数转换器 &#xff08;1&#xff09;AD单通道 &#xff08;2&#xff09;AD多通道 二、DMA原理和应用 &#xff08;1&#xff09;DMA数据转运&#xff08;内存到内存&#xff09; &#xff08;2&#xff09;DMAAD多同道&#xff08;外设到内存&#x…

debian和ubuntu的核心系统和系统命令的区别

Debian和Ubuntu虽然有很深的渊源&#xff0c;都是基于Debian的发行版&#xff0c;但它们在核心系统和系统命令上还是有一些差别的。以下是一些主要的不同之处&#xff1a; 1. 发布周期&#xff1a; - Debian&#xff1a; Debian项目采用滚动发布模型&#xff0c;持续更新&a…

SpringCloud Alibaba--nacos配置中心

目录 一.基础介绍 1.1概念 1.2 功能 二.实现 2.1 依赖 2.2 新建配置文件 2.3 克隆 2.4 配置bootstap.yml文件 三.测试 一.基础介绍 1.1概念 在微服务架构中&#xff0c;配置中心就是统一管理各个微服务配置文件的服务。把传统的单体jar包拆分成多个微服务后&#xf…

到底什么是认证

认证和授权 什么是认证 认证 (Authentication) 是根据凭据验明访问者身份的流程。即验证“你是你所说的那个人”的过程。 身份认证&#xff0c;通常通过用户名/邮箱/手机号以及密码匹配来完成&#xff0c;也可以通过手机/邮箱验证码或者生物特征&#xff08;如&#xff1a;指纹…

LangChain的核心模块和实战

主要模型 LLM:对话模型, 输入和输出都是文本Chat Model: 输入输出都是数据结构 模型IO设计 Format: 将提示词模版格式化Predict: langchain就是通过predict的方式调用不同的模型, 两个模型的区别不大, Chat Model 是以LLM为基础的.Parese: langchain还可以对结果进行干预, 得…

css盒子设置圆角边框的方法

前言 欢迎来到我的博客 个人主页&#xff1a;北岭敲键盘的荒漠猫-CSDN博客 本文为我整理的设置圆角边框的方法 需求描述 我们在设置盒子边框时&#xff0c;他总是方方正正的。 我们想让这个直直的边框委婉一点该怎么办呢。这个就提到了我们这篇文章讲的东西&#xff1a; bord…

二分查找知识点及练习题

知识点讲解 一、没有相同元素查找 请在一个有序递增数组中&#xff08;不存在相同元素&#xff09;&#xff0c;采用二分查找&#xff0c;找出值x的位置&#xff0c;如果x在数组中不存在&#xff0c;请输出-1&#xff01; 输入格式 第一行&#xff0c;一个整数n&#xff0c;代…