物联网之使用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,实际生产中,比较复杂,会出现粘包和拆包,需要自定义相关规则

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

相关推荐
liulilittle10 小时前
删除 Inflight Bounds:为什么 KCC 放弃了 BDP 钳位
linux·网络·tcp/ip·计算机网络·信息与通信·tcp·通信
liulilittle2 天前
TCP KCC v1.0(卡尔曼拥塞控制)
linux·服务器·网络·tcp/ip·计算机网络·tcp·通信
金融支付架构实战指南2 天前
Java Socket 全网read/write底层原理 + 避坑实战
socket·tcp·write·listen·connect
liulilittle2 天前
用户态 TCP 端口转发:对 CUBIC 友好,对 BBR/KCC 收益不大
运维·网络·tcp/ip·计算机网络·信息与通信·tcp·通信
liulilittle3 天前
关于拥塞控制的几点思考
网络·c++·tcp/ip·计算机网络·信息与通信·tcp·通信
liulilittle3 天前
过冲:拥塞控制的呼吸与盲行
linux·网络·c++·tcp/ip·计算机网络·tcp·通信
liulilittle3 天前
拥塞控制:公平性的不可能三角
网络·c++·网络协议·tcp/ip·计算机网络·tcp·通信
liulilittle3 天前
什么是“单流”?一个服务器上能不能同时存在多个“单流”?
服务器·网络·tcp/ip·计算机网络·信息与通信·tcp·通信
Irissgwe3 天前
7、传输层协议 TCP
网络·网络协议·tcp/ip·tcp·三次握手·四次挥手
liulilittle4 天前
我从 BBRv1 到 KCC 的思考
网络·c++·tcp/ip·计算机网络·tcp·bbr·通信