当前位置: 首页 > news >正文

基于Netty实现安全认证的WebSocket(wss)客户端

1.Netty服务端

服务端代码参考【基于Netty实现安全认证的WebSocket(wss)服务端-CSDN博客】

2.Netty客户端

客户端代码参考【基于Netty实现WebSocket客户端-CSDN博客】中两种都可以;这里用的是第一种。

新增SslHandler的代码:

SslContext sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
...
pipeline.addLast(sslCtx.newHandler(sc.alloc(), webSocketURL.getHost(), webSocketURL.getPort()));

服务端地址的协议头调整为wss

final URI webSocketURL = new URI("wss://127.0.0.1:7070/helloWs");

完整的客户端代码如下:

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.stream.ChunkedWriteHandler;
import lombok.extern.slf4j.Slf4j;import java.net.URI;
import java.util.concurrent.CountDownLatch;/*** https://blog.csdn.net/a1053765496/article/details/130701218* 基于Netty快速实现WebSocket客户端,不手动处理握手*/
@Slf4j
public class SimpleWssClient {final CountDownLatch latch = new CountDownLatch(1);public static void main(String[] args) throws Exception {SimpleWssClient client = new SimpleWssClient();client.test();}public void test() throws Exception {Channel dest = dest();latch.await();dest.writeAndFlush(new TextWebSocketFrame("CountDownLatch完成后发送的消息"));}public Channel dest() throws Exception {final URI webSocketURL = new URI("wss://127.0.0.1:7070/helloWs");EventLoopGroup group = new NioEventLoopGroup();SslContext sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();Bootstrap boot = new Bootstrap();boot.option(ChannelOption.SO_KEEPALIVE, true).option(ChannelOption.TCP_NODELAY, true).group(group).handler(new LoggingHandler(LogLevel.INFO)).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel sc) throws Exception {ChannelPipeline pipeline = sc.pipeline();pipeline.addLast(sslCtx.newHandler(sc.alloc(), webSocketURL.getHost(), webSocketURL.getPort()));pipeline.addLast(new HttpClientCodec());pipeline.addLast(new ChunkedWriteHandler());pipeline.addLast(new HttpObjectAggregator(64 * 1024));pipeline.addLast(new WebSocketClientProtocolHandler(WebSocketClientHandshakerFactory.newHandshaker(webSocketURL, WebSocketVersion.V13, null, false, new DefaultHttpHeaders())));pipeline.addLast(new SimpleChannelInboundHandler<TextWebSocketFrame>() {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg)throws Exception {System.err.println(" 客户端收到消息======== " + msg.text());}@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {if (WebSocketClientProtocolHandler.ClientHandshakeStateEvent.HANDSHAKE_COMPLETE.equals(evt)) {log.info(ctx.channel().id().asShortText() + " 握手完成!");latch.countDown();send(ctx.channel());}super.userEventTriggered(ctx, evt);}});}});ChannelFuture cf = boot.connect(webSocketURL.getHost(), webSocketURL.getPort()).sync();return cf.channel();}public static void send(Channel channel) {final String textMsg = "握手完成后直接发送的消息";if (channel != null && channel.isActive()) {TextWebSocketFrame frame = new TextWebSocketFrame(textMsg);channel.writeAndFlush(frame).addListener((ChannelFutureListener) channelFuture -> {if (channelFuture.isDone() && channelFuture.isSuccess()) {log.info("     ================= 发送成功.");} else {channelFuture.channel().close();log.info("     ================= 发送失败. cause = " + channelFuture.cause());channelFuture.cause().printStackTrace();}});} else {log.error("消息发送失败! textMsg = " + textMsg);}}}

参考:利用netty开发webScoketClient(支持wss协议,客户端、服务端心跳实现)_websocketclient-CSDN博客

相关文章:

基于Netty实现安全认证的WebSocket(wss)客户端

1.Netty服务端 服务端代码参考【基于Netty实现安全认证的WebSocket&#xff08;wss&#xff09;服务端-CSDN博客】 2.Netty客户端 客户端代码参考【基于Netty实现WebSocket客户端-CSDN博客】中两种都可以&#xff1b;这里用的是第一种。 新增SslHandler的代码&#xff1a; …...

代码随想录算法训练营第四十四天 | 01背包问题 二维、 01背包问题 一维、416. 分割等和子集

01背包问题 二维 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili 1.dp数组定义 dp[i][j] 下标为[0,i]之间的物品&…...

redis常见使用场景

文章目录 redis常见使用场景全局ID位统计购物车用户消息时间线timeline抽奖商品筛选分布式锁限流redis实现计数器排行榜消息队列redis 如何实现延时队列 redis生产常用的场景 redis常见使用场景 Redis 是一种高性能的内存数据库&#xff0c;广泛应用于各种场景中。以下是 Redi…...

模糊C均值(FCM)算法更新公式推导

模糊C均值&#xff08;FCM&#xff09;算法更新公式推导 目标函数 FCM的目标函数为&#xff1a; J m ∑ i 1 n ∑ j 1 k u i j m ∥ x i − c j ∥ 2 J_m \sum_{i1}^n \sum_{j1}^k u_{ij}^m \|x_i - c_j\|^2 Jm​i1∑n​j1∑k​uijm​∥xi​−cj​∥2 其中&#xff1a; …...

