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

Vert.x学习笔记

文章目录

  • 一、概述
    • 1、官网
  • 二、vertx-core
    • 0、导包
    • 1、hello world
    • 2、Verticle
      • (1)参考
      • (2)示例
    • 3、eventBus事件总线
      • (1)hello world
      • (2)消费确认回复
    • 4、Json处理
      • (1)常用方法
      • (2)不确定类型转换
    • 5、Buffer操作
    • 6、TCP客户端与服务端
      • (1)demo
    • 7、Http客户端与服务端
  • 三、vertx-web
    • 0、导包
    • 1、使用
  • 【重磅推荐!免费简单内网穿透神器!支持linux+windows】

一、概述

1、官网

https://vertx.io/

二、vertx-core

0、导包

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>4.5.10</version>
</dependency>

1、hello world

package com.vertx;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.file.FileProps;
import io.vertx.core.file.FileSystem;

import java.util.concurrent.CompletableFuture;

public class Test {


    public static void main(String[] args) {

        // 创建一个Vertx实例
        VertxOptions options = new VertxOptions()
                .setWorkerPoolSize(40);
        Vertx vertx = Vertx.vertx(options);

        // 每秒执行一次
        vertx.setPeriodic(1000, id -> {
            System.out.println("timer fired!");
        });

        // 完全都是异步的,
        FileSystem fs = vertx.fileSystem();
        Future<FileProps> future = fs.props("D:\\example.db");
        future.onComplete((AsyncResult<FileProps> ar) -> {
            if (ar.succeeded()) {
                FileProps props = ar.result();
                System.out.println("File size = " + props.size());
            } else {
                System.out.println("Failure: " + ar.cause().getMessage());
            }
        });
        // 操作链
        Future<Void> future2 = fs
            .createFile("D:\\foo")
            .compose(v -> {
                // 当文件foo创建完之后执行,同时返回一个Future
                return fs.writeFile("D:\\foo", Buffer.buffer());
            })
            .compose(v -> {
                // 当文件foo创建完之后执行,同时返回一个Future
                return fs.move("D:\\foo", "D:\\bar");
            });
        // 所有都成功
        Future.all(future, future2).onComplete(ar -> {
            if (ar.succeeded()) {
                // All servers started

            } else {
                // At least one server failed
            }
        });

        // CompletableFuture与Vertx的Future可以转换
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {});
        Future.fromCompletionStage(voidCompletableFuture, vertx.getOrCreateContext())
                .onSuccess(str -> {
                    System.out.println("We have a result: " + str);
                })
                .onFailure(err -> {
                    System.err.println("We have a problem");
                    err.printStackTrace();
                });
        // 互相转换
        future.toCompletionStage().whenComplete((r, t) -> {});
    }
}

2、Verticle

(1)参考

https://blog.csdn.net/zhangzehai2234/article/details/134215914

(2)示例

import io.vertx.core.AbstractVerticle;

public class BaseVerticle extends AbstractVerticle {

    @Override
    public void start() {
        System.out.println(("Start"));
    }

    @Override
    public void stop() {
        System.out.println(("Stop"));
    }
}
import io.vertx.core.AbstractVerticle;

public class MyVerticle extends AbstractVerticle {


    @Override
    public void start() {
        long delay = 1000;
        for (int i = 0; i < 50; i++) {
            vertx.setTimer(delay, id -> deploy());  // 每隔1秒部署一个 BaseVerticle 实例
            delay = delay + 1000;
        }
    }

    private void deploy() {
        vertx.deployVerticle(new BaseVerticle(), ar -> {   // vertx中的Vertcle的部署是一个异步的操作,所以这里使用带异步结果的异步方法来进行部署,部署成功会生成一个唯一的Verticle ID
            if (ar.succeeded()) {
                String id = ar.result();
                System.out.println(("Successfully deployed " + id));
                vertx.setTimer(5000, tid -> undeployLater(id));   // Verticle部署成功5秒以后就卸载该实例
            } else {
                System.out.println(("Error while deploying" + ar.cause()));
            }
        });
    }

