入门级 使用 vertx进行tcp 开发 spring boot整合vertx开发tcp

news/2024/11/25 7:56:33/

Vertx 简介

准备

软件下载
网络调试工具

创建Spring boot 项目

导入依赖

<!--   vertx tcp开发依赖     -->
<dependency><groupId>io.vertx</groupId><artifactId>vertx-core</artifactId><version>4.3.1</version>
</dependency><!--   spring boot 依赖   --><dependency>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</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-data-redis</artifactId>
</dependency><!--   其他工具类依赖     --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.11</version>
</dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.8.graal</version>
</dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.25</version>
</dependency>

创建tcpServer

  1. server.connectHandler 服务端创建连接后的操作
  2. socket.writeHandlerID() 获取 clientid
  3. socket.handler 接收客户端发送的消息
  4. vertx.setPeriodic 设置定时器 通过定时器,服务端主动定时给服务端发送消息
  5. socket.closeHandler 监测客户端是否断开连接
  6. server.listen 监听指定的端口号,启动TcpServer

使用 vertx.createNetServer 创建 netServer

当客户端连入后,服务端会通过配置的定时发送消息,给客户端发送消息,客户端断开连接后,会通过socket.closeHandler 监测,检测到取消定时器,不再向客户端发送消息

package com.example.socketdemo.socket5;import cn.hutool.core.util.CharsetUtil;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetServer;
import io.vertx.core.net.NetServerOptions;
import lombok.extern.slf4j.Slf4j;import java.time.LocalDateTime;@Slf4j
public class VertxTCPServer extends AbstractVerticle {@Overridepublic void start() {// 可以配置 ip 端口号NetServerOptions netServerOptions = new NetServerOptions().setPort(9090).setHost("127.0.0.1");// 创建TCP服务器NetServer server = vertx.createNetServer(netServerOptions);// 处理连接请求server.connectHandler(socket -> {String handlerID = socket.writeHandlerID();System.out.println("服务端id" + handlerID);// 接收客户端发送的消息socket.handler(buff -> {System.out.println("RECV: " + buff.length());// 需要回复消息可以在这发送socket.write(Buffer.buffer("TcpServer Receive -=== Hello Vertx from Server!"));});// 创建服务端发送消息定时器long id = vertx.setPeriodic(10000, res -> {socket.write(Buffer.buffer("Hello Vertx from Server!......"), ar -> {if (ar.succeeded()) {socket.handler(buffer -> {// 在这里应该解析报文,封装为协议对象,并找到响应的处理类,得到处理结果,并响应log.info("TcpServer接收到的数据为:" + buffer.toString(CharsetUtil.CHARSET_GBK) + " " + LocalDateTime.now());//todo  收到客户端消息后做其他操作});} else {log.error("写入数据失败!");// todo 发送给客户端消息失败 记录日志或其他操作}});});// 监听客户端的退出连接socket.closeHandler(close -> {System.out.println("客户端退出连接"+ socket.writeHandlerID());// 取消定时器  不再向退出连接的客户端发送信息vertx.cancelTimer(id);});});// 监听端口server.listen(9090, "127.0.0.1", res -> {if (res.succeeded()) {log.info(" 服务器启动成功");} else {log.error(" 服务器启动失败 {}", res.cause().getMessage());}});}public static void main(String[] args) {// 启动服务端   spring boot 可以使用 ApplicationRunner 启动Vertx.vertx().deployVerticle(new VertxTCP2Server());}
}

在这里插入图片描述

注意 这里有两个 socket.handler 接收消息的方法,客户端创建连接后第一个,定时器里面第二个,第一个接收创建连接后的第一条消息,可以理解为注册包, 后面客户端发送的消息都在第二个 socket.handler 接收

启动完服务端之后,我们可以通过 网络调试助手 启动客户端,进行消息发送接收测试
使用 public static void main 进行简单的启动测试
整合spring Boot 可以使用 ApplicationRunner 代码如下

@Component
public class ThreadApplicationRuner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {Vertx.vertx().deployVerticle(new VertxTCP2Server());}
}

创建 TcpClient

使用 vertx.createNetClient 创建客户端

  1. client.connect 客户端进行连接
  2. socket.handler 连接成功后 接收客户端消息

启动同 TcpServer 可以使用 ApplicationRunner