金融创新浪潮下的拆分盘投资探索

随着数字化时代的步伐加速&#xff0c;金融领域正经历着前所未有的变革。在众多金融创新中&#xff0c;拆分盘作为一种新兴的投资模式&#xff0c;以其独特的增长机制&#xff0c;吸引了投资者的广泛关注。本文将对拆分盘的投资逻辑进行深入剖析&#xff0c;并结合具体案例&…...

一份不知道哪里来的第十五届国赛模拟题

这是一个不知道来源的模拟题目&#xff0c;没有完全完成&#xff0c;只作代码记录&#xff0c;不作分析和展示&#xff0c;极其冗长&#xff0c;但里面有长按短按双击的复合&#xff0c;可以看看。 目录 题目代码底层驱动主程序核心代码关键&#xff1a;双击单击长按复合代码 …...

机器人动力学模型与MATLAB仿真

机器人刚体动力学由以下方程控制&#xff01;&#xff01;&#xff01; startup_rvc mdl_puma560 p560.dyn 提前计算出来这些“disturbance”&#xff0c;然后在控制环路中将它“抵消”&#xff08;有时候也叫前馈控制&#xff09; 求出所需要的力矩&#xff0c;其中M项代表克服…...

SAPUI5基础知识3 - 引导过程(Bootstrap)

1. 背景 在上一篇博客中&#xff0c;我们已经建立出了第一个SAPUI5项目&#xff0c;接下来&#xff0c;我们将为这个项目添加引导过程。 在动手练习之前&#xff0c;让我们先解释一下什么引导过程。 1.1 什么是引导过程&#xff1f; 在计算机科学中&#xff0c;引导过程也称…...

ABAP 借助公司封装的钉钉URL,封装的RFC给钉钉发送消息

FUNCTION ZRFC_BC_SMSSEND_DINGTALK. *"---------------------------------------------------------------------- *"*"本地接口&#xff1a; *" IMPORTING *" VALUE(DESTUSRID) TYPE CHAR255 *" VALUE(CONTENT) TYPE CHAR255 *&quo…...

登录校验及全局异常处理器

登录校验 会话技术 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束.在一次会话中可以包含多次请求和响应会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话请求间共享数据会话跟踪方案 客户端…...

计算机视觉与模式识别实验1-2 图像的形态学操作

文章目录 &#x1f9e1;&#x1f9e1;实验流程&#x1f9e1;&#x1f9e1;1.图像膨胀2.图像腐蚀3.膨胀与腐蚀的综合使用4.对下面二值图像的目标提取骨架&#xff0c;并分析骨架结构。 &#x1f9e1;&#x1f9e1;全部代码&#x1f9e1;&#x1f9e1; &#x1f9e1;&#x1f9e1…...

【前端每日基础】day31——uni-app

uni-app 开发详细介绍 基本概念 uni-app&#xff1a;uni-app 是一个使用 Vue.js 开发多端应用的框架&#xff0c;可以编译到微信小程序、支付宝小程序、百度小程序、字节跳动小程序、H5、App等多个平台。 跨平台&#xff1a;一次开发&#xff0c;多端部署。通过条件编译实现多…...

云动态摘要 2024-05-31

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [1.5折起]年中盛惠--AI分会场 腾讯云 2024-05-30 人脸核身、语音识别、文字识别、数智人、腾讯混元等热门AI产品特惠&#xff0c;1.5折起 云服务器ECS试用产品续用 阿里云 2024-04-14 云…...

Oracle数据块如何存储真实数据

上周休假了几天,颓废了,没有输出。今天写一点内容。 先抛出一个问题。表中的数据在Oracle数据块中是如何存储的呢?今天简单说一下这个问题。通常数据库中的表会存储字符,数字,日期 这3种常见的数据类型。下面的例子就用这3种数据类型作说明 首先,Oracle数据块底层存储这…...

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第30课-门的移动动画

【WEB前端2024】开源智体世界&#xff1a;乔布斯3D纪念馆-第30课-门的移动动画 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎…...

智能化改造给企业带来的实际效果

1. 提高生产效率&#xff1a;通过自动化和智能化的生产线&#xff0c;减少人工操作&#xff0c;显著提升单位时间内的生产量。 2. 提升产品质量&#xff1a;智能化改造通过精确控制生产过程&#xff0c;减少人为错误&#xff0c;提高产品的一致性和可靠性。 3. 降低生产成本&am…...

深度学习-语言模型

深度学习-语言模型 统计语言模型神经网络语言模型语言模型的应用序列模型&#xff08;Sequence Model&#xff09;语言模型&#xff08;Language Model&#xff09;序列模型和语言模型的区别 语言模型&#xff08;Language Model&#xff09;是自然语言处理&#xff08;NLP&…...

微型导轨在自动化制造中有哪些优势?