    private void undeployLater(String id) {
        vertx.undeploy(id, ar -> {  //卸载的过程和部署的过程类似,也是一个异步的操作
            if (ar.succeeded()) {
                System.out.println(("{} was undeployed" + id));
            } else {
                System.out.println(("{} could not be undeployed" + id));
            }
        });
    }
}

import io.vertx.core.Vertx;

public class Test {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new MyVerticle());
    }

}

3、eventBus事件总线

(1)hello world


import io.vertx.core.Vertx;
import io.vertx.core.eventbus.DeliveryOptions;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.MessageConsumer;

import java.util.Arrays;

public class Test {


    public static void main(String[] args) {

        // 创建一个Vertx实例
        Vertx vertx = Vertx.vertx();

        // 一个vertx有一个eventBus实例
        EventBus eventBus = vertx.eventBus();
        // 创建一个消费者,address + message,也可以简写 eb.consumer("news.uk.sport", message -> {})
        MessageConsumer<Object> consumer = eventBus.consumer("VERTX://MY/TEST");
        consumer.handler(message -> {
            System.out.println("message: " + message.body());
        });
        // consumer.unregister(); // 取消注册
        eventBus.consumer("VERTX://MY/TEST", message -> {
            System.out.println("message2: " + message.body());
        });


        // 指定address就可以发送事件消息,所有注册这个地址的消费者都会收到该消息
        eventBus.publish("VERTX://MY/TEST", "hello world");

        // 只收到一次,相当于消费者做了负载均衡,可以发送任意Object类型
        eventBus.send("VERTX://MY/TEST", "hello world2");
        eventBus.send("VERTX://MY/TEST", "hello world3");
        eventBus.send("VERTX://MY/TEST", Arrays.asList("hello world4", "hello world5"));


        // 可以设置header,消费者也可以接收header
        // DeliveryOptions options = new DeliveryOptions();
        // options.addHeader("some-header", "some-value");
        // eventBus.send("VERTX://MY/TEST", "Yay! Someone kicked a ball", options);
        
    }
}

(2)消费确认回复

import io.vertx.core.Vertx;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.MessageConsumer;

public class Test {


    public static void main(String[] args) {

        // 创建一个Vertx实例
        Vertx vertx = Vertx.vertx();

        // 一个vertx有一个eventBus实例
        EventBus eventBus = vertx.eventBus();
        MessageConsumer<String> consumer = eventBus.consumer("news.uk.sport");
        consumer.handler(message -> {
            System.out.println("收到消息: " + message.body());
            // 消费回复
            message.reply("我处理完消息了");
        });

        eventBus
                .request("news.uk.sport", "我发送了一条消息")
                .onComplete(ar -> {
                    // 判断是否消费成功,消费者调用reply之后会调用
                    if (ar.succeeded()) {
                        System.out.println("消费成功: " + ar.result().body());
                    }
                });


    }
}

4、Json处理

(1)常用方法

Json处理默认是用的Jackson库,更详细的操作可以查阅Jackson库的操作。

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.HashMap;
import java.util.Map;

public class Test {

    static class User {
        private String id;

        private String name;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }


    public static void main(String[] args) {

        String jsonString = "{\"foo\":\"bar\"}";
        // 字符串转json对象
        JsonObject object = new JsonObject(jsonString);
        // 根据key取值
        System.out.println(object.getString("foo"));
        //String val = object.getString("some-key");
        //int intVal = object.getInteger("some-other-key");

        // 根据map生成JsonObject对象
        Map<String, Object> map = new HashMap<>();
        map.put("foo", "bar");
        map.put("xyz", 3);
        JsonObject object2 = new JsonObject(map);

        // 可以手动放key-value
        JsonObject object3 = new JsonObject();
        object3.put("foo", "bar").put("num", 123).put("mybool", true);

        // 转成实体类
        JsonObject objectUser = new JsonObject();
        objectUser.put("id", "123").put("name", "zhangsan");
        User user = objectUser.mapTo(User.class);
        System.out.println(user.getId());

        // 实体类转JsonObject
        JsonObject jsonObjectMapFrom = JsonObject.mapFrom(user);
        System.out.println(jsonObjectMapFrom.getString("id"));

        // 数组操作
        JsonArray jsonArray = new JsonArray();
        jsonArray.add("foo").add(123).add(false);

        // 字符串转json数组
        String jsonArrayString = "[\"foo\",\"bar\"]";
        JsonArray array = new JsonArray(jsonArrayString);

        // 从数组取值
        String val = array.getString(0);
        Integer intVal = array.getInteger(1);
        Boolean boolVal = array.getBoolean(2);

    }
}