package com.example.socketdemo.socket5;import cn.hutool.core.util.CharsetUtil;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;import java.time.LocalDateTime;@Slf4j
public class VertxTCPClient extends AbstractVerticle {@Overridepublic void start() {NetClientOptions options = new NetClientOptions().setConnectTimeout(10000);NetClient client = vertx.createNetClient(options);client.connect(11203, "192.168.2.141", res -> {if (res.succeeded()) {System.out.println("Connected!");NetSocket socket = res.result();socket.handler(buffer -> {
//                    // 在这里应该解析报文,封装为协议对象,并找到响应的处理类,得到处理结果,并响应log.info("tcpClient 接收到的数据为:" + buffer.toString(CharsetUtil.CHARSET_GBK) + " " + LocalDateTime.now());
//                    String heartStr = HexUtil.encodeHexStr(buffer.toString(CharsetUtil.CHARSET_GBK).getBytes(CharsetUtil.CHARSET_GBK)).toUpperCase();
//                    System.out.println("接收到的数据为 -HEX:" + HexUtil.encodeHexStr(buffer.toString(CharsetUtil.CHARSET_GBK).getBytes(CharsetUtil.CHARSET_GBK)).toUpperCase());// 收到客户端消息后回复客户端信息socket.write(Buffer.buffer("tcpClient send ====> Hello Vertx from Server!"));});} else {System.out.println("Failed to connect: " + res.cause().getMessage());}});}public static void main(String[] args) {Vertx.vertx().deployVerticle(new VertxTCPClient());}
}

http://www.ppmy.cn/news/82522.html

相关文章

微信小程序-页面生命周期方法

在经过上一篇文章的介绍之后&#xff0c;我们知道了大体的生命周期在什么时候执行&#xff0c;这次主要是以代码的形式来展示一下具体的阶段执行什么生命周期方法。 首先我们编写一个代码可以从首页跳转到日志页面&#xff1a; <!--index.wxml--> <text>首页</t…

51单片机四路开关电路+限位开关

#include <reg51.h> #include <intrins.h> unsigned char tmp; void send_char(unsigned char txd); void delay(unsigned int k); sbit key1 P1^0; sbit key2 P1^1; sbit key3 P1^2; sbit key4 P1^3; sbit key21 P2^1; // 限位开关1 zgf sbit key22 P2^2…

企业选择CRM系统的三个好处

跟随着全面放开的脚步&#xff0c;国内经济正在强势复苏&#xff0c;每家企业都在抢订单、找客户&#xff0c;想要提高企业竞争力还是要借助CRM客户管理系统&#xff0c;CRM系统客户信息管理的价值有哪些&#xff1f;从哪些方面助力企业发展。 一、高效率的管理线索 1.便捷录…

【Error】Python3.7 No module named ‘_sqlite3‘ 解决方案

场景&#xff1a;docker容器运行keybert时出现错误 No module named ‘_sqlite3‘&#xff0c;是容器环境没有sqlite的库&#xff0c;如下图所示&#xff1a; 本机是能够正常导入sqlite3的&#xff0c;虚拟环境conda下也有该库。 python3.8版本的不可用于python3.7中&#xff0…

C++基础容器 -- C的数组和字符串和C++的数组和字符串

文章目录 C基础容器序列型容器数组off-by-one error&#xff08;差一错误&#xff09;数组的增删改查二维数组的访问 动态数组 std::vectorvector插入操作vector删除操作 字符串和字符数组Unicode编码字符串的指针表示方法字符串的常见操作字符串操作的问题 C中的std::string C…

【实践篇】领域驱动设计:DDD工程参考架构 | 京东云技术团队

背景 为什么要制定参考工程架构 不同团队落地DDD所采取的应用架构风格可能不同&#xff0c;并没有统一的、标准的DDD工程架构。有些团队可能遵循经典的DDD四层架构&#xff0c;或改进的DDD四层架构&#xff0c;有些团队可能综合考虑分层架构、整洁架构、六边形架构等多种架构…

Activity的onCreate方法是怎样被调用的?

Activity的onCreate方法是怎样被调用的&#xff1f; 按前面源码分析的介绍&#xff0c;在Activity的onCreate方法中&#xff0c;添加如下的log&#xff1a; android.util.Log.i("wztest", "Activity onCreate", new Exception());重新编译后&#xff0c;…

GC之查看GC日志

写在前面 本文一起看下如何查看GC日志。 1&#xff1a;环境准备 为了能更模拟真实的业务环境生成GC日志&#xff0c;我们首先来准备一个测试类&#xff0c;详细的注释已经在代码中&#xff0c;如下&#xff1a; import java.util.Random; import java.util.concurrent.TimeU…