微型导轨在自动化制造中发挥重要作用&#xff0c;能够满足自动化设备制造中对精度要求较高的工艺环节。适用于自动装配线、自动检测设备和机器人操作等环节&#xff0c;推动了行业的进步与发展。那么&#xff0c;微型导轨在使用中有哪些优势呢&#xff1f; 1、精度高和稳定性强…...

探索气象数据的多维度三维可视化:PM2.5、风速与高度分析

探索气象数据的多维度可视化&#xff1a;PM2.5、风速与高度分析 摘要 在现代气象学中&#xff0c;数据可视化是理解复杂气象模式和趋势的关键工具。本文将介绍一种先进的数据可视化技术&#xff0c;它能够将PM2.5浓度、风速和高度等多维度数据以直观和动态的方式展现出来。 …...

【传知代码】双深度学习模型实现结直肠癌检测(论文复现)

前言&#xff1a;在医学领域&#xff0c;科技的进步一直是改变人类生活的关键驱动力之一。随着深度学习技术的不断发展&#xff0c;其在医学影像诊断领域的应用正日益受到关注。结直肠癌是一种常见但危害极大的恶性肿瘤&#xff0c;在早期发现和及时治疗方面具有重要意义。然而…...

平衡二叉树的应用举例

AVL 是一种自平衡二叉搜索树&#xff0c;其中任何节点的左右子树的高度之差不能超过 1。 AVL树的特点&#xff1a; 1、它遵循二叉搜索树的一般属性。 2、树的每个子树都是平衡的&#xff0c;即左右子树的高度之差最多为1。 3、当插入新节点时&#xff0c;树会自我平衡。因此…...

一键安装 HaloDB 之 Ansible for Halo

↑ 关注“少安事务所”公众号&#xff0c;欢迎⭐收藏&#xff0c;不错过精彩内容~ 前倾回顾 前面介绍了“光环”数据库的基本情况和安装办法。 哈喽&#xff0c;国产数据库&#xff01;Halo DB! 三步走&#xff0c;Halo DB 安装指引 以及 HaloDB 的 Oracle 和 MySQL 兼容模式: …...

el-table的上下筛选功能

el-table的sort-change事件可以监听到筛选的事件&#xff1b; 会返回prop属性和order排序的顺序&#xff1b; html&#xff1a; <el-table :data"tableData" border style"width: 100%" :cell-style"{ textAlign: center }"header-cell-c…...

【手撕面试题】Vue(高频知识点一)

每天10道题&#xff0c;100天后&#xff0c;搞定所有前端面试的高频知识点&#xff0c;加油&#xff01;&#xff01;&#xff01;&#xff0c;在看文章的同时&#xff0c;希望不要直接看答案&#xff0c;先思考一下自己会不会&#xff0c;如果会&#xff0c;自己的答案是什么&…...

LabVIEW车轮动平衡检测系统

LabVIEW车轮动平衡检测系统 随着汽车行业的快速发展&#xff0c;车轮动平衡问题对乘坐舒适性、操控稳定性及安全性的影响日益凸显&#xff0c;成为了提高汽车性能的一个关键环节。传统的检测系统因精度低、成本高、操作复杂等问题&#xff0c;难以满足现代汽车行业的需求。开发…...

【Python爬虫--scrapy+selenium框架】超详细的Python爬虫scrapy+selenium框架学习笔记(保姆级别的,非常详细)

六&#xff0c;selenium 想要下载PDF或者md格式的笔记请点击以下链接获取 python爬虫学习笔记点击我获取 Scrapyselenium详细学习笔记点我获取 Python超详细的学习笔记共21万字点我获取 1&#xff0c;下载配置 ## 安装&#xff1a; pip install selenium## 它与其他库不同…...

【Linux】Linux环境基础开发工具_3

文章目录 四、Linux环境基础开发工具2. vim3. gcc和g动静态库的理解 未完待续 四、Linux环境基础开发工具 2. vim vim 怎么批量化注释呢&#xff1f;最简单的方法就是在注释开头和结尾输入 /* 或 */ 。当然也可以使用快捷键&#xff1a; Ctrl v 按 hjkl 光标移动进行区域选择…...

数字水印 | 图像噪声攻击(高斯/椒盐/泊松/斑点)

目录 Noise Attack1 高斯噪声&#xff08;Gaussian Noise&#xff09;2 椒盐噪声&#xff08;Salt and Pepper Noise&#xff09;3 泊松噪声&#xff08;Poisson Noise&#xff09;4 斑点噪声&#xff08;Speckle Noise&#xff09;5 完整代码 参考博客&#xff1a;Python…...

LeetCode-47 全排列Ⅱ

LeetCode-47 全排列Ⅱ 题目描述解题思路代码说明 题目描述 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 &#xff1a; 输入&#xff1a;nums [1,1,2]输出&#xff1a; [[1,1,2], [1,2,1], [2,1,1]] b站题目解读讲的不好&…...

list 的实现

目录 list 结点类 结点类的构造函数 list的尾插尾删 list的头插头删 迭代器 运算符重载 --运算符重载 和! 运算符重载 * 和 -> 运算符重载 list 的insert list的erase list list实际上是一个带头双向循环链表,要实现list,则首先需要实现一个结点类,而一个结点需要…...