(2)不确定类型转换

可以使用Json.decodeValue转换为Object之后,再进行类型判断。


// 不确定的类型转换
Object indeterminacyObject = Json.decodeValue("arbitraryJson");
if (indeterminacyObject instanceof JsonObject) {
    // That's a valid json object
} else if (indeterminacyObject instanceof JsonArray) {
    // That's a valid json array
} else if (indeterminacyObject instanceof String) {
    // That's valid string
} else {
    // etc...
}

5、Buffer操作

import io.vertx.core.buffer.Buffer;

public class BufferTest {

    public static void main(String[] args) {

        // 创建空buffer,并指定缓冲区大小
        Buffer buff = Buffer.buffer(1000);

        // 根据字符串创建buffer,默认utf-8
        Buffer buff2 = Buffer.buffer("some string");

        // 指定编码格式
        Buffer buff3 = Buffer.buffer("some string", "UTF-16");

        // 从byte数组创建Buffer
        byte[] bytes = new byte[] {1, 3, 5};
        Buffer buff4 = Buffer.buffer(bytes);

        // 追加buffer
        buff.appendInt(123).appendString("hello\n");
        socket.write(buff);

        // 指定索引写入数据
        buff.setInt(1000, 123);
        buff.setString(0, "hello");

        // 读取Buffer
        for (int i = 0; i < buff.length(); i += 4) {
            System.out.println("int value at " + i + " is " + buff.getInt(i));
        }

        int pos = 15;
        buff.setUnsignedByte(pos, (short) 200);
        System.out.println(buff.getUnsignedByte(pos));

        // 获取缓冲区长度,缓冲区的长度是缓冲区中索引最大的字节的索引+ 1。
        System.out.println(buff.length());
    }
}

6、TCP客户端与服务端

TCP支持限流、SSL等高级操作。

(1)demo

import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetServer;
import io.vertx.core.net.NetServerOptions;

public class ServerTest {



    public static void main(String[] args) {

        Vertx vertx = Vertx.vertx();
        // 创建TCP服务端,进行部分设置
        NetServerOptions options = new NetServerOptions()
                .setPort(8000);
        NetServer server = vertx.createNetServer(options);

        // 客户端连接
        server.connectHandler(socket -> {
            // 客户端连接成功会调用
            System.out.println("连接成功");

            // 连接关闭
            socket.closeHandler(v -> {
                System.out.println("连接关闭");
            });
        });

        // 数据接收和写出
        server.connectHandler(socket -> {
            socket.handler(buffer -> {
                // 数据接收的操作,需要用Buffer进行操作
                System.out.println("I received some bytes: " + buffer.length());

                // 数据写出,都是异步操作
                Buffer writeBuffer = Buffer.buffer().appendFloat(12.34f).appendInt(123);
                socket.write(writeBuffer);
                // 默认UTF-8编码
                socket.write("some data");
                // 使用指定的编码编写字符串
                socket.write("some data", "UTF-16");

                // 直接发送文件,零拷贝
                //socket.sendFile("myfile.dat");
            });


        });


        // 开始监听
        server.listen();
        // 可以监听指定主机
        // server.listen(1234, "localhost");

        // 如果将0用作监听端口,服务器将找到一个未使用的随机端口进行监听。要找出服务器监听的真正端口,可以调用actualPort。
//        server
//                .listen(0, "localhost")
//                .onComplete(res -> {
//                    if (res.succeeded()) {
//                        System.out.println("Server is now listening on actual port: " + server.actualPort());
//                    } else {
//                        System.out.println("Failed to bind!");
//                    }
//                });


        // 关闭服务器
//        server
//                .close()
//                .onComplete(res -> {
//                    if (res.succeeded()) {
//                        System.out.println("Server is now closed");
//                    } else {
//                        System.out.println("close failed");
//                    }
//                });

    }
}

