Java中初步使用websocket(springBoot版本)
一、什么是websocket
WebSocket是一种在Web应用程序中实现实时双向通信的协议。它为浏览器和服务器之间提供了一种持久连接,在一个连接上可以双向传输数据。相比传统的HTTP协议,WebSocket具有更低的延迟和更高的效率。
WebSocket使用了类似于握手的方式来建立连接。在握手过程中,浏览器和服务器会交换一些信息,以建立一个WebSocket连接。一旦连接建立,浏览器和服务器之间就可以实时地传输数据,而不需要每次都发起新的HTTP请求。
WebSocket协议可以在不同的平台和编程语言中实现,包括Web浏览器和服务器端。在Web浏览器中,可以使用JavaScript中的WebSocket API来实现WebSocket连接。在服务器端,可以使用各种编程语言和框架来实现WebSocket服务器。
WebSocket的应用场景非常广泛。它可以用于实时聊天应用、实时游戏、实时股票行情、实时协作编辑等需要实时通信的应用程序。通过WebSocket,开发人员可以更加方便地实现实时通信功能,提高用户体验。
这里我们使用Java配合springboot2进行使用。
二、依赖坐标地址
1.springBoot父级依赖
<!--依赖的父级工程--> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.6</version><relativePath/> </parent>
2.springBoot依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>
3.webSocket依赖
<dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.3.8</version> </dependency>
三、代码
不多说了,直接拿去看吧,都在注释里面了。
服务器:
package com.blockchain.qgy.network.websocket;import com.blockchain.qgy.util.Strings;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;@Component
public class P2pPointServer {//日志记录private Logger logger = LoggerFactory.getLogger(P2pPointServer.class);//本机的Server的WebSocket端口private Integer port = 7001;//所有连接到服务器的WebSocket缓存器private List<WebSocket> localSockets = new ArrayList<>();public List<WebSocket> getLocalSockets() {return localSockets;}public void setLocalSockets(List<WebSocket> localSockets) {this.localSockets = localSockets;}@PostConstruct@Order(1)public void initServer(){final WebSocketServer socketServer = new WebSocketServer(new InetSocketAddress(port)) {//创建链接成功时触发@Overridepublic void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {sendMessage(webSocket,"孩子们,我回来了!");localSockets.add(webSocket);}//断开连接时触发@Overridepublic void onClose(WebSocket webSocket, int i, String s, boolean b) {logger.info(webSocket.getRemoteSocketAddress() + "客户端与服务器断开连接");localSockets.remove(webSocket);}//接收到消息时触发@Overridepublic void onMessage(WebSocket webSocket, String s) {logger.info("收到了客户端的消息:" + s);sendMessage(webSocket,"孩子们,我收到消息了");}//连接发送错误时调用,后触发onClose方法@Overridepublic void onError(WebSocket webSocket, Exception e) {logger.info(webSocket.getRemoteSocketAddress() + "客户端与服务器连接发送错误");localSockets.remove(webSocket);}@Overridepublic void onStart() {logger.info("孩子们我要启动了!!");}};socketServer.start();logger.info("Man!what can I say,我已经启动了");}/*** 一对一发送* @param webSocket:客户端* @param message:信息*/public void sendMessage(WebSocket webSocket,String message){logger.info("发送给"+webSocket.getRemoteSocketAddress().getPort() + "的p2p消息是:" + message);webSocket.send(message);}/*** 一对多发送* @param message:信息*/public void broatcast(String message){if (localSockets.size() == 0 || Strings.isNullOrEmpty(message)) return;logger.info("张开第三只眼");for (WebSocket webSocket : localSockets){this.sendMessage(webSocket,message);}logger.info("孩子们我燃尽了");}
}
客户端:
package com.blockchain.qgy.network.websocket;import com.blockchain.qgy.util.Strings;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;@Component
public class P2pPointClient {//日志记录private Logger logger = LoggerFactory.getLogger(P2pPointClient.class);//服务器端的地址private String wsUrl = "ws://localhost:7001/";//所有连接到客户端的WebSocket缓存器private List<WebSocket> localSockets = new ArrayList<>();public List<WebSocket> getLocalSockets() {return localSockets;}public void setLocalSockets(List<WebSocket> localSockets) {this.localSockets = localSockets;}@PostConstruct@Order(2)public void connectServer(){try {final WebSocketClient socketClient = new WebSocketClient(new URI(wsUrl)) {@Overridepublic void onOpen(ServerHandshake serverHandshake) {sendMessage(this,"孩子们,我是客户端");localSockets.add(this);}@Overridepublic void onMessage(String s) {logger.info("收到服务器发来的信息:"+s);}@Overridepublic void onClose(int i, String s, boolean b) {logger.info("断开连接");localSockets.remove(this);}@Overridepublic void onError(Exception e) {logger.info("连接错误");localSockets.remove(this);}};socketClient.connect();} catch (Exception e) {e.printStackTrace();logger.info("连接错误");}}/*** 一对一发送* @param webSocket:客户端* @param message:信息*/public void sendMessage(WebSocket webSocket,String message){logger.info("发送给"+webSocket.getRemoteSocketAddress().getPort() + "的p2p消息是:" + message);webSocket.send(message);}/*** 一对多发送* @param message:信息*/public void broatcast(String message){if (localSockets.size() == 0 || Strings.isNullOrEmpty(message)) return;logger.info("张开第三只眼");for (WebSocket webSocket : localSockets){this.sendMessage(webSocket,message);}logger.info("孩子们我燃尽了");}
}
相关文章:
Java中初步使用websocket(springBoot版本)
一、什么是websocket WebSocket是一种在Web应用程序中实现实时双向通信的协议。它为浏览器和服务器之间提供了一种持久连接,在一个连接上可以双向传输数据。相比传统的HTTP协议,WebSocket具有更低的延迟和更高的效率。 WebSocket使用了类似于握手的方式来…...
2025年大年初一篇,C#调用GPU并行计算推荐
C#调用GPU库的主要目的是利用GPU的并行计算能力,加速计算密集型任务,提高程序性能,支持大规模数据处理,优化资源利用,满足特定应用场景的需求,并提升用户体验。在需要处理大量并行数据或进行复杂计算的场景…...
K8S ReplicaSet 控制器
一、理论介绍 今天我们来实验 ReplicaSet 控制器(也叫工作负载)。官网描述如下: 1、是什么? ReplicaSet 副本集, 维护一组稳定的副本 Pod 集合。 2、为什么需要? 解决 pod 被删除了,不能自我恢…...
FreeRTOS学习 --- 任务调度
开启任务调度器 作用:用于启动任务调度器,任务调度器启动后, FreeRTOS 便会开始进行任务调度 该函数内部实现,如下: 1、创建空闲任务(优先级最低) 2、如果使能软件定时器,则创建定…...
【小鱼闪闪】单片机开发工具——米思齐软件下载安装(图文)
浏览器打开网址 mixly.org, 在软件平台选择mixly离线版。 最新版本为3.0,会支持audinio, ESP32、ESP8266 , 可以选择下载安装器或者完整版。 这里选择下载安装器,下载后运行“一键更新.bat”,即可自动下载最新版本的M…...
MFC开发,给对话框添加垂直滚动条并解决鼠标滚动响应的问题
无论在使用QT或者MFC进行界面开发时,都会出现在一个对话框里面存在好多的选项,导致对话框变得非常长或者非常大,就会显现的不美观,在这种情况下通常是添加一个页面的滚动条来解决这个问题,下面我们就来介绍给MFC的对话…...
动态规划DP 最长上升子序列模型 导弹防御模型(题目分析+C++完整代码实现)
概览检索 动态规划DP 最长上升子序列模型 导弹防御系统 原题链接 AcWiing 187. 导弹防御系统 题目描述 为了对抗附近恶意国家的威胁,R国更新了他们的导弹防御系统。 一套防御系统的导弹拦截高度要么一直 严格单调 上升要么一直 严格单调 下降。 例如࿰…...
LevelDB 源码阅读:写入键值的工程实现和优化细节
读、写键值是 KV 数据库中最重要的两个操作,LevelDB 中提供了一个 Put 接口,用于写入键值对。使用方法很简单: leveldb::Status status leveldb::DB::Open(options, "./db", &db); status db->Put(leveldb::WriteOptions…...
药店药品销售管理系统的设计与实现
标题:药店药品销售管理系统的设计与实现 内容:1.摘要 摘要:本文介绍了药店药品销售管理系统的设计与实现。该系统旨在提高药店的运营效率和管理水平,通过信息化手段实现药品销售、库存管理、财务管理等功能。本文详细阐述了系统的需求分析、设计思路、技…...
人格分裂(交互问答)-小白想懂Elasticsearch
通过交互式追问了解一个中间件 ? 啥是Elasticsearch ! 分布式搜索和分析引擎 ? 为啥是分布式搜索,单体难道用不了吗 ? 实际上是说这个东西可以分布式部署 ! 单机可用但扩展性差,分布式通过分片、副本和负载均衡实现海量数据存储与高并发处理 ? 提…...
【论文投稿-第八届智能制造与自动化学术会议(IMA 2025)】HTML, CSS, JavaScript:三者的联系与区别
大会官网:www.icamima.org 目录 前言 一、HTML(超文本标记语言):网页的骨架 HTML 的作用: 例子: 总结: 二、CSS(层叠样式表):网页的外观设计 CSS 的…...
python | OpenCV小记(一):cv2.imread(f) 读取图像操作(待更新)
python | OpenCV小记(一):cv2.imread(f)读取图像操作 1. 为什么 [:, :, 0] 提取的是第一个通道(B 通道)?OpenCV 的通道存储格式索引操作 [:, :, 0] 的解释常见误解 1. 为什么 [:, :,…...
网络工程师 (9)文件管理
一、树形目录结构 (一)定义与构成 树形目录结构由一个根目录和若干层子文件夹(或称为子目录)组成,它像一棵倒置的树。这棵树的根称为根文件夹(也叫根目录),从根向下,每一…...
Java中的线程池参数(详解)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {} 此构造方法的参数如下: int corePoolSize&…...
2 MapReduce
2 MapReduce 1. MapReduce 介绍1.1 MapReduce 设计构思 2. MapReduce 编程规范3. Mapper以及Reducer抽象类介绍1.Mapper抽象类的基本介绍2.Reducer抽象类基本介绍 4. WordCount示例编写5. MapReduce程序运行模式6. MapReduce的运行机制详解6.1 MapTask 工作机制6.2 ReduceTask …...
如何用函数去计算x年x月x日是(C#)
如何用函数去计算x年x月x日是? 由于现在人工智能的普及,我们往往会用计算机去算,或者去记录事情 1.计算某一年某一个月有多少天 2.计算某年某月某日是周几 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threadin…...
开发过程中如何减少属性注释?
一、注释冗余 举个例子,我们在开发项目中肯定会有状态字段,现在有个工单状态枚举 StatusEnum.java package cn.zxj.note;/*** author: Administrator* since: 2025/1/30 14:40* description:*/ public enum StatusEnum {TO_BE_SUBMITTED(1,"待提交…...
NX/UG二次开发—CAM—快速查找程序参数名称
使用UF_PARAM_XXX读取或设置参数时,会发现程序中有一个INT类型参数param_index,这个就是对应程序中的参数,比如读取程序余量,则param_index = UF_PARAM_STOCK_PART,读取程序的加工坐标系则param_index = UF_PARAM_MCS等等。 你需要读取什么参数,只要只能在uf_param_indic…...
socket实现HTTP请求,参考HttpURLConnection源码解析
背景 有台服务器,网卡绑定有2个ip地址,分别为: A:192.168.111.201 B:192.168.111.202 在这台服务器请求目标地址 C:192.168.111.203 时必须使用B作为源地址才能访问目标地址C,在这台服务器默认…...
访问CMOS RAM
实验内容、程序清单及运行结果 访问CMOS RAM(课本实验14) 代码如下: assume cs:code data segment time db yy/mm/dd hh:mm:ss$ ;int 21h 显示字符串,要求以$结尾 table db 9,8,7,4,2,0 ;各时间量的存放单元 data ends cod…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
