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
server.connectHandler
服务端创建连接后的操作socket.writeHandlerID()
获取clientid
socket.handler
接收客户端发送的消息vertx.setPeriodic
设置定时器 通过定时器,服务端主动定时给服务端发送消息socket.closeHandler
监测客户端是否断开连接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
创建客户端
client.connect
客户端进行连接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());}
}