import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.*;

public class ClientTest {

    public static void main(String[] args) {

        Vertx vertx = Vertx.vertx();
        // 创建TCP服务端,进行部分设置
        NetClientOptions options = new NetClientOptions()
                .setConnectTimeout(10000).
                // 设置重连
                setReconnectAttempts(10).
                setReconnectInterval(500);
        NetClient client = vertx.createNetClient(options);

        client
                .connect(8000, "localhost")
                .onComplete(res -> {
                    if (res.succeeded()) {
                        System.out.println("连接成功!");
                        NetSocket socket = res.result();
                        // 发送数据
                        socket.write("some data client");
                        // 接收数据
                        socket.handler(buffer -> {
                            // 数据接收的操作,需要用Buffer进行操作
                            System.out.println("client received some bytes: " + buffer.length());
                        });
                    } else {
                        System.out.println("连接失败: " + res.cause().getMessage());
                    }
                });
    }
}

7、Http客户端与服务端

看到https://vertx.io/docs/vertx-core/java/#_verticles

三、vertx-web

0、导包

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web</artifactId>
    <version>4.5.10</version>
</dependency>

1、使用

https://vertx.io/docs/vertx-web/java/
vertx使用起来或许性能会强一些?但是终归生态不如springboot的,用起来还是挺麻烦

【重磅推荐!免费简单内网穿透神器!支持linux+windows】

推荐内网穿透神器【cpolar】https://www.cpolar.com/
点击【免费注册】之后,输入自己的个人信息就可以注册一个账号啦!
本地web项目如何使用外网访问?教你轻松使用cpolar在windows搭建内网穿透
linux虚拟机部署的web项目如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透
linux虚拟机部署的MySQL如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透


http://www.kler.cn/news/364639.html

相关文章:

  • HttpContext模块 --- http上下文模块
  • [C++进阶数据结构]红黑树(半成品)
  • 跨平台 OTT 项目使用 Google Analytics 替代 KPI log
  • VSCode编译器改为中文
  • vue3移动端可同时上传照片和视频的组件
  • C#中的委托、匿名方法、Lambda、Action和Func
  • Eclipse中继承自Collection<Object>的示例
  • 【三十七】【QT开发应用】使用QVideoWidget播放视频,QT模块缺失时更新安装模块步骤(利用虚拟网址打开应用加速)
  • 架构师考试系列(6)论文专题:论分布式架构设计
  • Mac虚拟机, 在Win的Linux子系统的Docker里运行MacOS,操作系统大套娃
  • H5实现PDF文件预览,使用pdf.js-dist进行加载
  • Mac 出现zsh: command not found: aapt
  • 敏捷开发实践:SpringBoot房屋租赁管理系统
  • HivisionIDPhoto Docker部署以及Springboot接口对接(AI证件照制作)
  • 开源数据库 - mysql - 体系结构与组件
  • 京准电钟HR-901GB双GPS北斗卫星时钟服务器
  • C++桂城 2022.六年级.02.最小的数
  • 什么是单片机?
  • cesium相机(camera)控制
  • 高并发负载均衡——nginx与lvs
  • C++研发笔记4——C语言程序设计初阶学习笔记2
  • 技术成神之路:设计模式(二十一)外观模式
  • Windows图形界面(GUI)-QT-C/C++ - QT基本概念 - 安装配置 - QT Creator
  • 07 设计模式-结构型模式-桥接模式
  • uniapp实现多文件下载,保存到本地
  • 【数字信号处理】三种频率(f,Ω,ω)的关系(未完)