物联网之使用Vertx实现TCP最佳实践【响应式】

小伙伴们,你们好呀,我是老寇,跟我一起学习使用Vertx实现TCP-Server

实现TCP-Server【响应式】

Vertx-Core地址

实现过程

查看源码

代码比较简单,懒得讲解啦
代码比较简单,懒得讲解啦
代码比较简单,懒得讲解啦
tcp-server【响应式】
xml 复制代码
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-core</artifactId>
  <version>5.0.0</version>
</dependency>

VertxConfig

java 复制代码
/**
 * @author laokou
 */
@Configuration
public class VertxConfig {

    @Bean(destroyMethod = "close")
    public Vertx vertx() {
       VertxOptions vertxOptions = new VertxOptions();
       vertxOptions.setMaxEventLoopExecuteTime(30);
       vertxOptions.setWorkerPoolSize(40);
       vertxOptions.setMaxWorkerExecuteTime(30);
       vertxOptions.setMaxEventLoopExecuteTimeUnit(TimeUnit.SECONDS);
       vertxOptions.setMaxWorkerExecuteTimeUnit(TimeUnit.SECONDS);
       vertxOptions.setPreferNativeTransport(true);
       vertxOptions.setInternalBlockingPoolSize(40);
       vertxOptions.setEventLoopPoolSize(Math.max(32, 2 * CpuCoreSensor.availableProcessors()));
       return Vertx.vertx(vertxOptions);
    }

}

TcpServerProperties

java 复制代码
/**
 * @author laokou
 */
@Data
@Component
@ConfigurationProperties(prefix = "spring.tcp-server")
public class TcpServerProperties {

    private String host = "0.0.0.0";

    private Set<Integer> ports = new HashSet<>(0);

    private int acceptBacklog = -1;

    private ClientAuth clientAuth = ClientAuth.NONE;

    private boolean sni = false;

    private boolean useProxyProtocol = false;

    private long proxyProtocolTimeout = 30L;

    private TimeUnit proxyProtocolTimeoutUnit = TimeUnit.SECONDS;

    private boolean registerWriteHandler = false;

}

VertxTcpServer

java 复制代码
/**
 * @author laokou
 */
@Slf4j
final class VertxTcpServer extends AbstractVerticle {

    private final TcpServerProperties properties;

    private final Vertx vertx;

    private volatile Flux<NetServer> netServer;

    private boolean isClosed = false;

    VertxTcpServer(Vertx vertx, TcpServerProperties properties) {
       this.vertx = vertx;
       this.properties = properties;
    }

    @Override
    public synchronized void start() {
       netServer = getTcpServerOptions().map(vertx::createNetServer)
          .doOnNext(server -> server.connectHandler(socket -> {
             socket.handler(buffer -> log.info("【Vertx-Tcp-Server】 => 接收数据:{}", buffer.toString()))
                .closeHandler(close -> log.info("【Vertx-Tcp-Server】 => 连接关闭"));
          }).listen().onComplete(result -> {
             if (isClosed) {
                return;
             }
             if (result.succeeded()) {
                log.info("【Vertx-Tcp-Server】 => TCP服务启动成功,端口:{}", result.result().actualPort());
             }
             else {
                Throwable ex = result.cause();
                log.error("【Vertx-Tcp-Server】 => TCP服务启动失败,错误信息:{}", ex.getMessage(), ex);
             }
          }));
       netServer.subscribeOn(Schedulers.boundedElastic()).subscribe();
    }

    @Override
    public synchronized void stop() {
       isClosed = true;
       netServer.doOnNext(server -> server.close().onComplete(result -> {
          if (result.succeeded()) {
             log.info("【Vertx-Tcp-Server】 => HTTP服务停止成功,端口:{}", server.actualPort());
          }
          else {
             Throwable ex = result.cause();
             log.error("【Vertx-Tcp-Server】 => HTTP服务停止失败,错误信息:{}", ex.getMessage(), ex);
          }
       })).subscribeOn(Schedulers.boundedElastic()).subscribe();
    }

    public void deploy() {
       // 部署服务
       vertx.deployVerticle(this);
       // 停止服务
       Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
    }

    private Flux<NetServerOptions> getTcpServerOptions() {
       return Flux.fromIterable(properties.getPorts()).map(this::getTcpServerOption);
    }

    private NetServerOptions getTcpServerOption(int port) {
       NetServerOptions options = new NetServerOptions();
       options.setHost(properties.getHost());
       options.setPort(port);
       options.setClientAuth(properties.getClientAuth());
       options.setSni(properties.isSni());
       options.setUseProxyProtocol(properties.isUseProxyProtocol());
       options.setProxyProtocolTimeout(properties.getProxyProtocolTimeout());
       options.setProxyProtocolTimeoutUnit(properties.getProxyProtocolTimeoutUnit());
       options.setRegisterWriteHandler(properties.isRegisterWriteHandler());
       options.setAcceptBacklog(properties.getAcceptBacklog());
       return options;
    }

}

这个只是一个demo,实际生产中,比较复杂,会出现粘包和拆包,需要自定义相关规则

我是老寇,我们下次再见啦!

相关推荐
阿巴~阿巴~2 小时前
“可达”方能“可靠”:深入解析网络层在TCP通信中的基石作用
运维·服务器·网络·网络协议·tcp/ip·ip·tcp
阿巴~阿巴~10 小时前
路由的本质:从逐跳转发到全球互联的决策机制解析
网络·网络协议·tcp/ip·智能路由器·ip·tcp·路由
阿巴~阿巴~12 小时前
私网与公网的协同之道:NAT、IP架构与互联网连接全景解析
网络·网络协议·tcp/ip·架构·ip·tcp·公网私网ip
阿巴~阿巴~3 天前
TCP可靠传输的底层密码:序号、窗口与六大标志位全解析
运维·服务器·网络·tcp·序列号·六大标志位·确认序号
阿巴~阿巴~3 天前
TCP性能优化秘籍:延迟应答、捎带确认与粘包破解之道
运维·服务器·网络·网络协议·udp·tcp
阿巴~阿巴~3 天前
从滑动窗口到拥塞控制:TCP高效可靠传输的三大支柱
服务器·网络·网络协议·tcp·滑动窗口·流量控制·拥塞控制
阿巴~阿巴~3 天前
TCP可靠传输双引擎:确认应答与超时重传的精妙协同
运维·服务器·网络·网络协议·tcp·超时重传·确认应答
chenyuhao20245 天前
Linux网络编程:TCP协议
linux·运维·服务器·网络协议·tcp/ip·udp·tcp
西幻凌云6 天前
TCP 解析:头部格式、三次握手与四次挥手
网络协议·tcp/ip·udp·tcp·三次握手·四次挥手·传输层
不染尘.8 天前
TCP拥塞控制
服务器·网络·计算机网络·tcp