Python máy chủ udp đa luồng

Chức năng trong lõi ở mức khá thấp - bạn sẽ không tìm thấy những thứ như quyền truy cập cơ sở dữ liệu, ủy quyền hoặc chức năng web cấp cao ở đây - loại nội dung đó bạn sẽ tìm thấy trong Vert. x ext [tiện ích mở rộng]

Vert. x core nhỏ và nhẹ. Bạn chỉ cần sử dụng những phần bạn muốn. Nó cũng hoàn toàn có thể nhúng vào các ứng dụng hiện có của bạn - chúng tôi không buộc bạn phải cấu trúc các ứng dụng của mình theo một cách đặc biệt chỉ để bạn có thể sử dụng Vert. x

Bạn có thể sử dụng lõi từ bất kỳ ngôn ngữ nào khác mà Vert. hỗ trợ x. Nhưng đây là một điều thú vị - chúng tôi không bắt buộc bạn phải sử dụng API Java trực tiếp từ, chẳng hạn như JavaScript hoặc Ruby - xét cho cùng, các ngôn ngữ khác nhau có các quy ước và thành ngữ khác nhau, và sẽ thật kỳ quặc khi buộc các nhà phát triển Ruby sử dụng các thành ngữ Java [ . Thay vào đó, chúng tôi tự động tạo một thành ngữ tương đương với các API Java cốt lõi cho từng ngôn ngữ

Từ bây giờ chúng ta sẽ chỉ dùng từ core để chỉ Vert. lõi x

Nếu bạn đang sử dụng Maven hoặc Gradle, hãy thêm phần phụ thuộc sau vào phần phụ thuộc trong bộ mô tả dự án của bạn để truy cập Vert. x API lõi

  • Maven [trong

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    14 của bạn]


 io.vertx
 vertx-core
 4.3.7

  • Gradle [trong tệp

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    15 của bạn]

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}

Hãy thảo luận về các khái niệm và tính năng khác nhau trong lõi

Ban đầu có Vert. x

Bạn không thể làm gì nhiều trong Vert. x-land trừ khi bạn có thể giao tiếp với một đối tượng

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
16

Đó là trung tâm điều khiển của Vert. x và là cách bạn thực hiện hầu hết mọi thứ, bao gồm tạo máy khách và máy chủ, nhận tham chiếu đến xe buýt sự kiện, đặt bộ hẹn giờ cũng như nhiều thứ khác

Vì vậy, làm thế nào để bạn có được một ví dụ?

Nếu bạn đang nhúng Vert. x thì bạn chỉ cần tạo một instance như sau

Vertx vertx = Vertx.vertx[];

Ghi chú

Hầu hết các ứng dụng sẽ chỉ cần một Vert duy nhất. x, nhưng có thể tạo nhiều phiên bản Vert. x nếu bạn yêu cầu, chẳng hạn như cách ly giữa xe buýt sự kiện hoặc các nhóm máy chủ và máy khách khác nhau

Chỉ định các tùy chọn khi tạo đối tượng Vertx

Khi tạo một Vert. x, bạn cũng có thể chỉ định các tùy chọn nếu các giá trị mặc định không phù hợp với bạn

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];

Đối tượng

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
17 có nhiều cài đặt và cho phép bạn định cấu hình những thứ như phân cụm, tính sẵn sàng cao, kích thước nhóm và nhiều cài đặt khác

Tạo một cụm Vert. đối tượng x

Nếu bạn đang tạo một nhóm Vert. x [Xem phần trên bus sự kiện để biết thêm thông tin về phân cụm bus sự kiện], thì thông thường bạn sẽ sử dụng biến thể không đồng bộ để tạo đối tượng Vertx

Điều này là do thường mất một khoảng thời gian [có thể là vài giây] cho các Vert khác nhau. x trong một cụm để nhóm lại với nhau. Trong thời gian đó, chúng tôi không muốn chặn chuỗi cuộc gọi, vì vậy chúng tôi cung cấp kết quả cho bạn một cách không đồng bộ

Bạn thông thạo?

Bạn có thể nhận thấy rằng trong các ví dụ trước, API thông thạo đã được sử dụng

API trôi chảy là nơi có thể kết nối nhiều lệnh gọi phương thức với nhau. Ví dụ

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];

Đây là một mô hình phổ biến trong suốt Vert. x API, vì vậy hãy làm quen với nó

Xâu chuỗi các cuộc gọi như thế này cho phép bạn viết mã ít dài dòng hơn một chút. Tất nhiên, nếu bạn không thích cách tiếp cận trôi chảy, chúng tôi không bắt buộc bạn phải làm theo cách đó, bạn có thể vui vẻ bỏ qua nó nếu muốn và viết mã của mình như thế này

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];

Đừng gọi cho chúng tôi, chúng tôi sẽ gọi cho bạn

Bụi cây. x API phần lớn được điều khiển theo sự kiện. Điều này có nghĩa là khi mọi thứ xảy ra trong Vert. x mà bạn quan tâm, Vert. x sẽ gọi cho bạn bằng cách gửi cho bạn các sự kiện

Một số sự kiện ví dụ là

  • một bộ đếm thời gian đã kích hoạt

  • một số dữ liệu đã đến trên một ổ cắm,

  • một số dữ liệu đã được đọc từ đĩa

  • một ngoại lệ đã xảy ra

  • một máy chủ HTTP đã nhận được yêu cầu

Bạn xử lý các sự kiện bằng cách cung cấp trình xử lý cho Vert. x API. Ví dụ: để nhận sự kiện hẹn giờ mỗi giây, bạn sẽ làm


 io.vertx
 vertx-core
 4.3.7
0

Hoặc để nhận một yêu cầu HTTP


 io.vertx
 vertx-core
 4.3.7
1

Some time later when Vert. x has an event to pass to your handler Vert. x sẽ gọi nó không đồng bộ

This leads us to some important concepts in Vert. x

Don’t block me

With very few exceptions [i. e. some file system operations ending in 'Sync'], none of the APIs in Vert. x block the calling thread

If a result can be provided immediately, it will be returned immediately, otherwise you will usually provide a handler to receive events some time later

Because none of the Vert. x APIs block threads that means you can use Vert. x to handle a lot of concurrency using just a small number of threads

With a conventional blocking API the calling thread might block when

  • Reading data from a socket

  • Writing data to disk

  • Sending a message to a recipient and waiting for a reply

  • …​ Many other situations

In all the above cases, when your thread is waiting for a result it can’t do anything else - it’s effectively useless

This means that if you want a lot of concurrency using blocking APIs then you need a lot of threads to prevent your application grinding to a halt

Threads have overhead in terms of the memory they require [e. g. for their stack] and in context switching

For the levels of concurrency required in many modern applications, a blocking approach just doesn’t scale

Reactor and Multi-Reactor

We mentioned before that Vert. x APIs are event driven - Vert. x passes events to handlers when they are available

In most cases Vert. x calls your handlers using a thread called an event loop

As nothing in Vert. x or your application blocks, the event loop can merrily run around delivering events to different handlers in succession as they arrive

Because nothing blocks, an event loop can potentially deliver huge amounts of events in a short amount of time. Ví dụ: một vòng lặp sự kiện có thể xử lý hàng nghìn yêu cầu HTTP rất nhanh

We call this the Reactor Pattern

You may have heard of this before - for example Node. js implements this pattern

In a standard reactor implementation there is a single event loop thread which runs around in a loop delivering all events to all handlers as they arrive

The trouble with a single thread is it can only run on a single core at any one time, so if you want your single threaded reactor application [e. g. your Node. js application] to scale over your multi-core server you have to start up and manage many different processes

Vert. x works differently here. Instead of a single event loop, each Vertx instance maintains several event loops. By default we choose the number based on the number of available cores on the machine, but this can be overridden

This means a single Vertx process can scale across your server, unlike Node. js

We call this pattern the Multi-Reactor Pattern to distinguish it from the single threaded reactor pattern

Ghi chú

Even though a Vertx instance maintains multiple event loops, any particular handler will never be executed concurrently, and in most cases [with the exception of worker verticles] will always be called using the exact same event loop

The Golden Rule - Don’t Block the Event Loop

We already know that the Vert. x APIs are non blocking and won’t block the event loop, but that’s not much help if you block the event loop yourself in a handler

If you do that, then that event loop will not be able to do anything else while it’s blocked. If you block all of the event loops in Vertx instance then your application will grind to a complete halt

So don’t do it. You have been warned

Examples of blocking include

  • Thread. sleep[]

  • Waiting on a lock

  • Waiting on a mutex or monitor [e. g. synchronized section]

  • Doing a long lived database operation and waiting for a result

  • Doing a complex calculation that takes some significant time

  • Spinning in a loop

If any of the above stop the event loop from doing anything else for a significant amount of time then you should go immediately to the naughty step, and await further instructions

So…​ what is a significant amount of time?

How long is a piece of string? It really depends on your application and the amount of concurrency you require

Nếu bạn có một vòng lặp sự kiện duy nhất và bạn muốn xử lý 10000 yêu cầu http mỗi giây, thì rõ ràng là mỗi yêu cầu không thể mất nhiều hơn 0. 1 mili giây để xử lý, vì vậy bạn không thể chặn lâu hơn thế

Toán học không khó và sẽ để lại như một bài tập cho người đọc

Nếu ứng dụng của bạn không phản hồi, đó có thể là dấu hiệu cho thấy bạn đang chặn vòng lặp sự kiện ở đâu đó. Để giúp bạn chẩn đoán những vấn đề như vậy, Vert. x sẽ tự động ghi lại các cảnh báo nếu nó phát hiện một vòng lặp sự kiện không quay trở lại trong một thời gian. Nếu bạn thấy những cảnh báo như thế này trong nhật ký của mình, thì bạn nên điều tra


 io.vertx
 vertx-core
 4.3.7
2

Vert. x cũng sẽ cung cấp dấu vết ngăn xếp để xác định chính xác nơi xảy ra chặn

Nếu bạn muốn tắt các cảnh báo này hoặc thay đổi cài đặt, bạn có thể làm điều đó trong đối tượng

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
17 trước khi tạo đối tượng Vertx

kết quả trong tương lai

Vert. x 4 sử dụng hợp đồng tương lai để thể hiện kết quả không đồng bộ

Bất kỳ phương thức không đồng bộ nào cũng trả về một đối tượng

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
19 cho kết quả của cuộc gọi. thành công hay thất bại

Bạn không thể tương tác trực tiếp với kết quả của một tương lai, thay vào đó, bạn cần đặt một trình xử lý sẽ được gọi khi tương lai hoàn thành và kết quả có sẵn, giống như bất kỳ loại sự kiện nào khác


 io.vertx
 vertx-core
 4.3.7
5

Ghi chú

Vert. x 3 cung cấp mô hình chỉ gọi lại. Để cho phép di chuyển dễ dàng sang Vert. x 4, chúng tôi đã quyết định rằng mỗi phương thức không đồng bộ cũng có phiên bản gọi lại. Phương thức
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
20 ở trên cũng có phiên bản
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
21 với hàm gọi lại làm đối số phương thức

thận trọng

Đừng nhầm lẫn tương lai với những lời hứa

Nếu hợp đồng tương lai đại diện cho "phía đọc" của một kết quả không đồng bộ, thì các lời hứa là "phía ghi". Chúng cho phép bạn trì hoãn hành động cung cấp kết quả

Trong hầu hết các trường hợp, bạn không cần tự tạo lời hứa trong Vert. ứng dụng x. Bố cục trong tương lai và Phối hợp trong tương lai cung cấp cho bạn các công cụ để chuyển đổi và hợp nhất các kết quả không đồng bộ

Tuy nhiên, nếu trong cơ sở mã của bạn, bạn có các phương thức kế thừa sử dụng lệnh gọi lại, thì bạn có thể tận dụng thực tế là một lời hứa mở rộng

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
22

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
0

thận trọng

Các hoạt động của thiết bị đầu cuối như

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
23,
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
24 và
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
25 không đảm bảo bất kỳ điều gì liên quan đến thứ tự gọi các cuộc gọi lại

Xem xét một tương lai có 2 cuộc gọi lại được đăng ký

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
1

Có thể cuộc gọi lại thứ hai được gọi trước cuộc gọi đầu tiên

Nếu bạn cần sự đảm bảo như vậy, hãy cân nhắc sử dụng thành phần Tương lai với

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
26

Future composition

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
27 có thể được sử dụng để xâu chuỗi tương lai

  • khi tương lai hiện tại thành công, hãy áp dụng hàm đã cho, trả về một tương lai. Khi tương lai được trả lại này hoàn thành, tác phẩm thành công

  • khi tương lai hiện tại thất bại, bố cục thất bại

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
2

In this example, 3 operations are chained together

  1. a file is created

  2. dữ liệu được ghi trong tập tin này

  3. the file is moved

When these 3 steps are successful, the final future [

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
28] will succeed. However, if one of the steps fails, the final future will fail

Beyond this,

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
19 offers more.
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
30,
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
31,
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
32,
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
33 and even a
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
34 which is an alias of
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
35

Future coordination

Coordination of multiple futures can be achieved with Vert. x

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
36. It supports concurrent composition [run several async operations in parallel] and sequential composition [chain async operations]

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
37 takes several futures arguments [up to 6] and returns a future that is succeeded when all the futures are succeeded and failed when at least one of the futures is failed

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
3

The operations run concurrently, the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
38 attached to the returned future is invoked upon completion of the composition. When one of the operation fails [one of the passed future is marked as a failure], the resulting future is marked as failed too. When all the operations succeed, the resulting future is completed with a success

On success, the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
39 method guarantees the results in the same order specified in the call to
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
40. In the example above, regardless of which item completed first, the
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
41 result can be accessed using
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
42 and the
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
43 result can be accessed using
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
44

Alternatively, you can pass a list [potentially empty] of futures

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
4

While the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
45 composition waits until all futures are successful [or one fails], the
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
46 composition waits for the first succeeded future.
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
47 takes several futures arguments [up to 6] and returns a future that is succeeded when one of the futures is, and failed when all the futures are failed

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
5

A list of futures can be used also

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
6

Thành phần

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
48 đợi cho đến khi tất cả các tương lai được hoàn thành, dù thành công hay thất bại.
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
49 lấy một số đối số tương lai [tối đa 6] và trả về một tương lai thành công khi tất cả các tương lai đều thành công và thất bại khi tất cả các tương lai được hoàn thành và ít nhất một trong số chúng không thành công

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
7

A list of futures can be used also

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
8

CompletionStage interoperability

The Vert. x

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50 API offers compatibility from and to
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
51 which is the JDK interface for composable asynchronous operations

We can go from a Vert. x

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50 to a
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
51 using the
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
54 method, as in

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
9

We can conversely go from a

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
51 to Vert. x
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50 using
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
57. There are 2 variants

  1. the first variant takes just a

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    51 and calls the
    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    50 methods from the thread that resolves the
    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    51 instance, and

  2. biến thể thứ hai lấy thêm tham số

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    61 để gọi các phương thức
    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    50 trên Vert. x context

Important

In most cases the variant with a
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
51 and a
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
64 is the one you will want to use to respect the Vert. x threading model, since Vert. x
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50 are more likely to be used with Vert. x code, libraries and clients

Here is an example of going from a

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
51 to a Vert. x
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50 and dispatching on a context

Vertx vertx = Vertx.vertx[];
0

Verticles

Vert. x comes with a simple, scalable, actor-like deployment and concurrency model out of the box that you can use to save you writing your own

Mô hình này là hoàn toàn tùy chọn và Vert. x does not force you to create your applications in this way if you don’t want to

The model does not claim to be a strict actor-model implementation, but it does share similarities especially with respect to concurrency, scaling and deployment

To use this model, you write your code as set of verticles

Verticles are chunks of code that get deployed and run by Vert. x. A Vert. x instance maintains N event loop threads [where N by default is core*2] by default. Verticles can be written in any of the languages that Vert. x supports and a single application can include verticles written in multiple languages

You can think of a verticle as a bit like an actor in the Actor Model

An application would typically be composed of many verticle instances running in the same Vert. x instance at the same time. The different verticle instances communicate with each other by sending messages on the event bus

Writing Verticles

Verticle classes must implement the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
68 interface

They can implement it directly if you like but usually it’s simpler to extend the abstract class

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
69

Here’s an example verticle

Vertx vertx = Vertx.vertx[];
1

Normally you would override the start method like in the example above

When Vert. x deploys the verticle it will call the start method, and when the method has completed the verticle will be considered started

You can also optionally override the stop method. Điều này sẽ được gọi bởi Vert. x when the verticle is undeployed and when the method has completed the verticle will be considered stopped

Asynchronous Verticle start and stop

Sometimes you want to do something in your verticle start-up which takes some time and you don’t want the verticle to be considered deployed until that happens. For example you might want to start an HTTP server in the start method and propagate the asynchronous result of the server

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
70 method

Bạn không thể chặn chờ máy chủ HTTP liên kết trong phương thức bắt đầu của mình vì điều đó sẽ vi phạm Quy tắc vàng

So how can you do this?

The way to do it is to implement the asynchronous start method. This version of the method takes a Future as a parameter. When the method returns the verticle will not be considered deployed

Some time later, after you’ve done everything you need to do [e. g. start the HTTP server], you can call complete on the Future [or fail] to signal that you’re done

Here’s an example

Vertx vertx = Vertx.vertx[];
2

Similarly, there is an asynchronous version of the stop method too. Bạn sử dụng cái này nếu bạn muốn thực hiện một số thao tác dọn dẹp theo chiều dọc cần một chút thời gian

Vertx vertx = Vertx.vertx[];
3

INFO. You don’t need to manually stop the HTTP server started by a verticle, in the verticle’s stop method. Vert. x will automatically stop any running server when the verticle is undeployed

Verticle Types

There are two different types of verticles

Standard Verticles

These are the most common and useful type - they are always executed using an event loop thread. We’ll discuss this more in the next section

Worker Verticles

These run using a thread from the worker pool. An instance is never executed concurrently by more than one thread

Standard verticles

Standard verticles are assigned an event loop thread when they are created and the start method is called with that event loop. When you call any other methods that takes a handler on a core API from an event loop then Vert. x will guarantee that those handlers, when called, will be executed on the same event loop

This means we can guarantee that all the code in your verticle instance is always executed on the same event loop [as long as you don’t create your own threads and call it. ]

This means you can write all the code in your application as single threaded and let Vert. x worry about the threading and scaling. No more worrying about synchronized and volatile any more, and you also avoid many other cases of race conditions and deadlock so prevalent when doing hand-rolled 'traditional' multi-threaded application development

Worker verticles

A worker verticle is just like a standard verticle but it’s executed using a thread from the Vert. x worker thread pool, rather than using an event loop

Worker verticles are designed for calling blocking code, as they won’t block any event loops

If you don’t want to use a worker verticle to run blocking code, you can also run inline blocking code directly while on an event loop

If you want to deploy a verticle as a worker verticle you do that with

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
71

Vertx vertx = Vertx.vertx[];
4

Worker verticle instances are never executed concurrently by Vert. x by more than one thread, but can executed by different threads at different times

Deploying verticles programmatically

You can deploy a verticle using one of the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
72 method, specifying a verticle name or you can pass in a verticle instance you have already created yourself

Ghi chú

Deploying Verticle instances is Java only

Vertx vertx = Vertx.vertx[];
5

You can also deploy verticles by specifying the verticle name

The verticle name is used to look up the specific

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
73 that will be used to instantiate the actual verticle instance[s]

Different verticle factories are available for instantiating verticles in different languages and for various other reasons such as loading services and getting verticles from Maven at run-time

This allows you to deploy verticles written in any language from any other language that Vert. x supports

Here’s an example of deploying some different types of verticles

Vertx vertx = Vertx.vertx[];
6

Rules for mapping a verticle name to a verticle factory

When deploying verticle[s] using a name, the name is used to select the actual verticle factory that will instantiate the verticle[s]

Verticle names can have a prefix - which is a string followed by a colon, which if present will be used to look-up the factory, e. g

Vertx vertx = Vertx.vertx[];
7

If no prefix is present, Vert. x will look for a suffix and use that to lookup the factory, e. g

Vertx vertx = Vertx.vertx[];
8

If no prefix or suffix is present, Vert. x will assume it’s a Java fully qualified class name [FQCN] and try and instantiate that

How are Verticle Factories located?

Most Verticle factories are loaded from the classpath and registered at Vert. x startup

You can also programmatically register and unregister verticle factories using

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
74 and
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
75 if you wish

Waiting for deployment to complete

Verticle deployment is asynchronous and may complete some time after the call to deploy has returned

If you want to be notified when deployment is complete you can deploy specifying a completion handler

Vertx vertx = Vertx.vertx[];
9

The completion handler will be passed a result containing the deployment ID string, if deployment succeeded

ID triển khai này có thể được sử dụng sau này nếu bạn muốn hủy triển khai triển khai

Undeploying verticle deployments

Deployments can be undeployed with

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
76

Un-deployment is itself asynchronous so if you want to be notified when un-deployment is complete you can deploy specifying a completion handler

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
0

Specifying number of verticle instances

When deploying a verticle using a verticle name, you can specify the number of verticle instances that you want to deploy

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
1

This is useful for scaling easily across multiple cores. For example you might have a web-server verticle to deploy and multiple cores on your machine, so you want to deploy multiple instances to utilise all the cores

Passing configuration to a verticle

Configuration in the form of JSON can be passed to a verticle at deployment time

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
2

This configuration is then available via the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
61 object or directly using the
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
78 method. The configuration is returned as a JSON object so you can retrieve data as follows

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
3

Accessing environment variables in a Verticle

Environment variables and system properties are accessible using the Java API

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
4

High Availability

Verticles can be deployed with High Availability [HA] enabled. In that context, when a verticle is deployed on a vert. x instance that dies abruptly, the verticle is redeployed on another vert. x instance from the cluster

To run an verticle with the high availability enabled, just append the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
79 switch

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
5

When enabling high availability, no need to add

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
80

More details about the high availability feature and configuration in the High Availability and Fail-Over section

Running Verticles from the command line

You can use Vert. x directly in your Maven or Gradle projects in the normal way by adding a dependency to the Vert. x core library and hacking from there

However you can also run Vert. x verticles directly from the command line if you wish

To do this you need to download and install a Vert. x distribution, and add the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
81 directory of the installation to your
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
82 environment variable. Also make sure you have a Java JDK on your
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
82

Vert. x supports Java from 8 to 17

Ghi chú

Cần có JDK để hỗ trợ quá trình biên dịch mã Java nhanh chóng

You can now run verticles by using the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
84 command. Here are some examples

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
6

You can even run Java source verticles without compiling them first

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
7

Vert. x will compile the Java source file on the fly before running it. This is really useful for quickly prototyping verticles and great for demos. No need to set-up a Maven or Gradle build first to get going

For full information on the various options available when executing

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85 on the command line, type
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85 at the command line

Causing Vert. x to exit

Threads maintained by Vert. x instances are not daemon threads so they will prevent the JVM from exiting

If you are embedding Vert. x and you have finished with it, you can call

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
87 to close it down

This will shut-down all internal thread pools and close other resources, and will allow the JVM to exit

The Context object

When Vert. x provides an event to a handler or calls the start or stop methods of a

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
68, the execution is associated with a
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
64. Usually a context is an event-loop context and is tied to a specific event loop thread. So executions for that context always occur on that exact same event loop thread. In the case of worker verticles and running inline blocking code a worker context will be associated with the execution which will use a thread from the worker thread pool

To retrieve the context, use the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
90 method

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
8

If the current thread has a context associated with it, it reuses the context object. Nếu không phải là một phiên bản ngữ cảnh mới được tạo. You can test the type of context you have retrieved

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
9

When you have retrieved the context object, you can run code in this context asynchronously. In other words, you submit a task that will be eventually run in the same context, but later

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
0

When several handlers run in the same context, they may want to share data. The context object offers methods to store and retrieve data shared in the context. For instance, it lets you pass data to some action run with

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
91

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
1

Đối tượng ngữ cảnh cũng cho phép bạn truy cập cấu hình cột dọc bằng phương thức

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
92. Check the Passing configuration to a verticle section for more details about this configuration

Executing periodic and delayed actions

It’s very common in Vert. x to want to perform an action after a delay, or periodically

In standard verticles you can’t just make the thread sleep to introduce a delay, as that will block the event loop thread

Instead you use Vert. x timers. Timers can be one-shot or periodic. We’ll discuss both

One-shot Timers

Bộ đếm thời gian một lần gọi trình xử lý sự kiện sau một độ trễ nhất định, được biểu thị bằng mili giây

To set a timer to fire once you use

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
93 method passing in the delay and a handler

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
2

The return value is a unique timer id which can later be used to cancel the timer. The handler is also passed the timer id

Hẹn giờ định kỳ

You can also set a timer to fire periodically by using

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
94

There will be an initial delay equal to the period

The return value of

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
95 is a unique timer id [long]. This can be later used if the timer needs to be cancelled

The argument passed into the timer event handler is also the unique timer id

Keep in mind that the timer will fire on a periodic basis. If your periodic treatment takes a long amount of time to proceed, your timer events could run continuously or even worse . xếp chồng lên nhau

In this case, you should consider using

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
93 instead. Once your treatment has finished, you can set the next timer

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
3

Cancelling timers

To cancel a periodic timer, call

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
97 specifying the timer id. For example

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
4

Automatic clean-up in verticles

If you’re creating timers from inside verticles, those timers will be automatically closed when the verticle is undeployed

Verticle worker pool

Verticles use the Vert. x worker pool for executing blocking actions, i. e

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
98 or worker verticle

A different worker pool can be specified in deployment options

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
5

The Event Bus

The

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
99 is the nervous system of Vert. x

There is a single event bus instance for every Vert. x instance and it is obtained using the method

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
00

The event bus allows different parts of your application to communicate with each other, irrespective of what language they are written in, and whether they’re in the same Vert. x instance, or in a different Vert. x instance

It can even be bridged to allow client-side JavaScript running in a browser to communicate on the same event bus

The event bus forms a distributed peer-to-peer messaging system spanning multiple server nodes and multiple browsers

The event bus supports publish/subscribe, point-to-point, and request-response messaging

API xe buýt sự kiện rất đơn giản. It basically involves registering handlers, unregistering handlers and sending and publishing messages

First some theory

The Theory

Addressing

Messages are sent on the event bus to an address

Vert. x doesn’t bother with any fancy addressing schemes. In Vert. x an address is simply a string. Any string is valid. However, it is wise to use some kind of scheme, e. g. using periods to demarcate a namespace

Some examples of valid addresses are europe. news. feed1, acme. games. pacman, sausages, and X

Handlers

Messages are received by handlers. You register a handler at an address

Many different handlers can be registered at the same address

A single handler can be registered at many different addresses

Publish / subscribe messaging

The event bus supports publishing messages

Messages are published to an address. Publishing means delivering the message to all handlers that are registered at that address

This is the familiar publish/subscribe messaging pattern

Point-to-point and Request-Response messaging

The event bus also supports point-to-point messaging

Messages are sent to an address. Vert. x will then route them to just one of the handlers registered at that address

If there is more than one handler registered at the address, one will be chosen using a non-strict round-robin algorithm

With point-to-point messaging, an optional reply handler can be specified when sending the message

When a message is received by a recipient, and has been handled, the recipient can optionally decide to reply to the message. If they do so, the reply handler will be called

When the reply is received back by the sender, it too can be replied to. This can be repeated ad infinitum, and allows a dialog to be set up between two different verticles

This is a common messaging pattern called the request-response pattern

Best-effort delivery

Vert. x does its best to deliver messages and won’t consciously throw them away. This is called best-effort delivery

However, in case of failure of all or parts of the event bus, there is a possibility messages might be lost

If your application cares about lost messages, you should code your handlers to be idempotent, and your senders to retry after recovery

Types of messages

Out of the box Vert. x allows any primitive/simple type, String, or

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
01 to be sent as messages

However, it’s a convention and common practice in Vert. x to send messages as JSON

JSON is very easy to create, read and parse in all the languages that Vert. x supports, so it has become a kind of lingua franca for Vert. x

However, you are not forced to use JSON if you don’t want to

The event bus is very flexible and also supports sending arbitrary objects over the event bus. You can do this by defining a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
02 for the objects you want to send

The Event Bus API

Let’s jump into the API

Getting the event bus

You get a reference to the event bus as follows

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
6

There is a single instance of the event bus per Vert. x instance

Registering Handlers

This simplest way to register a handler is using

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
03. Here’s an example

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
7

When a message arrives for your handler, your handler will be called, passing in the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
04

The object returned from call to consumer[] is an instance of

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
05

This object can subsequently be used to unregister the handler, or use the handler as a stream

Alternatively you can use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
03 to return a MessageConsumer with no handler set, and then set the handler on that. For example

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
8

When registering a handler on a clustered event bus, it can take some time for the registration to reach all nodes of the cluster

If you want to be notified when this has completed, you can register a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
07 on the MessageConsumer object

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
9

Un-registering Handlers

To unregister a handler, call

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
08

If you are on a clustered event bus, un-registering can take some time to propagate across the nodes. If you want to be notified when this is complete, use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
09

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
0

Publishing messages

Publishing a message is simple. Just use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
10 specifying the address to publish it to

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
1

That message will then be delivered to all handlers registered against the address news. uk. sport

Sending messages

Sending a message will result in only one handler registered at the address receiving the message. This is the point-to-point messaging pattern. The handler is chosen in a non-strict round-robin fashion

You can send a message with

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
11

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
2

Setting headers on messages

Messages sent over the event bus can also contain headers. Điều này có thể được chỉ định bằng cách cung cấp một

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
12 khi gửi hoặc xuất bản

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
3

Message ordering

Vert. x will deliver messages to any particular handler in the same order they were sent from any particular sender

The Message object

The object you receive in a message handler is a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
13

The

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
14 of the message corresponds to the object that was sent or published

The headers of the message are available with

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
15

Acknowledging messages / sending replies

When using

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
11 the event bus attempts to deliver the message to a
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
05 registered with the event bus

In some cases it’s useful for the sender to know when the consumer has received the message and "processed" it using request-response pattern

To acknowledge that the message has been processed, the consumer can reply to the message by calling

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
18

When this happens it causes a reply to be sent back to the sender and the reply handler is invoked with the reply

An example will make this clear

The receiver

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
4

The sender

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
5

The reply can contain a message body which can contain useful information

What the "processing" actually means is application-defined and depends entirely on what the message consumer does and is not something that the Vert. x event bus itself knows or cares about

Vài ví dụ

  • A simple message consumer which implements a service which returns the time of the day would acknowledge with a message containing the time of day in the reply body

  • Người tiêu dùng tin nhắn thực hiện hàng đợi liên tục, có thể xác nhận bằng

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    19 nếu tin nhắn được duy trì thành công trong bộ nhớ hoặc
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    20 nếu không

  • A message consumer which processes an order might acknowledge with

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    19 when the order has been successfully processed so it can be deleted from the database

Sending with timeouts

When sending a message with a reply handler, you can specify a timeout in the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
12

If a reply is not received within that time, the reply handler will be called with a failure

The default timeout is 30 seconds

gửi thất bại

Message sends can fail for other reasons, including

  • There are no handlers available to send the message to

  • The recipient has explicitly failed the message using

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    23

In all cases, the reply handler will be called with the specific failure

Message Codecs

You can send any object you like across the event bus if you define and register a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
24 for it

Message codecs have a name and you specify that name in the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
12 when sending or publishing the message

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
6

If you always want the same codec to be used for a particular type then you can register a default codec for it, then you don’t have to specify the codec on each send in the delivery options

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
7

You unregister a message codec with

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
26

Message codecs don’t always have to encode and decode as the same type. For example you can write a codec that allows a MyPOJO class to be sent, but when that message is sent to a handler it arrives as a MyOtherPOJO class

Vert. x has built-in codecs for certain data types

  • các loại cơ bản [chuỗi, mảng byte, byte, int, long, double, boolean, short, char] hoặc

  • một số Vert. x kiểu dữ liệu [bộ đệm, mảng JSON, đối tượng JSON] hoặc

  • các loại triển khai giao diện

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    27 hoặc

  • các loại triển khai giao diện

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    28

Important

Ở chế độ nhóm, các đối tượng

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
27 và
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
28 bị từ chối theo mặc định vì lý do bảo mật

Bạn có thể xác định lớp nào được phép mã hóa và giải mã bằng cách cung cấp các hàm kiểm tra tên của lớp

  • HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    31, and

  • HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    32

Xe buýt sự kiện cụm

Xe buýt sự kiện không chỉ tồn tại trong một Vert. ví dụ x. Bằng cách nhóm các Vert khác nhau. x cùng nhau trên mạng của bạn, chúng có thể tạo thành một bus sự kiện phân tán duy nhất

Phân cụm theo chương trình

Nếu bạn đang tạo Vert của mình. x theo chương trình, bạn sẽ nhận được một bus sự kiện theo cụm bằng cách định cấu hình Vert. x dưới dạng nhóm;

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
8

You should also make sure you have a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
33 implementation on your classpath, for example the Hazelcast cluster manager

Clustering on the command line

You can run Vert. x clustered on the command line with

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
9

Automatic clean-up in verticles

If you’re registering event bus handlers from inside verticles, those handlers will be automatically unregistered when the verticle is undeployed

Configuring the event bus

The event bus can be configured. It is particularly useful when the event bus is clustered. Under the hood the event bus uses TCP connections to send and receive messages, so the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
34 let you configure all aspects of these TCP connections. As the event bus acts as a server and client, the configuration is close to
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
35 and
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
36


 io.vertx
 vertx-core
 4.3.7
00

The previous snippet depicts how you can use SSL connections for the event bus, instead of plain TCP connections

CẢNH BÁO. to enforce the security in clustered mode, you must configure the cluster manager to use encryption or enforce security. Refer to the documentation of the cluster manager for further details

The event bus configuration needs to be consistent in all the cluster nodes

The

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
34 also lets you specify whether or not the event bus is clustered, the port and host

When used in containers, you can also configure the public host and port


 io.vertx
 vertx-core
 4.3.7
01

JSON

Unlike some other languages, Java does not have first class support for JSON so we provide two classes to make handling JSON in your Vert. x applications a bit easier

JSON objects

The

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
38 class represents JSON objects

A JSON object is basically just a map which has string keys and values can be of one of the JSON supported types [string, number, boolean]

JSON objects also support null values

Creating JSON objects

Empty JSON objects can be created with the default constructor

You can create a JSON object from a string JSON representation as follows


 io.vertx
 vertx-core
 4.3.7
02

You can create a JSON object from a map as follows


 io.vertx
 vertx-core
 4.3.7
03

Putting entries into a JSON object

Use the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
39 methods to put values into the JSON object

The method invocations can be chained because of the fluent API


 io.vertx
 vertx-core
 4.3.7
04

Getting values from a JSON object

You get values from a JSON object using the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
40 methods, for example


 io.vertx
 vertx-core
 4.3.7
05

Mapping between JSON objects and Java objects

You can create a JSON object from the fields of a Java object as follows

You can instantiate a Java object and populate its fields from a JSON object as follows


 io.vertx
 vertx-core
 4.3.7
06

Note that both of the above mapping directions use Jackson’s

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
41 to perform the mapping. See the Jackson documentation for information on the impact of field and constructor visibility, caveats on serialization and deserialization across object references, etc

However, in the simplest case, both

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
42 and
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
43 should succeed if all fields of the Java class are public [or have public getters/setters], and if there is a public default constructor [or no defined constructors]

Referenced objects will be transitively serialized/deserialized to/from nested JSON objects as long as the object graph is acyclic

Encoding a JSON object to a String

You use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
44 to encode the object to a String form

JSON arrays

Lớp

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
45 đại diện cho các mảng JSON

A JSON array is a sequence of values [string, number, boolean]

JSON arrays can also contain null values

Creating JSON arrays

Empty JSON arrays can be created with the default constructor

You can create a JSON array from a string JSON representation as follows


 io.vertx
 vertx-core
 4.3.7
07

Adding entries into a JSON array

You add entries to a JSON array using the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
46 methods


 io.vertx
 vertx-core
 4.3.7
08

Getting values from a JSON array

You get values from a JSON array using the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
40 methods, for example


 io.vertx
 vertx-core
 4.3.7
09

Encoding a JSON array to a String

You use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
48 to encode the array to a String form

Tạo JSON tùy ý

Creating JSON object and array assumes you are using valid string representation

When you are unsure of the string validity then you should use instead

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
49


 io.vertx
 vertx-core
 4.3.7
10

Json Pointers

Vert. x provides an implementation of Json Pointers from RFC6901. You can use pointers both for querying and for writing. Bạn có thể xây dựng

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
50 của mình bằng cách sử dụng chuỗi, URI hoặc đường dẫn nối thêm thủ công


 io.vertx
 vertx-core
 4.3.7
11

After instantiating your pointer, use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
51 to query a JSON value. You can update a Json Value using
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
52


 io.vertx
 vertx-core
 4.3.7
12

You can use Vert. x Con trỏ Json với bất kỳ mô hình đối tượng nào bằng cách cung cấp triển khai tùy chỉnh của

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
53

bộ đệm

Hầu hết dữ liệu được xáo trộn xung quanh bên trong Vert. x sử dụng bộ đệm

Bộ đệm là một chuỗi gồm 0 hoặc nhiều byte có thể đọc hoặc ghi vào và tự động mở rộng khi cần thiết để chứa bất kỳ byte nào được ghi vào nó. You can perhaps think of a buffer as smart byte array

Creating buffers

Bộ đệm có thể tạo bằng cách sử dụng một trong các phương pháp tĩnh

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
54

Bộ đệm có thể được khởi tạo từ chuỗi hoặc mảng byte hoặc có thể tạo bộ đệm trống

Here are some examples of creating buffers

Tạo một bộ đệm trống mới


 io.vertx
 vertx-core
 4.3.7
13

Create a buffer from a String. Chuỗi sẽ được mã hóa trong bộ đệm bằng UTF-8


 io.vertx
 vertx-core
 4.3.7
14

Tạo bộ đệm từ Chuỗi. Chuỗi sẽ được mã hóa bằng mã hóa đã chỉ định, e. g


 io.vertx
 vertx-core
 4.3.7
15

Create a buffer from a byte[]


 io.vertx
 vertx-core
 4.3.7
16

Create a buffer with an initial size hint. Nếu bạn biết bộ đệm của mình sẽ có một lượng dữ liệu nhất định được ghi vào bộ đệm, bạn có thể tạo bộ đệm và chỉ định kích thước này. Điều này làm cho bộ đệm ban đầu phân bổ nhiều bộ nhớ đó và hiệu quả hơn bộ đệm tự động thay đổi kích thước nhiều lần khi dữ liệu được ghi vào nó

Lưu ý rằng bộ đệm được tạo theo cách này trống. Nó không tạo bộ đệm chứa đầy số 0 cho đến kích thước đã chỉ định


 io.vertx
 vertx-core
 4.3.7
17

Ghi vào bộ đệm

Có hai cách để ghi vào bộ đệm. nối thêm và truy cập ngẫu nhiên. Trong cả hai trường hợp, bộ đệm sẽ luôn tự động mở rộng để bao gồm các byte. Không thể lấy một chiếc

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
55 có bộ đệm

Appending to a Buffer

To append to a buffer, you use the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
56 methods. Append methods exist for appending various different types

The return value of the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
56 methods is the buffer itself, so these can be chained


 io.vertx
 vertx-core
 4.3.7
18

Random access buffer writes

You can also write into the buffer at a specific index, by using the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
58 methods. Set methods exist for various different data types. All the set methods take an index as the first argument - this represents the position in the buffer where to start writing the data

The buffer will always expand as necessary to accommodate the data


 io.vertx
 vertx-core
 4.3.7
19

Reading from a Buffer

Data is read from a buffer using the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
40 methods. Get methods exist for various datatypes. The first argument to these methods is an index in the buffer from where to get the data


 io.vertx
 vertx-core
 4.3.7
20

Working with unsigned numbers

Unsigned numbers can be read from or appended/set to a buffer with the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
60,
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
61 and
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
62 methods. This is useful when implementing a codec for a network protocol optimized to minimize bandwidth consumption

In the following example, value 200 is set at specified position with just one byte


 io.vertx
 vertx-core
 4.3.7
21

The console shows '200'

Buffer length

Use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
63 to obtain the length of the buffer. The length of a buffer is the index of the byte in the buffer with the largest index + 1

Copying buffers

Use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
64 to make a copy of the buffer

Slicing buffers

A sliced buffer is a new buffer which backs onto the original buffer, i. e. it does not copy the underlying data. Use

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
65 to create a sliced buffers

Buffer re-use

After writing a buffer to a socket or other similar place, they cannot be re-used

Writing TCP servers and clients

Vert. x cho phép bạn dễ dàng viết các máy khách và máy chủ TCP không chặn

Creating a TCP server

The simplest way to create a TCP server, using all default options is as follows


 io.vertx
 vertx-core
 4.3.7
22

Configuring a TCP server

If you don’t want the default, a server can be configured by passing in a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
36 instance when creating it


 io.vertx
 vertx-core
 4.3.7
23

Start the Server Listening

To tell the server to listen for incoming requests you use one of the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
67 alternatives

To tell the server to listen at the host and port as specified in the options


 io.vertx
 vertx-core
 4.3.7
24

Or to specify the host and port in the call to listen, ignoring what is configured in the options


 io.vertx
 vertx-core
 4.3.7
25

The default host is

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
68 which means 'listen on all available addresses' and the default port is
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
69, which is a special value that instructs the server to find a random unused local port and use that

The actual bind is asynchronous, so the server might not actually be listening until some time after the call to listen has returned

If you want to be notified when the server is actually listening you can provide a handler to the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
70 call. For example


 io.vertx
 vertx-core
 4.3.7
26

Listening on a random port

If

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
69 is used as the listening port, the server will find an unused random port to listen on

To find out the real port the server is listening on you can call

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
72


 io.vertx
 vertx-core
 4.3.7
27

Getting notified of incoming connections

To be notified when a connection is made you need to set a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
73


 io.vertx
 vertx-core
 4.3.7
28

When a connection is made the handler will be called with an instance of

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74

This is a socket-like interface to the actual connection, and allows you to read and write data as well as do various other things like close the socket

Reading data from the socket

To read data from the socket you set the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
75 on the socket

This handler will be called with an instance of

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
76 every time data is received on the socket


 io.vertx
 vertx-core
 4.3.7
29

Writing data to a socket

You write to a socket using one of

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
77


 io.vertx
 vertx-core
 4.3.7
50

Write operations are asynchronous and may not occur until some time after the call to write has returned

Closed handler

If you want to be notified when a socket is closed, you can set a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
78 on it


 io.vertx
 vertx-core
 4.3.7
51

Handling exceptions

Bạn có thể đặt

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
79 để nhận bất kỳ ngoại lệ nào xảy ra trên ổ cắm

You can set an

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
80 to receive any exceptions that happens before the connection is passed to the
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
73 , e. g during the TLS handshake

Event bus write handler

Every socket automatically registers a handler on the event bus, and when any buffers are received in this handler, it writes them to itself. Those are local subscriptions not routed on the cluster

This enables you to write data to a socket which is potentially in a completely different verticle by sending the buffer to the address of that handler

The address of the handler is given by

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
82

Local and remote addresses

The local address of a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74 can be retrieved using
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
84

The remote address, [i. e. the address of the other end of the connection] of a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74 can be retrieved using
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
86

Sending files or resources from the classpath

Files and classpath resources can be written to the socket directly using

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
87. This can be a very efficient way to send files, as it can be handled by the OS kernel directly where supported by the operating system

Please see the chapter about serving files from the classpath for restrictions of the classpath resolution or disabling it


 io.vertx
 vertx-core
 4.3.7
52

Streaming sockets

Instances of

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74 are also
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89 and
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90 instances, so they can be used to pipe data to or from other read and write streams

See the chapter on streams for more information

Upgrading connections to SSL/TLS

A non SSL/TLS connection can be upgraded to SSL/TLS using

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
91

The server or client must be configured for SSL/TLS for this to work correctly. Vui lòng xem chương về SSL/TLS để biết thêm thông tin

Closing a TCP Server

Call

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
92 to close the server. Closing the server closes any open connections and releases all server resources

The close is actually asynchronous and might not complete until some time after the call has returned. If you want to be notified when the actual close has completed then you can pass in a handler

This handler will then be called when the close has fully completed


 io.vertx
 vertx-core
 4.3.7
53

Automatic clean-up in verticles

If you’re creating TCP servers and clients from inside verticles, those servers and clients will be automatically closed when the verticle is undeployed

Scaling - sharing TCP servers

The handlers of any TCP server are always executed on the same event loop thread

This means that if you are running on a server with a lot of cores, and you only have this one instance deployed then you will have at most one core utilised on your server

In order to utilise more cores of your server you will need to deploy more instances of the server

You can instantiate more instances programmatically in your code


 io.vertx
 vertx-core
 4.3.7
54

hoặc, bạn có thể chỉ cần triển khai nhiều phiên bản hơn của trục máy chủ của mình bằng cách sử dụng tùy chọn

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
93 trên dòng lệnh


 io.vertx
 vertx-core
 4.3.7
55

Once you do this you will find the echo server works functionally identically to before, but all your cores on your server can be utilised and more work can be handled

At this point you might be asking yourself 'How can you have more than one server listening on the same host and port? Surely you will get port conflicts as soon as you try and deploy more than one instance?'

Vert. x does a little magic here. *

When you deploy another server on the same host and port as an existing server it doesn’t actually try and create a new server listening on the same host/port

Instead it internally maintains just a single server, and, as incoming connections arrive it distributes them in a round-robin fashion to any of the connect handlers

Consequently Vert. x TCP servers can scale over available cores while each instance remains single threaded

Creating a TCP client

The simplest way to create a TCP client, using all default options is as follows


 io.vertx
 vertx-core
 4.3.7
56

Configuring a TCP client

If you don’t want the default, a client can be configured by passing in a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
35 instance when creating it


 io.vertx
 vertx-core
 4.3.7
57

Making connections

Để tạo kết nối với máy chủ, bạn sử dụng

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
95, chỉ định cổng và máy chủ của máy chủ và trình xử lý sẽ được gọi với kết quả chứa
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74 khi kết nối thành công hoặc lỗi nếu kết nối không thành công


 io.vertx
 vertx-core
 4.3.7
58

Configuring connection attempts

A client can be configured to automatically retry connecting to the server in the event that it cannot connect. This is configured with

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
97 and
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
98

Ghi chú

Currently, Vert. x will not attempt to reconnect if a connection fails, reconnect attempts and interval only apply to creating initial connections


 io.vertx
 vertx-core
 4.3.7
59

By default, multiple connection attempts are disabled

Ghi nhật ký hoạt động mạng

For debugging purposes, network activity can be logged

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
00

Here is the output of a simple HTTP server

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
01

By default, binary data is logged in hex format

You can reduce the data format verbosity to only print the buffer length instead of the entire data by setting the log data fomat

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
02

Here is the same output with simple buffer format

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
03

Clients can also log network activity

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
04

Network activity is logged by Netty with the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
99 level and with the

 io.vertx
 vertx-core
 4.3.7
000 name. When using network activity logging there are a few things to keep in mind

  • logging is not performed by Vert. x logging but by Netty

  • this is not a production feature

You should read the Netty logging section

Configuring servers and clients to work with SSL/TLS

TCP clients and servers can be configured to use Transport Layer Security - earlier versions of TLS were known as SSL

The APIs of the servers and clients are identical whether or not SSL/TLS is used, and it’s enabled by configuring the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
35 or
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
36 instances used to create the servers or clients

Enabling SSL/TLS on the server

SSL/TLS is enabled with


 io.vertx
 vertx-core
 4.3.7
003

By default it is disabled

Specifying key/certificate for the server

SSL/TLS servers usually provide certificates to clients in order verify their identity to clients

Certificates/keys can be configured for servers in several ways

The first method is by specifying the location of a Java key-store which contains the certificate and private key

Java key stores can be managed with the keytool utility which ships with the JDK

The password for the key store should also be provided

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
05

Alternatively you can read the key store yourself as a buffer and provide that directly

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
06

Key/certificate in PKCS#12 format [http. //en. wikipedia. org/wiki/PKCS_12], usually with the


 io.vertx
 vertx-core
 4.3.7
004 or the

 io.vertx
 vertx-core
 4.3.7
005 extension can also be loaded in a similar fashion than JKS key stores

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
07

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
08

Another way of providing server private key and certificate separately using


 io.vertx
 vertx-core
 4.3.7
006 files

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
09

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
10

Vert. x supports reading of unencrypted RSA and/or ECC based private keys from PKCS8 PEM files. RSA based private keys can also be read from PKCS1 PEM files. X. 509 certificates can be read from PEM files containing a textual encoding of the certificate as defined by RFC 7468, Section 5

Warning

Keep in mind that the keys contained in an unencrypted PKCS8 or a PKCS1 PEM file can be extracted by anybody who can read the file. Thus, make sure to put proper access restrictions on such PEM files in order to prevent misuse

Finally, you can also load generic Java keystore, it is useful for using other KeyStore implementations like Bouncy Castle

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
11

Specifying trust for the server

SSL/TLS servers can use a certificate authority in order to verify the identity of the clients

Certificate authorities can be configured for servers in several ways

Java trust stores can be managed with the keytool utility which ships with the JDK

The password for the trust store should also be provided

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
12

Alternatively you can read the trust store yourself as a buffer and provide that directly

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
13

Certificate authority in PKCS#12 format [http. //en. wikipedia. org/wiki/PKCS_12], usually with the


 io.vertx
 vertx-core
 4.3.7
004 or the

 io.vertx
 vertx-core
 4.3.7
005 extension can also be loaded in a similar fashion than JKS trust stores

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
14

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
15

Another way of providing server certificate authority using a list


 io.vertx
 vertx-core
 4.3.7
006 files

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
16

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
17

Enabling SSL/TLS on the client

Net Clients cũng có thể được cấu hình dễ dàng để sử dụng SSL. They have the exact same API when using SSL as when using standard sockets

To enable SSL on a NetClient the function setSSL[true] is called

Client trust configuration

If the


 io.vertx
 vertx-core
 4.3.7
010 is set to true on the client, then the client will trust all server certificates. The connection will still be encrypted but this mode is vulnerable to 'man in the middle' attacks. I. e. you can’t be sure who you are connecting to. Use this with caution. Giá trị mặc định là sai

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
18

If


 io.vertx
 vertx-core
 4.3.7
011 is not set then a client trust store must be configured and should contain the certificates of the servers that the client trusts

By default, host verification is disabled on the client. To enable host verification, set the algorithm to use on your client [only HTTPS and LDAPS is currently supported]

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
19

Likewise server configuration, the client trust can be configured in several ways

The first method is by specifying the location of a Java trust-store which contains the certificate authority

It is just a standard Java key store, the same as the key stores on the server side. Vị trí cửa hàng ủy thác của khách hàng được đặt bằng cách sử dụng chức năng


 io.vertx
 vertx-core
 4.3.7
012 trên

 io.vertx
 vertx-core
 4.3.7
013. If a server presents a certificate during connection which is not in the client trust store, the connection attempt will not succeed

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
20

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
21

Certificate authority in PKCS#12 format [http. //en. wikipedia. org/wiki/PKCS_12], usually with the


 io.vertx
 vertx-core
 4.3.7
004 or the

 io.vertx
 vertx-core
 4.3.7
005 extension can also be loaded in a similar fashion than JKS trust stores

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
22

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
23

Another way of providing server certificate authority using a list


 io.vertx
 vertx-core
 4.3.7
006 files

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
24

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
25

Chỉ định khóa/chứng chỉ cho khách hàng

If the server requires client authentication then the client must present its own certificate to the server when connecting. The client can be configured in several ways

The first method is by specifying the location of a Java key-store which contains the key and certificate. Again it’s just a regular Java key store. The client keystore location is set by using the function


 io.vertx
 vertx-core
 4.3.7
012 on the

 io.vertx
 vertx-core
 4.3.7
013

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
26

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
27

Key/certificate in PKCS#12 format [http. //en. wikipedia. org/wiki/PKCS_12], usually with the


 io.vertx
 vertx-core
 4.3.7
004 or the

 io.vertx
 vertx-core
 4.3.7
005 extension can also be loaded in a similar fashion than JKS key stores

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
28

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
29

Another way of providing server private key and certificate separately using


 io.vertx
 vertx-core
 4.3.7
006 files

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
30

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
31

Keep in mind that pem configuration, the private key is not crypted

Self-signed certificates for testing and development purposes

thận trọng

Do not use this in production settings, and note that the generated keys are very insecure

It is very often the case that self-signed certificates are required, be it for unit / integration tests or for running a development version of an application


 io.vertx
 vertx-core
 4.3.7
022 can be used to provide self-signed PEM certificate helpers and give

 io.vertx
 vertx-core
 4.3.7
023 and

 io.vertx
 vertx-core
 4.3.7
024 configurations

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
32

The client can also be configured to trust all certificates

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
33

Note that self-signed certificates also work for other TCP protocols like HTTPS

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
34

Revoking certificate authorities

Trust can be configured to use a certificate revocation list [CRL] for revoked certificates that should no longer be trusted. The


 io.vertx
 vertx-core
 4.3.7
025 configures the crl list to use

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
35

Cấu hình bộ đệm cũng được hỗ trợ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
36

Configuring the Cipher suite

By default, the TLS configuration will use the list of Cipher suites of the SSL engine

  • JDK SSL engine when

    
     io.vertx
     vertx-core
     4.3.7
    
    026 is used

  • OpenSSL engine when

    
     io.vertx
     vertx-core
     4.3.7
    
    027 is used

This Cipher suite can be configured with a suite of enabled ciphers

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
37

When the enabled cipher suites is defined [i. e không trống], nó được ưu tiên hơn các bộ mật mã mặc định của công cụ SSL

Cipher suite can be specified on the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
36 or
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
35 configuration

Configuring TLS protocol versions

By default, the TLS configuration will use the following protocol versions. SSLv2Hello, TLSv1, TLSv1. 1 and TLSv1. 2. Protocol versions can be configured by explicitly adding enabled protocols

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
38

Protocol versions can be specified on the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
36 or
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
35 configuration

SSL engine

The engine implementation can be configured to use OpenSSL instead of the JDK implementation. OpenSSL provides better performances and CPU usage than the JDK engine, as well as JDK version independence

The engine options to use is

  • the

    
     io.vertx
     vertx-core
     4.3.7
    
    032 options when it is set

  • nếu không thì

    
     io.vertx
     vertx-core
     4.3.7
    
    026

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
39

Server Name Indication [SNI]

Chỉ định tên máy chủ [SNI] là một tiện ích mở rộng TLS mà khách hàng chỉ định tên máy chủ đang cố gắng kết nối. during the TLS handshake the client gives a server name and the server can use it to respond with a specific certificate for this server name instead of the default deployed certificate. If the server requires client authentication the server can use a specific trusted CA certificate depending on the indicated server name

When SNI is active the server uses

  • the certificate CN or SAN DNS [Subject Alternative Name with DNS] to do an exact match, e. g

    
     io.vertx
     vertx-core
     4.3.7
    
    034

  • the certificate CN or SAN DNS certificate to match a wildcard name, e. g

    
     io.vertx
     vertx-core
     4.3.7
    
    035

  • otherwise the first certificate when the client does not present a server name or the presented server name cannot be matched

When the server additionally requires client authentication

  • if

    
     io.vertx
     vertx-core
     4.3.7
    
    036 were used to set the trust options [
    
     io.vertx
     vertx-core
     4.3.7
    
    037] then an exact match with the trust store alias is done

  • mặt khác, các chứng chỉ CA có sẵn được sử dụng theo cách giống như khi không có SNI

You can enable SNI on the server by setting


 io.vertx
 vertx-core
 4.3.7
038 to
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
19 and configured the server with multiple key/certificate pairs

Java KeyStore files or PKCS12 files can store multiple key/cert pairs out of the box

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
40


 io.vertx
 vertx-core
 4.3.7
040 có thể được cấu hình để chứa nhiều mục nhập

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
41

The client implicitly sends the connecting host as an SNI server name for Fully Qualified Domain Name [FQDN]

You can provide an explicit server name when connecting a socket

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
42

It can be used for different purposes

  • present a server name different than the server host

  • present a server name while connecting to an IP

  • force to present a server name when using shortname

Application-Layer Protocol Negotiation [ALPN]

Application-Layer Protocol Negotiation [ALPN] is a TLS extension for application layer protocol negotiation. It is used by HTTP/2. during the TLS handshake the client gives the list of application protocols it accepts and the server responds with a protocol it supports

Java TLS supports ALPN [Java 8 with the most recent versions]

OpenSSL ALPN support

OpenSSL also supports [native] ALPN

OpenSSL requires to configure


 io.vertx
 vertx-core
 4.3.7
041 and use netty-tcnative jar on the classpath. Using tcnative may require OpenSSL to be installed on your OS depending on the tcnative implementation

Using a proxy for client connections

The


 io.vertx
 vertx-core
 4.3.7
042 supports either a HTTP/1. x CONNECT, SOCKS4a or SOCKS5 proxy

The proxy can be configured in the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
35 by setting a

 io.vertx
 vertx-core
 4.3.7
044 object containing proxy type, hostname, port and optionally username and password

Here’s an example

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
43

The DNS resolution is always done on the proxy server, to achieve the functionality of a SOCKS4 client, it is necessary to resolve the DNS address locally

You can use


 io.vertx
 vertx-core
 4.3.7
045 to configure a list of host bypassing the proxy. The lists accepts

 io.vertx
 vertx-core
 4.3.7
046 wildcard for matching domains

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
44

Using HA PROXY protocol

HA PROXY protocol provides a convenient way to safely transport connection information such as a client’s address across multiple layers of NAT or TCP proxies

HA PROXY protocol can be enabled by setting the option


 io.vertx
 vertx-core
 4.3.7
047 and adding the following dependency in your classpath

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
45

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
46

Writing HTTP servers and clients

Vert. x allows you to easily write non blocking HTTP clients and servers

Vert. x supports the HTTP/1. 0, HTTP/1. 1 and HTTP/2 protocols

The base API for HTTP is the same for HTTP/1. x and HTTP/2, specific API features are available for dealing with the HTTP/2 protocol

Creating an HTTP Server

The simplest way to create an HTTP server, using all default options is as follows

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
47

Configuring an HTTP server

If you don’t want the default, a server can be configured by passing in a


 io.vertx
 vertx-core
 4.3.7
048 instance when creating it

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
48

Configuring an HTTP/2 server

Vert. x supports HTTP/2 over TLS


 io.vertx
 vertx-core
 4.3.7
049 and over TCP

 io.vertx
 vertx-core
 4.3.7
050

  • 
     io.vertx
     vertx-core
     4.3.7
    
    049 identifies the HTTP/2 protocol when used over TLS negotiated by Application-Layer Protocol Negotiation [ALPN]

  • 
     io.vertx
     vertx-core
     4.3.7
    
    050 identifies the HTTP/2 protocol when using in clear text over TCP, such connections are established either with an HTTP/1. 1 upgraded request or directly

To handle


 io.vertx
 vertx-core
 4.3.7
049 requests, TLS must be enabled along with

 io.vertx
 vertx-core
 4.3.7
054

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
49

ALPN is a TLS extension that negotiates the protocol before the client and the server start to exchange data

Clients that don’t support ALPN will still be able to do a classic SSL handshake

ALPN will usually agree on the


 io.vertx
 vertx-core
 4.3.7
049 protocol, although

 io.vertx
 vertx-core
 4.3.7
056 can be used if the server or the client decides so

To handle


 io.vertx
 vertx-core
 4.3.7
050 requests, TLS must be disabled, the server will upgrade to HTTP/2 any request HTTP/1. 1 that wants to upgrade to HTTP/2. It will also accept a direct

 io.vertx
 vertx-core
 4.3.7
050 connection beginning with the

 io.vertx
 vertx-core
 4.3.7
059 preface

Warning

most browsers won’t support

 io.vertx
 vertx-core
 4.3.7
050, so for serving web sites you should use

 io.vertx
 vertx-core
 4.3.7
049 and not

 io.vertx
 vertx-core
 4.3.7
050

When a server accepts an HTTP/2 connection, it sends to the client its


 io.vertx
 vertx-core
 4.3.7
063. The settings define how the client can use the connection, the default initial settings for a server are

  • 
     io.vertx
     vertx-core
     4.3.7
    
    064.
    
     io.vertx
     vertx-core
     4.3.7
    
    065 as recommended by the HTTP/2 RFC

  • the default HTTP/2 settings values for the others

Logging network server activity

For debugging purposes, network activity can be logged

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
50

See the chapter on logging network activity for a detailed explanation

Start the Server Listening

To tell the server to listen for incoming requests you use one of the


 io.vertx
 vertx-core
 4.3.7
066 alternatives

To tell the server to listen at the host and port as specified in the options

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
51

Or to specify the host and port in the call to listen, ignoring what is configured in the options

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
52

The default host is

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
68 which means 'listen on all available addresses' and the default port is

 io.vertx
 vertx-core
 4.3.7
068

The actual bind is asynchronous so the server might not actually be listening until some time after the call to listen has returned

If you want to be notified when the server is actually listening you can provide a handler to the

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
70 call. For example

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
53

Getting notified of incoming requests

To be notified when a request arrives you need to set a


 io.vertx
 vertx-core
 4.3.7
070

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
54

Handling requests

When a request arrives, the request handler is called passing in an instance of


 io.vertx
 vertx-core
 4.3.7
071. This object represents the server side HTTP request

The handler is called when the headers of the request have been fully read

If the request contains a body, that body will arrive at the server some time after the request handler has been called

The server request object allows you to retrieve the


 io.vertx
 vertx-core
 4.3.7
072,

 io.vertx
 vertx-core
 4.3.7
073,

 io.vertx
 vertx-core
 4.3.7
074 and

 io.vertx
 vertx-core
 4.3.7
075, amongst other things

Each server request object is associated with one server response object. You use


 io.vertx
 vertx-core
 4.3.7
076 to get a reference to the

 io.vertx
 vertx-core
 4.3.7
077 object

Here’s a simple example of a server handling a request and replying with "hello world" to it

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
55

Request version

The version of HTTP specified in the request can be retrieved with


 io.vertx
 vertx-core
 4.3.7
078

Request method

Use


 io.vertx
 vertx-core
 4.3.7
079 to retrieve the HTTP method of the request. [tôi. e. whether it’s GET, POST, PUT, DELETE, HEAD, OPTIONS, etc]

Request URI

Use


 io.vertx
 vertx-core
 4.3.7
072 to retrieve the URI of the request

Note that this is the actual URI as passed in the HTTP request, and it’s almost always a relative URI

The URI is as defined in Section 5. 1. 2 of the HTTP specification - Request-URI

Request path

Use


 io.vertx
 vertx-core
 4.3.7
073 to return the path part of the URI

For example, if the request URI was `a/b/c/page. html?param1=abc¶m2=xyz

Then the path would be


 io.vertx
 vertx-core
 4.3.7
082

Request query

Use


 io.vertx
 vertx-core
 4.3.7
083 to return the query part of the URI

For example, if the request URI was


 io.vertx
 vertx-core
 4.3.7
084

Sau đó, truy vấn sẽ là


 io.vertx
 vertx-core
 4.3.7
085

Request headers

Use


 io.vertx
 vertx-core
 4.3.7
075 to return the headers of the HTTP request

This returns an instance of


 io.vertx
 vertx-core
 4.3.7
087 - which is like a normal Map or Hash but allows multiple values for the same key - this is because HTTP allows multiple header values with the same key

It also has case-insensitive keys, that means you can do the following

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
56

Request host

Use


 io.vertx
 vertx-core
 4.3.7
088 to return the host of the HTTP request

For HTTP/1. x requests the


 io.vertx
 vertx-core
 4.3.7
089 header is returned, for HTTP/1 requests the

 io.vertx
 vertx-core
 4.3.7
090 pseudo header is returned

Request parameters

Use


 io.vertx
 vertx-core
 4.3.7
074 to return the parameters of the HTTP request

Just like


 io.vertx
 vertx-core
 4.3.7
075 this returns an instance of

 io.vertx
 vertx-core
 4.3.7
087 as there can be more than one parameter with the same name

Thông số yêu cầu được gửi trên URI yêu cầu, sau đường dẫn. For example if the URI was


 io.vertx
 vertx-core
 4.3.7
094

Then the parameters would contain the following

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
57

Note that these request parameters are retrieved from the URL of the request. If you have form attributes that have been sent as part of the submission of an HTML form submitted in the body of a


 io.vertx
 vertx-core
 4.3.7
095 request then they will not appear in the params here

Remote address

The address of the sender of the request can be retrieved with


 io.vertx
 vertx-core
 4.3.7
096

Absolute URI

The URI passed in an HTTP request is usually relative. If you wish to retrieve the absolute URI corresponding to the request, you can get it with


 io.vertx
 vertx-core
 4.3.7
097

End handler

The


 io.vertx
 vertx-core
 4.3.7
098 of the request is invoked when the entire request, including any body has been fully read

Reading Data from the Request Body

Often an HTTP request contains a body that we want to read. As previously mentioned the request handler is called when just the headers of the request have arrived so the request object does not have a body at that point

This is because the body may be very large [e. g. a file upload] and we don’t generally want to buffer the entire body in memory before handing it to you, as that could cause the server to exhaust available memory

To receive the body, you can use the


 io.vertx
 vertx-core
 4.3.7
099 on the request, this will get called every time a chunk of the request body arrives. Here’s an example

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
58

The object passed into the handler is a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
76, and the handler can be called multiple times as data arrives from the network, depending on the size of the body

Trong một số trường hợp [e. g. if the body is small] you will want to aggregate the entire body in memory, so you could do the aggregation yourself as follows

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
59

This is such a common case, that Vert. x provides a


 io.vertx
 vertx-core
 4.3.7
101 to do this for you. The body handler is called once when all the body has been received

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
60

Streaming requests

The request object is a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89 so you can pipe the request body to any
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90 instance

Xem chương về luồng để được giải thích chi tiết

Handling HTML forms

HTML forms can be submitted with either a content type of


 io.vertx
 vertx-core
 4.3.7
104 or

 io.vertx
 vertx-core
 4.3.7
105

Đối với các biểu mẫu được mã hóa url, các thuộc tính của biểu mẫu được mã hóa trong url, giống như các tham số truy vấn thông thường

For multi-part forms they are encoded in the request body, and as such are not available until the entire body has been read from the wire

Multi-part forms can also contain file uploads

If you want to retrieve the attributes of a multi-part form you should tell Vert. x mà bạn mong muốn nhận được một biểu mẫu như vậy trước khi bất kỳ nội dung nào được đọc bằng cách gọi


 io.vertx
 vertx-core
 4.3.7
106 cùng với
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
19, sau đó bạn nên truy xuất các thuộc tính thực tế bằng cách sử dụng

 io.vertx
 vertx-core
 4.3.7
108 sau khi toàn bộ nội dung đã được đọc

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
61

Form attributes have a maximum size of


 io.vertx
 vertx-core
 4.3.7
109 bytes. When the client submits a form with an attribute size greater than this value, the file upload triggers an exception on

 io.vertx
 vertx-core
 4.3.7
110 exception handler. You can set a different maximum size with

 io.vertx
 vertx-core
 4.3.7
111

Handling form file uploads

Vert. x can also handle file uploads which are encoded in a multi-part request body

To receive file uploads you tell Vert. x to expect a multi-part form and set an


 io.vertx
 vertx-core
 4.3.7
112 on the request

This handler will be called once for every upload that arrives on the server

The object passed into the handler is a


 io.vertx
 vertx-core
 4.3.7
113 instance

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
62

File uploads can be large we don’t provide the entire upload in a single buffer as that might result in memory exhaustion, instead, the upload data is received in chunks

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
63

The upload object is a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89 so you can pipe the request body to any
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90 instance. See the chapter on streams for a detailed explanation

If you just want to upload the file to disk somewhere you can use


 io.vertx
 vertx-core
 4.3.7
116

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
64

Warning

Make sure you check the filename in a production system to avoid malicious clients uploading files to arbitrary places on your filesystem. See security notes for more information

Handling cookies

You use


 io.vertx
 vertx-core
 4.3.7
117 to retrieve a cookie by name, or use

 io.vertx
 vertx-core
 4.3.7
118 to retrieve all the cookies

To remove a cookie, use


 io.vertx
 vertx-core
 4.3.7
119

Để thêm cookie, hãy sử dụng


 io.vertx
 vertx-core
 4.3.7
120

The set of cookies will be written back in the response automatically when the response headers are written so the browser can store them

Cookies are described by instances of


 io.vertx
 vertx-core
 4.3.7
121. This allows you to retrieve the name, value, domain, path and other normal cookie properties

Same Site Cookies let servers require that a cookie shouldn’t be sent with cross-site [where Site is defined by the registrable domain] requests, which provides some protection against cross-site request forgery attacks. This kind of cookies are enabled using the setter.


 io.vertx
 vertx-core
 4.3.7
122

Same site cookies can have one of 3 values

  • Không có - Trình duyệt sẽ gửi cookie với cả yêu cầu trên nhiều trang và yêu cầu trên cùng một trang

  • Nghiêm ngặt - Trình duyệt sẽ chỉ gửi cookie cho các yêu cầu cùng trang [yêu cầu bắt nguồn từ trang đã đặt cookie]. If the request originated from a different URL than the URL of the current location, none of the cookies tagged with the Strict attribute will be included

  • Lax - Same-site cookies are withheld on cross-site subrequests, such as calls to load images or frames, but will be sent when a user navigates to the URL from an external site; for example, by following a link

Here’s an example of querying and adding cookies

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
65

Handling compressed body

Vert. x can handle compressed body payloads which are encoded by the client with the deflate, gzip or brotli algorithms

To enable decompression set


 io.vertx
 vertx-core
 4.3.7
123 on the options when creating the server

You need to have Brotli4j on the classpath to decompress Brotli

  • Maven [trong

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    14 của bạn]

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
66

  • Gradle [trong tệp

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    15 của bạn]

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
67

When using Gradle, you need to add the runtime native library manually depending on your OS and architecture. See the Gradle section of Brotli4j for more details

By default, decompression is disabled

Receiving custom HTTP/2 frames

HTTP/2 is a framed protocol with various frames for the HTTP request/response model. The protocol allows other kind of frames to be sent and received

To receive custom frames, you can use the


 io.vertx
 vertx-core
 4.3.7
126 on the request, this will get called every time a custom frame arrives. Here’s an example

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
68

HTTP/2 frames are not subject to flow control - the frame handler will be called immediately when a custom frame is received whether the request is paused or is not

Sending back responses

The server response object is an instance of


 io.vertx
 vertx-core
 4.3.7
077 and is obtained from the request with

 io.vertx
 vertx-core
 4.3.7
076

You use the response object to write a response back to the HTTP client

Setting status code and message

The default HTTP status code for a response is


 io.vertx
 vertx-core
 4.3.7
129, representing

 io.vertx
 vertx-core
 4.3.7
130

Use


 io.vertx
 vertx-core
 4.3.7
131 to set a different code

You can also specify a custom status message with


 io.vertx
 vertx-core
 4.3.7
132

If you don’t specify a status message, the default one corresponding to the status code will be used

Ghi chú

for HTTP/2 the status won’t be present in the response since the protocol won’t transmit the message to the client

Writing HTTP responses

To write data to an HTTP response, you use one of the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
77 operations

These can be invoked multiple times before the response is ended. They can be invoked in a few ways

With a single buffer

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
69

With a string. In this case the string will encoded using UTF-8 and the result written to the wire

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
70

With a string and an encoding. In this case the string will encoded using the specified encoding and the result written to the wire

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
71

Writing to a response is asynchronous and always returns immediately after write has been queued

If you are just writing a single string or buffer to the HTTP response you can write it and end the response in a single call to the


 io.vertx
 vertx-core
 4.3.7
134

The first call to write results in the response header being written to the response. Consequently, if you are not using HTTP chunking then you must set the


 io.vertx
 vertx-core
 4.3.7
135 header before writing to the response, since it will be too late otherwise. If you are using HTTP chunking you do not have to worry

Ending HTTP responses

Once you have finished with the HTTP response you should


 io.vertx
 vertx-core
 4.3.7
136 it

This can be done in several ways

With no arguments, the response is simply ended

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
72

It can also be called with a string or buffer in the same way


 io.vertx
 vertx-core
 4.3.7
137 is called. In this case it’s just the same as calling write with a string or buffer followed by calling end with no arguments. For example

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
73

Closing the underlying connection

You can close the underlying TCP connection with


 io.vertx
 vertx-core
 4.3.7
138

Non keep-alive connections will be automatically closed by Vert. x when the response is ended

Keep-alive connections are not automatically closed by Vert. x by default. If you want keep-alive connections to be closed after an idle time, then you configure


 io.vertx
 vertx-core
 4.3.7
139

HTTP/2 connections send a {@literal GOAWAY} frame before closing the response

Setting response headers

HTTP response headers can be added to the response by adding them directly to the


 io.vertx
 vertx-core
 4.3.7
140

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
74

Or you can use


 io.vertx
 vertx-core
 4.3.7
141

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
75

Tất cả các tiêu đề phải được thêm vào trước khi bất kỳ phần nào của nội dung phản hồi được viết

Chunked HTTP responses and trailers

Vert. x hỗ trợ mã hóa HTTP chunked Transfer

This allows the HTTP response body to be written in chunks, and is normally used when a large response body is being streamed to a client and the total size is not known in advance

You put the HTTP response into chunked mode as follows

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
76

Default is non-chunked. When in chunked mode, each call to one of the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
77 methods will result in a new HTTP chunk being written out

When in chunked mode you can also write HTTP response trailers to the response. These are actually written in the final chunk of the response

Ghi chú

chunked response has no effect for an HTTP/2 stream

To add trailers to the response, add them directly to the


 io.vertx
 vertx-core
 4.3.7
143

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
77

Or use


 io.vertx
 vertx-core
 4.3.7
144

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
78

Serving files directly from disk or the classpath

If you were writing a web server, one way to serve a file from disk would be to open it as an


 io.vertx
 vertx-core
 4.3.7
145 and pipe it to the HTTP response

Or you could load it it one go using


 io.vertx
 vertx-core
 4.3.7
146 and write it straight to the response

Alternatively, Vert. x provides a method which allows you to serve a file from disk or the filesystem to an HTTP response in one operation. Where supported by the underlying operating system this may result in the OS directly transferring bytes from the file to the socket without being copied through user-space at all

This is done by using


 io.vertx
 vertx-core
 4.3.7
147, and is usually more efficient for large files, but may be slower for small files

Here’s a very simple web server that serves files from the file system using sendFile

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
79

Sending a file is asynchronous and may not complete until some time after the call has returned. If you want to be notified when the file has been written you can use


 io.vertx
 vertx-core
 4.3.7
148

Please see the chapter about serving files from the classpath for restrictions about the classpath resolution or disabling it

Ghi chú

If you use

 io.vertx
 vertx-core
 4.3.7
149 while using HTTPS it will copy through user-space, since if the kernel is copying data directly from disk to socket it doesn’t give us an opportunity to apply any encryption

Warning

If you’re going to write web servers directly using Vert. x be careful that users cannot exploit the path to access files outside the directory from which you want to serve them or the classpath It may be safer instead to use Vert. x Web

When there is a need to serve just a segment of a file, say starting from a given byte, you can achieve this by doing

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
80

You are not required to supply the length if you want to send a file starting from an offset until the end, in this case you can just do

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
81

Piping responses

The server response is a

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90 so you can pipe to it from any
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89, e. g.

 io.vertx
 vertx-core
 4.3.7
145,
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74,

 io.vertx
 vertx-core
 4.3.7
154 or

 io.vertx
 vertx-core
 4.3.7
071

Here’s an example which echoes the request body back in the response for any PUT methods. It uses a pipe for the body, so it will work even if the HTTP request body is much larger than can fit in memory at any one time

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
82

You can also use the


 io.vertx
 vertx-core
 4.3.7
156 method to send a
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89

Sending a stream is a pipe operation, however as this is a method of


 io.vertx
 vertx-core
 4.3.7
077, it will also take care of chunking the response when the

 io.vertx
 vertx-core
 4.3.7
159 is not set

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
83

Writing HTTP/2 frames

HTTP/2 is a framed protocol with various frames for the HTTP request/response model. The protocol allows other kind of frames to be sent and received

To send such frames, you can use the


 io.vertx
 vertx-core
 4.3.7
160 on the response. Here’s an example

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
84

These frames are sent immediately and are not subject to flow control - when such frame is sent there it may be done before other {@literal DATA} frames

Stream reset

HTTP/1. x does not allow a clean reset of a request or a response stream, for example when a client uploads a resource already present on the server, the server needs to accept the entire response

HTTP/2 supports stream reset at any time during the request/response

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
85

By default, the


 io.vertx
 vertx-core
 4.3.7
161 [0] error code is sent, another code can sent instead

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
86

The HTTP/2 specification defines the list of error codes one can use

The request handler are notified of stream reset events with the


 io.vertx
 vertx-core
 4.3.7
162 and

 io.vertx
 vertx-core
 4.3.7
163

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
87

Server push

Server push is a new feature of HTTP/2 that enables sending multiple responses in parallel for a single client request

When a server process a request, it can push a request/response to the client

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
88

Khi máy chủ sẵn sàng đẩy phản hồi, trình xử lý phản hồi đẩy được gọi và trình xử lý có thể gửi phản hồi

The push response handler may receive a failure, for instance the client may cancel the push because it already has


 io.vertx
 vertx-core
 4.3.7
164 in its cache and does not want it anymore

Phương thức


 io.vertx
 vertx-core
 4.3.7
165 phải được gọi trước khi phản hồi bắt đầu kết thúc, tuy nhiên phản hồi đẩy có thể được viết sau

Handling exceptions

You can set an


 io.vertx
 vertx-core
 4.3.7
166 to receive any exceptions that happens before the connection is passed to the

 io.vertx
 vertx-core
 4.3.7
070 or to the

 io.vertx
 vertx-core
 4.3.7
168, e. g. trong quá trình bắt tay TLS

Handling invalid requests

Vert. x will handle invalid HTTP requests and provides a default handler that will handle the common case appropriately, e. g. it does respond with


 io.vertx
 vertx-core
 4.3.7
169 when a request header is too long

You can set your own


 io.vertx
 vertx-core
 4.3.7
170 to process invalid requests. Your implementation can handle specific cases and delegate other cases to to

 io.vertx
 vertx-core
 4.3.7
171

HTTP Compression

Vert. x comes with support for HTTP Compression out of the box

This means you are able to automatically compress the body of the responses before they are sent back to the client

If the client does not support HTTP compression the responses are sent back without compressing the body

This allows to handle Client that support HTTP Compression and those that not support it at the same time

To enable compression use can configure it with


 io.vertx
 vertx-core
 4.3.7
172

By default, compression is not enabled

When HTTP compression is enabled the server will check if the client includes an


 io.vertx
 vertx-core
 4.3.7
173 header which includes the supported compressions. Commonly used are deflate and gzip. Both are supported by Vert. x

If such a header is found the server will automatically compress the body of the response with one of the supported compressions and send it back to the client

Whenever the response needs to be sent without compression you can set the header


 io.vertx
 vertx-core
 4.3.7
174 to

 io.vertx
 vertx-core
 4.3.7
175

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
89

Be aware that compression may be able to reduce network traffic but is more CPU-intensive

To address this latter issue Vert. x cho phép bạn điều chỉnh tham số 'mức nén' có nguồn gốc từ thuật toán nén gzip/deflate

Compression level allows to configure gizp/deflate algorithms in terms of the compression ratio of the resulting data and the computational cost of the compress/decompress operation

The compression level is an integer value ranged from '1' to '9', where '1' means lower compression ratio but fastest algorithm and '9' means maximum compression ratio available but a slower algorithm

Using compression levels higher that 1-2 usually allows to save just some bytes in size - the gain is not linear, and depends on the specific data to be compressed - but it comports a non-trascurable cost in term of CPU cycles required to the server while generating the compressed response data [ Note that at moment Vert. x doesn’t support any form caching of compressed response data, even for static files, so the compression is done on-the-fly at every request body generation ] and in the same way it affects client[s] while decoding [inflating] received responses, operation that becomes more CPU-intensive the more the level increases

By default - if compression is enabled via


 io.vertx
 vertx-core
 4.3.7
172 - Vert. x will use '6' as compression level, but the parameter can be configured to address any case with

 io.vertx
 vertx-core
 4.3.7
177

HTTP compression algorithms

Vert. x supports out of the box deflate and gzip

Brotli and zstandard can also be used

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
90

Ghi chú

use

 io.vertx
 vertx-core
 4.3.7
178 static methods to create

 io.vertx
 vertx-core
 4.3.7
179

Brotli and zstandard libraries need to be added to the classpath

  • Maven [trong

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    14 của bạn]

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
91

  • Gradle [trong tệp

    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    15 của bạn]

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
92

When using Gradle, you need to add the runtime native library manually depending on your OS and architecture. See the Gradle section of Brotli4j for more details

You can configure compressors according to your needs

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
93

Creating an HTTP client

You create an


 io.vertx
 vertx-core
 4.3.7
182 instance with default options as follows

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
94

If you want to configure options for the client, you create it as follows

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
95

Vert. x supports HTTP/2 over TLS


 io.vertx
 vertx-core
 4.3.7
049 and over TCP

 io.vertx
 vertx-core
 4.3.7
050

By default, the http client performs HTTP/1. 1 requests, to perform HTTP/2 requests the


 io.vertx
 vertx-core
 4.3.7
185 must be set to

 io.vertx
 vertx-core
 4.3.7
186

For


 io.vertx
 vertx-core
 4.3.7
049 requests, TLS must be enabled with Application-Layer Protocol Negotiation

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
96

For


 io.vertx
 vertx-core
 4.3.7
050 requests, TLS must be disabled, the client will do an HTTP/1. 1 requests and try an upgrade to HTTP/2

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
97


 io.vertx
 vertx-core
 4.3.7
050 connections can also be established directly, i. e. connection started with a prior knowledge, when

 io.vertx
 vertx-core
 4.3.7
190 options is set to false. after the connection is established, the client will send the HTTP/2 connection preface and expect to receive the same preface from the server

The http server may not support HTTP/2, the actual version can be checked with


 io.vertx
 vertx-core
 4.3.7
191 when the response arrives

When a clients connects to an HTTP/2 server, it sends to the server its


 io.vertx
 vertx-core
 4.3.7
192. The settings define how the server can use the connection, the default initial settings for a client are the default values defined by the HTTP/2 RFC

Logging network client activity

For debugging purposes, network activity can be logged

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
98

See the chapter on logging network activity for a detailed explanation

Making requests

The http client is very flexible and there are various ways you can make requests with it

The first step when making a request is obtaining an HTTP connection to the remote server

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
99

The client will connect to the remote server or reuse an available connection from the client connection pool

Default host and port

Often you want to make many requests to the same host/port with an http client. To avoid you repeating the host/port every time you make a request you can configure the client with a default host/port

Vertx vertx = Vertx.vertx[];
00

Writing request headers

Bạn có thể viết tiêu đề cho yêu cầu bằng cách sử dụng


 io.vertx
 vertx-core
 4.3.7
193 như sau

Vertx vertx = Vertx.vertx[];
01

The headers are an instance of


 io.vertx
 vertx-core
 4.3.7
087 which provides operations for adding, setting and removing entries. Http headers allow more than one value for a specific key

You can also write headers using


 io.vertx
 vertx-core
 4.3.7
195

Vertx vertx = Vertx.vertx[];
02

If you wish to write headers to the request you must do so before any part of the request body is written

Writing request and processing response

The


 io.vertx
 vertx-core
 4.3.7
196

 io.vertx
 vertx-core
 4.3.7
197 methods connects to the remote server or reuse an existing connection. The request instance obtained is pre-populated with some data such like the host or the request URI, but you need to send this request to the server

You can call


 io.vertx
 vertx-core
 4.3.7
198 to send a request such as an HTTP

 io.vertx
 vertx-core
 4.3.7
199 and process the asynchronous

 io.vertx
 vertx-core
 4.3.7
200

Vertx vertx = Vertx.vertx[];
03

You can also send the request with a body


 io.vertx
 vertx-core
 4.3.7
201 with a string, the

 io.vertx
 vertx-core
 4.3.7
135 header will be set for you if it was not previously set

Vertx vertx = Vertx.vertx[];
04


 io.vertx
 vertx-core
 4.3.7
203 with a buffer, the

 io.vertx
 vertx-core
 4.3.7
135 header will be set for you if it was not previously set

Vertx vertx = Vertx.vertx[];
05


 io.vertx
 vertx-core
 4.3.7
205 with a stream, if the

 io.vertx
 vertx-core
 4.3.7
135 header was not previously set, the request is sent with a chunked

 io.vertx
 vertx-core
 4.3.7
207

Vertx vertx = Vertx.vertx[];
06

Streaming Request body

The


 io.vertx
 vertx-core
 4.3.7
208 method send requests at once

Sometimes you’ll want to have low level control on how you write requests bodies

The


 io.vertx
 vertx-core
 4.3.7
196 can be used to write the request body

Here are some examples of writing a POST request with a body

Vertx vertx = Vertx.vertx[];
07

Methods exist to write strings in UTF-8 encoding and in any specific encoding and to write buffers

Vertx vertx = Vertx.vertx[];
08

If you are just writing a single string or buffer to the HTTP request you can write it and end the request in a single call to the


 io.vertx
 vertx-core
 4.3.7
210 function

Vertx vertx = Vertx.vertx[];
09

When you’re writing to a request, the first call to


 io.vertx
 vertx-core
 4.3.7
137 will result in the request headers being written out to the wire

The actual write is asynchronous and might not occur until some time after the call has returned

Non-chunked HTTP requests with a request body require a


 io.vertx
 vertx-core
 4.3.7
135 header to be provided

Consequently, if you are not using chunked HTTP then you must set the


 io.vertx
 vertx-core
 4.3.7
135 header before writing to the request, as it will be too late otherwise

If you are calling one of the


 io.vertx
 vertx-core
 4.3.7
210 methods that take a string or buffer then Vert. x will automatically calculate and set the

 io.vertx
 vertx-core
 4.3.7
135 header before writing the request body

If you are using HTTP chunking a


 io.vertx
 vertx-core
 4.3.7
135 header is not required, so you do not have to calculate the size up-front

Ending streamed HTTP requests

Once you have finished with the HTTP request you must end it with one of the


 io.vertx
 vertx-core
 4.3.7
217 operations

Ending a request causes any headers to be written, if they have not already been written and the request to be marked as complete

Requests can be ended in several ways. With no arguments the request is simply ended

Vertx vertx = Vertx.vertx[];
10

Or a string or buffer can be provided in the call to


 io.vertx
 vertx-core
 4.3.7
210. This is like calling

 io.vertx
 vertx-core
 4.3.7
137 with the string or buffer before calling

 io.vertx
 vertx-core
 4.3.7
210 with no arguments

Vertx vertx = Vertx.vertx[];
11

Using the request as a stream

An


 io.vertx
 vertx-core
 4.3.7
196 instance is also a
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90 instance

You can pipe to it from any

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89 instance

For, example, you could pipe a file on disk to a http request body as follows

Vertx vertx = Vertx.vertx[];
12

Chunked HTTP requests

Vert. x supports HTTP Chunked Transfer Encoding for requests

This allows the HTTP request body to be written in chunks, and is normally used when a large request body is being streamed to the server, whose size is not known in advance

Bạn đặt yêu cầu HTTP ở chế độ chunked bằng cách sử dụng


 io.vertx
 vertx-core
 4.3.7
224

In chunked mode each call to write will cause a new chunk to be written to the wire. In chunked mode there is no need to set the


 io.vertx
 vertx-core
 4.3.7
135 of the request up-front

Vertx vertx = Vertx.vertx[];
13

Request timeouts

You can set a timeout for a specific http request using


 io.vertx
 vertx-core
 4.3.7
226 or

 io.vertx
 vertx-core
 4.3.7
227

Nếu yêu cầu không trả lại bất kỳ dữ liệu nào trong khoảng thời gian chờ, một ngoại lệ sẽ được chuyển đến trình xử lý ngoại lệ [nếu được cung cấp] và yêu cầu sẽ bị đóng

Writing HTTP/2 frames

HTTP/2 is a framed protocol with various frames for the HTTP request/response model. The protocol allows other kind of frames to be sent and received

To send such frames, you can use the

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
77 on the request. Here’s an example

Vertx vertx = Vertx.vertx[];
14

Stream reset

HTTP/1. x does not allow a clean reset of a request or a response stream, for example when a client uploads a resource already present on the server, the server needs to accept the entire response

HTTP/2 supports stream reset at any time during the request/response

Vertx vertx = Vertx.vertx[];
15

By default the NO_ERROR [0] error code is sent, another code can sent instead

Vertx vertx = Vertx.vertx[];
16

The HTTP/2 specification defines the list of error codes one can use

The request handler are notified of stream reset events with the


 io.vertx
 vertx-core
 4.3.7
229 and

 io.vertx
 vertx-core
 4.3.7
230

Vertx vertx = Vertx.vertx[];
17

Handling HTTP responses

You receive an instance of


 io.vertx
 vertx-core
 4.3.7
200 into the handler that you specify in of the request methods or by setting a handler directly on the

 io.vertx
 vertx-core
 4.3.7
196 object

You can query the status code and the status message of the response with


 io.vertx
 vertx-core
 4.3.7
233 and

 io.vertx
 vertx-core
 4.3.7
234

Vertx vertx = Vertx.vertx[];
18

Using the response as a stream

The


 io.vertx
 vertx-core
 4.3.7
200 instance is also a
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89 which means you can pipe it to any
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90 instance

Response headers and trailers

Http responses can contain headers. Use


 io.vertx
 vertx-core
 4.3.7
238 to get the headers

The object returned is a


 io.vertx
 vertx-core
 4.3.7
087 as HTTP headers can contain multiple values for single keys

Vertx vertx = Vertx.vertx[];
19

Chunked HTTP responses can also contain trailers - these are sent in the last chunk of the response body

You use


 io.vertx
 vertx-core
 4.3.7
240 to get the trailers. Trailers are also a

 io.vertx
 vertx-core
 4.3.7
087

Reading the request body

The response handler is called when the headers of the response have been read from the wire

If the response has a body this might arrive in several pieces some time after the headers have been read. We don’t wait for all the body to arrive before calling the response handler as the response could be very large and we might be waiting a long time, or run out of memory for large responses

As parts of the response body arrive, the


 io.vertx
 vertx-core
 4.3.7
242 is called with a
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
76 representing the piece of the body

Vertx vertx = Vertx.vertx[];
20

If you know the response body is not very large and want to aggregate it all in memory before handling it, you can either aggregate it yourself

Vertx vertx = Vertx.vertx[];
21

Or you can use the convenience


 io.vertx
 vertx-core
 4.3.7
244 which is called with the entire body when the response has been fully read

Vertx vertx = Vertx.vertx[];
22

Response end handler

The response


 io.vertx
 vertx-core
 4.3.7
245 is called when the entire response body has been read or immediately after the headers have been read and the response handler has been called if there is no body

Request and response composition

The client interface is very simple and follows this pattern

  1. 
     io.vertx
     vertx-core
     4.3.7
    
    197 a connection

  2. 
     io.vertx
     vertx-core
     4.3.7
    
    208 or
    
     io.vertx
     vertx-core
     4.3.7
    
    137/
    
     io.vertx
     vertx-core
     4.3.7
    
    210 the request to the server

  3. handle the beginning of the

    
     io.vertx
     vertx-core
     4.3.7
    
    200

  4. process the response events

You can use Vert. x future composition methods to make your code simpler, however the API is event driven and you need to understand it otherwise you might experience possible data races [i. e loosing events leading to corrupted data]

Ghi chú

Vert. x Web Client là một giải pháp thay thế API cấp cao hơn [trên thực tế, nó được xây dựng dựa trên ứng dụng khách này], bạn có thể cân nhắc nếu ứng dụng khách này ở mức quá thấp đối với các trường hợp sử dụng của bạn

The client API intentionally does not return a


 io.vertx
 vertx-core
 4.3.7
251 because setting a completion handler on the future can be racy when this is set outside of the event-loop

Vertx vertx = Vertx.vertx[];
23

Confining the


 io.vertx
 vertx-core
 4.3.7
252 usage within a verticle is the easiest solution as the Verticle will ensure that events are processed sequentially avoiding races

Vertx vertx = Vertx.vertx[];
24

When you are interacting with the client possibly outside a verticle then you can safely perform composition as long as you do not delay the response events, e. g processing directly the response on the event-loop

Vertx vertx = Vertx.vertx[];
25

If you need to delay the response processing then you need to


 io.vertx
 vertx-core
 4.3.7
253 the response or use a

 io.vertx
 vertx-core
 4.3.7
254, this might be necessary when another asynchronous operation is involved

Vertx vertx = Vertx.vertx[];
26

Reading cookies from the response

You can retrieve the list of cookies from a response using


 io.vertx
 vertx-core
 4.3.7
255

Alternatively you can just parse the


 io.vertx
 vertx-core
 4.3.7
256 headers yourself in the response

30x redirection handling

The client can be configured to follow HTTP redirections provided by the


 io.vertx
 vertx-core
 4.3.7
257 response header when the client receives

  • a

    
     io.vertx
     vertx-core
     4.3.7
    
    258,
    
     io.vertx
     vertx-core
     4.3.7
    
    259,
    
     io.vertx
     vertx-core
     4.3.7
    
    260 or
    
     io.vertx
     vertx-core
     4.3.7
    
    261 status code along with a HTTP GET or HEAD method

  • a

    
     io.vertx
     vertx-core
     4.3.7
    
    262 status code, in addition the directed request perform an HTTP GET method

Here’s an example

Vertx vertx = Vertx.vertx[];
27

The maximum redirects is


 io.vertx
 vertx-core
 4.3.7
263 by default and can be changed with

 io.vertx
 vertx-core
 4.3.7
264

Vertx vertx = Vertx.vertx[];
28

One size does not fit all and the default redirection policy may not be adapted to your needs

The default redirection policy can changed with a custom implementation

Vertx vertx = Vertx.vertx[];
29

The policy handles the original


 io.vertx
 vertx-core
 4.3.7
200 received and returns either

 io.vertx
 vertx-core
 4.3.7
266 or a

 io.vertx
 vertx-core
 4.3.7
267

  • when

    
     io.vertx
     vertx-core
     4.3.7
    
    266 is returned, the original response is processed

  • when a future is returned, the request will be sent on its successful completion

  • when a future is returned, the exception handler set on the request is called on its failure

The returned request must be unsent so the original request handlers can be sent and the client can send it after

Most of the original request settings will be propagated to the new request

  • request headers, unless if you have set some headers

  • request body unless the returned request uses a

    
     io.vertx
     vertx-core
     4.3.7
    
    199 method

  • response handler

  • yêu cầu xử lý ngoại lệ

  • request timeout

100-Continue handling

According to the HTTP 1. 1 specification a client can set a header


 io.vertx
 vertx-core
 4.3.7
270 and send the request header before sending the rest of the request body

The server can then respond with an interim response status


 io.vertx
 vertx-core
 4.3.7
271 to signify to the client that it is ok to send the rest of the body

The idea here is it allows the server to authorise and accept/reject the request before large amounts of data are sent. Sending large amounts of data if the request might not be accepted is a waste of bandwidth and ties up the server in reading data that it will just discard

Vert. x allows you to set a


 io.vertx
 vertx-core
 4.3.7
272 on the client request object

This will be called if the server sends back a


 io.vertx
 vertx-core
 4.3.7
271 response to signify that it is ok to send the rest of the request

This is used in conjunction with `sendHead`to send the head of the request

Here’s an example

Vertx vertx = Vertx.vertx[];
30

On the server side a Vert. x http server can be configured to automatically send back 100 Continue interim responses when it receives an


 io.vertx
 vertx-core
 4.3.7
270 header

This is done by setting the option


 io.vertx
 vertx-core
 4.3.7
275

If you’d prefer to decide whether to send back continue responses manually, then this property should be set to

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
20 [the default], then you can inspect the headers and call

 io.vertx
 vertx-core
 4.3.7
277 to have the client continue sending the body

Vertx vertx = Vertx.vertx[];
31

You can also reject the request by sending back a failure status code directly. in this case the body should either be ignored or the connection should be closed [100-Continue is a performance hint and cannot be a logical protocol constraint]

Vertx vertx = Vertx.vertx[];
32

Creating HTTP tunnels

HTTP tunnels can be created with


 io.vertx
 vertx-core
 4.3.7
278

Vertx vertx = Vertx.vertx[];
33

The handler will be called after the HTTP response header is received, the socket will be ready for tunneling and will send and receive buffers


 io.vertx
 vertx-core
 4.3.7
279 works like

 io.vertx
 vertx-core
 4.3.7
208, but it reconfigures the transport to exchange raw buffers

Client push

Server push is a new feature of HTTP/2 that enables sending multiple responses in parallel for a single client request

A push handler can be set on a request to receive the request/response pushed by the server

Vertx vertx = Vertx.vertx[];
34

If the client does not want to receive a pushed request, it can reset the stream

Vertx vertx = Vertx.vertx[];
35

When no handler is set, any stream pushed will be automatically cancelled by the client with a stream reset [


 io.vertx
 vertx-core
 4.3.7
281 error code]

Receiving custom HTTP/2 frames

HTTP/2 is a framed protocol with various frames for the HTTP request/response model. The protocol allows other kind of frames to be sent and received

To receive custom frames, you can use the customFrameHandler on the request, this will get called every time a custom frame arrives. Here’s an example

Vertx vertx = Vertx.vertx[];
36

Enabling compression on the client

The http client comes with support for HTTP Compression out of the box

This means the client can let the remote http server know that it supports compression, and will be able to handle compressed response bodies

An http server is free to either compress with one of the supported compression algorithms or to send the body back without compressing it at all. So this is only a hint for the Http server which it may ignore at will

To tell the http server which compression is supported by the client it will include an


 io.vertx
 vertx-core
 4.3.7
173 header with the supported compression algorithm as value. Multiple compression algorithms are supported. In case of Vert. x this will result in the following header added

Accept-Encoding. gzip, deflate

The server will choose then from one of these. You can detect if a server compressed the body by checking for the


 io.vertx
 vertx-core
 4.3.7
207 header in the response sent back from it

If the body of the response was compressed via gzip it will include for example the following header

Content-Encoding. gzip

To enable compression set


 io.vertx
 vertx-core
 4.3.7
284 on the options used when creating the client

By default compression is disabled

HTTP/1. x pooling and keep alive

Http keep alive allows http connections to be used for more than one request. This can be a more efficient use of connections when you’re making multiple requests to the same server

For HTTP/1. x versions, the http client supports pooling of connections, allowing you to reuse connections between requests

For pooling to work, keep alive must be true using


 io.vertx
 vertx-core
 4.3.7
285 on the options used when configuring the client. The default value is true

When keep alive is enabled. Vert. x will add a


 io.vertx
 vertx-core
 4.3.7
286 header to each HTTP/1. 0 request sent. When keep alive is disabled. Vert. x will add a

 io.vertx
 vertx-core
 4.3.7
287 header to each HTTP/1. 1 request sent to signal that the connection will be closed after completion of the response

The maximum number of connections to pool for each server is configured using


 io.vertx
 vertx-core
 4.3.7
288

When making a request with pooling enabled, Vert. x will create a new connection if there are less than the maximum number of connections already created for that server, otherwise it will add the request to a queue

Keep alive connections will be closed by the client automatically after a timeout. The timeout can be specified by the server using the


 io.vertx
 vertx-core
 4.3.7
289 header

Vertx vertx = Vertx.vertx[];
37

You can set the default timeout using


 io.vertx
 vertx-core
 4.3.7
290 - any connections not used within this timeout will be closed. Please note the timeout value is in seconds not milliseconds

HTTP/1. 1 pipe-lining

The client also supports pipe-lining of requests on a connection

Pipe-lining means another request is sent on the same connection before the response from the preceding one has returned. Pipe-lining is not appropriate for all requests

To enable pipe-lining, it must be enabled using


 io.vertx
 vertx-core
 4.3.7
291. By default, pipe-lining is disabled

When pipe-lining is enabled requests will be written to connections without waiting for previous responses to return

The number of pipe-lined requests over a single connection is limited by


 io.vertx
 vertx-core
 4.3.7
292. This option defines the maximum number of http requests sent to the server awaiting for a response. This limit ensures the fairness of the distribution of the client requests over the connections to the same server

HTTP/2 multiplexing

HTTP/2 advocates to use a single connection to a server, by default the http client uses a single connection for each server, all the streams to the same server are multiplexed over the same connection

When the clients needs to use more than a single connection and use pooling, the


 io.vertx
 vertx-core
 4.3.7
293 shall be used

When it is desirable to limit the number of multiplexed streams per connection and use a connection pool instead of a single connection,


 io.vertx
 vertx-core
 4.3.7
294 can be used

Vertx vertx = Vertx.vertx[];
38

The multiplexing limit for a connection is a setting set on the client that limits the number of streams of a single connection. The effective value can be even lower if the server sets a lower limit with the


 io.vertx
 vertx-core
 4.3.7
295 setting

HTTP/2 connections will not be closed by the client automatically. To close them you can call


 io.vertx
 vertx-core
 4.3.7
296 or close the client instance

Alternatively you can set idle timeout using


 io.vertx
 vertx-core
 4.3.7
297 - any connections not used within this timeout will be closed. Please note the idle timeout value is in seconds not milliseconds

HTTP connections

The


 io.vertx
 vertx-core
 4.3.7
298 offers the API for dealing with HTTP connection events, lifecycle and settings

HTTP/2 implements fully the


 io.vertx
 vertx-core
 4.3.7
298 API

HTTP/1. x implements partially the


 io.vertx
 vertx-core
 4.3.7
298 API. only the close operation, the close handler and exception handler are implemented. This protocol does not provide semantics for the other operations

Server connections

The


 io.vertx
 vertx-core
 4.3.7
501 method returns the request connection on the server

Vertx vertx = Vertx.vertx[];
39

A connection handler can be set on the server to be notified of any incoming connection

Vertx vertx = Vertx.vertx[];
40

Client connections

The


 io.vertx
 vertx-core
 4.3.7
502 method returns the request connection on the client

Vertx vertx = Vertx.vertx[];
39

A connection handler can be set on the client to be notified when a connection has been established happens

Vertx vertx = Vertx.vertx[];
42

Connection settings

The configuration of an HTTP/2 is configured by the


 io.vertx
 vertx-core
 4.3.7
503 data object

Each endpoint must respect the settings sent by the other side of the connection

When a connection is established, the client and the server exchange initial settings. Initial settings are configured by


 io.vertx
 vertx-core
 4.3.7
504 on the client and

 io.vertx
 vertx-core
 4.3.7
505 on the server

The settings can be changed at any time after the connection is established

Vertx vertx = Vertx.vertx[];
43

As the remote side should acknowledge on reception of the settings update, it’s possible to give a callback to be notified of the acknowledgment

Vertx vertx = Vertx.vertx[];
44

Conversely the


 io.vertx
 vertx-core
 4.3.7
506 is notified when the new remote settings are received

Vertx vertx = Vertx.vertx[];
45

Ghi chú

this only applies to the HTTP/2 protocol

Connection ping

HTTP/2 connection ping is useful for determining the connection round-trip time or check the connection validity.


 io.vertx
 vertx-core
 4.3.7
507 sends a {@literal PING} frame to the remote endpoint

Vertx vertx = Vertx.vertx[];
46

Vert. x will send automatically an acknowledgement when a {@literal PING} frame is received, an handler can be set to be notified for each ping received

Vertx vertx = Vertx.vertx[];
47

The handler is just notified, the acknowledgement is sent whatsoever. Such feature is aimed for implementing protocols on top of HTTP/2

Ghi chú

this only applies to the HTTP/2 protocol

Connection shutdown and go away

Calling


 io.vertx
 vertx-core
 4.3.7
508 will send a {@literal GOAWAY} frame to the remote side of the connection, asking it to stop creating streams. a client will stop doing new requests and a server will stop pushing responses. After the {@literal GOAWAY} frame is sent, the connection waits some time [30 seconds by default] until all current streams closed and close the connection

Vertx vertx = Vertx.vertx[];
48

The


 io.vertx
 vertx-core
 4.3.7
509 notifies when all streams have been closed, the connection is not yet closed

It’s possible to just send a {@literal GOAWAY} frame, the main difference with a shutdown is that it will just tell the remote side of the connection to stop creating new streams without scheduling a connection close

Vertx vertx = Vertx.vertx[];
49

Conversely, it is also possible to be notified when {@literal GOAWAY} are received

Vertx vertx = Vertx.vertx[];
50

The


 io.vertx
 vertx-core
 4.3.7
509 will be called when all current streams have been closed and the connection can be closed

Vertx vertx = Vertx.vertx[];
51

This applies also when a {@literal GOAWAY} is received

Ghi chú

this only applies to the HTTP/2 protocol

Connection close

Connection


 io.vertx
 vertx-core
 4.3.7
296 closes the connection

  • it closes the socket for HTTP/1. x

  • HTTP/2 tắt mà không có độ trễ, khung {@literal GOAWAY} sẽ vẫn được gửi trước khi đóng kết nối. *

The


 io.vertx
 vertx-core
 4.3.7
512 notifies when a connection is closed

Client sharing

You can share an HTTP client between multiple verticles or instances of the same verticle. Such client should be created outside of a verticle otherwise it will be closed when the verticle that created it is undeployed

Vertx vertx = Vertx.vertx[];
52

You can also create a shared HTTP client in each verticle

Vertx vertx = Vertx.vertx[];
53

The first time a shared client is created it will create and return a client. Subsequent calls will reuse this client and create a lease to this client. The client is closed after all leases have been disposed

By default, a client reuses the current event-loop when it needs to create a TCP connection. The HTTP client will therefore randomly use event-loops of verticles using it in a safe fashion

Bạn có thể chỉ định một số vòng lặp sự kiện mà máy khách sẽ sử dụng độc lập với máy khách sử dụng nó

Vertx vertx = Vertx.vertx[];
54

Server sharing

When several HTTP servers listen on the same port, vert. x orchestrates the request handling using a round-robin strategy

Let’s take a verticle creating a HTTP server such as

io. vertx. examples. http. sharing. HttpServerVerticle

Vertx vertx = Vertx.vertx[];
55

Dịch vụ này đang lắng nghe trên cổng 8080. So, when this verticle is instantiated multiple times as with.


 io.vertx
 vertx-core
 4.3.7
513, what’s happening ? If both verticles would bind to the same port, you would receive a socket exception. Fortunately, vert. x is handling this case for you. When you deploy another server on the same host and port as an existing server it doesn’t actually try and create a new server listening on the same host/port. Nó chỉ liên kết một lần với ổ cắm. When receiving a request it calls the server handlers following a round robin strategy

Let’s now imagine a client such as

Vertx vertx = Vertx.vertx[];
56

Vert. x delegates the requests to one of the server sequentially

Vertx vertx = Vertx.vertx[];
57

Consequently the servers can scale over available cores while each Vert. x verticle instance remains strictly single threaded, and you don’t have to do any special tricks like writing load-balancers in order to scale your server on your multi-core machine

You can bind on a shared random ports using a negative port value, the first bind will pick a port randomly, subsequent binds on the same port value will share this random port

io. vertx. examples. http. sharing. HttpServerVerticle

Vertx vertx = Vertx.vertx[];
58

Using HTTPS with Vert. x

Vert. máy chủ x http và máy khách có thể được định cấu hình để sử dụng HTTPS theo cách giống hệt như máy chủ mạng

Please see configuring net servers to use SSL for more information

SSL can also be enabled/disabled per request with


 io.vertx
 vertx-core
 4.3.7
514 or when specifying a scheme with

 io.vertx
 vertx-core
 4.3.7
515 method

Vertx vertx = Vertx.vertx[];
59

The


 io.vertx
 vertx-core
 4.3.7
516 setting acts as the default client setting

The


 io.vertx
 vertx-core
 4.3.7
517 overrides the default client setting

  • setting the value to

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    20 will disable SSL/TLS even if the client is configured to use SSL/TLS

  • setting the value to

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    19 will enable SSL/TLS even if the client is configured to not use SSL/TLS, the actual client SSL/TLS [such as trust, key/certificate, ciphers, ALPN, …​] will be reused

Likewise


 io.vertx
 vertx-core
 4.3.7
515 scheme also overrides the default client setting

Server Name Indication [SNI]

Vert. x http servers can be configured to use SNI in exactly the same way as {@linkplain io. vertx. core. net net servers}

Vert. x http client will present the actual hostname as server name during the TLS handshake

WebSockets

WebSockets là một công nghệ web cho phép kết nối giống như ổ cắm song công hoàn toàn giữa máy chủ HTTP và máy khách HTTP [thường là trình duyệt]

Vert. x supports WebSockets on both the client and server-side

WebSockets on the server

There are two ways of handling WebSockets on the server side

WebSocket handler

The first way involves providing a


 io.vertx
 vertx-core
 4.3.7
168 on the server instance

When a WebSocket connection is made to the server, the handler will be called, passing in an instance of


 io.vertx
 vertx-core
 4.3.7
522

Vertx vertx = Vertx.vertx[];
60

You can choose to reject the WebSocket by calling


 io.vertx
 vertx-core
 4.3.7
523

Vertx vertx = Vertx.vertx[];
61

You can perform an asynchronous handshake by calling


 io.vertx
 vertx-core
 4.3.7
524 with a
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50

Vertx vertx = Vertx.vertx[];
62

Ghi chú

the WebSocket will be automatically accepted after the handler is called unless the WebSocket’s handshake has been set

Upgrading to WebSocket

The second way of handling WebSockets is to handle the HTTP Upgrade request that was sent from the client, and call


 io.vertx
 vertx-core
 4.3.7
526 on the server request

Vertx vertx = Vertx.vertx[];
63

The server WebSocket

The


 io.vertx
 vertx-core
 4.3.7
522 instance enables you to retrieve the

 io.vertx
 vertx-core
 4.3.7
528,

 io.vertx
 vertx-core
 4.3.7
529,

 io.vertx
 vertx-core
 4.3.7
530 and

 io.vertx
 vertx-core
 4.3.7
531 of the HTTP request of the WebSocket handshake

WebSockets on the client

The Vert. x


 io.vertx
 vertx-core
 4.3.7
182 supports WebSockets

You can connect a WebSocket to a server using one of the


 io.vertx
 vertx-core
 4.3.7
533 operations and providing a handler

The handler will be called with an instance of


 io.vertx
 vertx-core
 4.3.7
154 when the connection has been made

Vertx vertx = Vertx.vertx[];
64

By default, the client sets the


 io.vertx
 vertx-core
 4.3.7
535 header to the server host, e. g http. //www. example. com. Some servers will refuse such request, you can configure the client to not set this header

Vertx vertx = Vertx.vertx[];
65

You can also set a different header

Vertx vertx = Vertx.vertx[];
66

Ghi chú

older versions of the WebSocket protocol use

 io.vertx
 vertx-core
 4.3.7
536 instead

Writing messages to WebSockets

If you wish to write a single WebSocket message to the WebSocket you can do this with


 io.vertx
 vertx-core
 4.3.7
537 or

 io.vertx
 vertx-core
 4.3.7
538

Vertx vertx = Vertx.vertx[];
67

If the WebSocket message is larger than the maximum WebSocket frame size as configured with


 io.vertx
 vertx-core
 4.3.7
539 then Vert. x sẽ chia nó thành nhiều khung WebSocket trước khi gửi nó trên dây

Writing frames to WebSockets

A WebSocket message can be composed of multiple frames. Trong trường hợp này, khung đầu tiên là khung nhị phân hoặc khung văn bản, theo sau là 0 hoặc nhiều khung tiếp theo

The last frame in the message is marked as final

To send a message consisting of multiple frames you create frames using


 io.vertx
 vertx-core
 4.3.7
540 ,

 io.vertx
 vertx-core
 4.3.7
541 or

 io.vertx
 vertx-core
 4.3.7
542 and write them to the WebSocket using

 io.vertx
 vertx-core
 4.3.7
543

Here’s an example for binary frames

Vertx vertx = Vertx.vertx[];
68

In many cases you just want to send a WebSocket message that consists of a single final frame, so we provide a couple of shortcut methods to do that with


 io.vertx
 vertx-core
 4.3.7
544 and

 io.vertx
 vertx-core
 4.3.7
545

Here’s an example

Vertx vertx = Vertx.vertx[];
69

Reading frames from WebSockets

To read frames from a WebSocket you use the


 io.vertx
 vertx-core
 4.3.7
546

The frame handler will be called with instances of


 io.vertx
 vertx-core
 4.3.7
547 when a frame arrives, for example

Vertx vertx = Vertx.vertx[];
70

Closing WebSockets

Use


 io.vertx
 vertx-core
 4.3.7
548 to close the WebSocket connection when you have finished with it

Piping WebSockets

The


 io.vertx
 vertx-core
 4.3.7
154 instance is also a
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89 and a
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90 so it can be used with pipes

When using a WebSocket as a write stream or a read stream it can only be used with WebSockets connections that are used with binary frames that are no split over multiple frames

Event bus handlers

Every WebSocket automatically registers two handler on the event bus, and when any data are received in this handler, it writes them to itself. Those are local subscriptions not routed on the cluster

This enables you to write data to a WebSocket which is potentially in a completely different verticle sending data to the address of that handler

The addresses of the handlers are given by


 io.vertx
 vertx-core
 4.3.7
552 and

 io.vertx
 vertx-core
 4.3.7
553

Using a proxy for HTTP/HTTPS connections

Máy khách http hỗ trợ truy cập các URL http/https qua proxy HTTP [e. g. Squid] or SOCKS4a or SOCKS5 proxy. The CONNECT protocol uses HTTP/1. x but can connect to HTTP/1. x and HTTP/2 servers

Connecting to h2c [unencrypted HTTP/2 servers] is likely not supported by http proxies since they will support HTTP/1. 1 only

The proxy can be configured in the


 io.vertx
 vertx-core
 4.3.7
554 by setting a

 io.vertx
 vertx-core
 4.3.7
044 object containing proxy type, hostname, port and optionally username and password

Here’s an example of using an HTTP proxy

Vertx vertx = Vertx.vertx[];
71

When the client connects to an http URL, it connects to the proxy server and provides the full URL in the HTTP request ["GET http. //www. somehost. com/path/file. html HTTP/1. 1"]

When the client connects to an https URL, it asks the proxy to create a tunnel to the remote host with the CONNECT method

For a SOCKS5 proxy

Vertx vertx = Vertx.vertx[];
72

The DNS resolution is always done on the proxy server, to achieve the functionality of a SOCKS4 client, it is necessary to resolve the DNS address locally

Proxy options can also be set per request

Vertx vertx = Vertx.vertx[];
73

Ghi chú

client connection pooling is aware of proxies [including authentication], consequently two requests to the same host through different proxies do not share the same pooled connection

You can use


 io.vertx
 vertx-core
 4.3.7
556 to configure a list of host bypassing the proxy. The lists accept

 io.vertx
 vertx-core
 4.3.7
046 wildcard for matching domains

Vertx vertx = Vertx.vertx[];
74

Handling of other protocols

The HTTP proxy implementation supports getting ftp. // urls if the proxy supports that

When the HTTP request URI contains the full URL then the client will not compute a full HTTP url and instead use the full URL specified in the request URI

Vertx vertx = Vertx.vertx[];
75

Using HA PROXY protocol

HA PROXY protocol provides a convenient way to safely transport connection information such as a client’s address across multiple layers of NAT or TCP proxies

HA PROXY protocol can be enabled by setting the option


 io.vertx
 vertx-core
 4.3.7
558 and adding the following dependency in your classpath

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
45

Vertx vertx = Vertx.vertx[];
77

Automatic clean-up in verticles

If you’re creating http servers and clients from inside verticles, those servers and clients will be automatically closed when the verticle is undeployed

Using the SharedData API

As its name suggests, the


 io.vertx
 vertx-core
 4.3.7
559 API allows you to safely share data between

  • các phần khác nhau của ứng dụng của bạn, hoặc

  • different applications in the same Vert. x instance, or

  • different applications across a cluster of Vert. x instances

In practice, it provides

  • synchronous maps [local-only]

  • asynchronous maps

  • khóa không đồng bộ

  • asynchronous counters

Important

The behavior of the distributed data structure depends on the cluster manager you use. Backup [replication] and behavior when a network partition is faced are defined by the cluster manager and its configuration. Please refer to the cluster manager documentation as well as to the underlying framework manual

Local maps


 io.vertx
 vertx-core
 4.3.7
560 allow you to share data safely between different event loops [e. g. different verticles] in the same Vert. x instance

They only allow certain data types to be used as keys and values

  • immutable types [e. g. strings, booleans, …​ etc], or

  • types implementing the

    
     io.vertx
     vertx-core
     4.3.7
    
    561 interface [buffers, JSON arrays, JSON objects, or your own shareable objects]

In the latter case the key/value will be copied before putting it into the map

This way we can ensure there is no shared access to mutable state between different threads in your Vert. x application. And you won’t have to worry about protecting that state by synchronising access to it

Ghi chú

As a convenience, objects implementing

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
27 or
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
28 can be used as keys and values too. In this case, the key/value will be copied before putting it into the map by serializing/deserializing. Therefore, it is recommended to consider implementing

 io.vertx
 vertx-core
 4.3.7
561 instead for better performance

Here’s an example of using a shared local map

Vertx vertx = Vertx.vertx[];
78

Asynchronous shared maps


 io.vertx
 vertx-core
 4.3.7
565 allow data to be put in the map and retrieved locally or from any other node

This makes them really useful for things like storing session state in a farm of servers hosting a Vert. x Web application

They only allow certain data types to be used as keys and values

  • immutable types [e. g. strings, booleans, …​ etc], or

  • types implementing the

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    27 interface [buffers, JSON arrays, JSON objects, or your own cluster serializable objects], or

  • các loại triển khai giao diện

    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    28

Getting the map is asynchronous and the result is returned to you in the handler that you specify. Here’s an example

Vertx vertx = Vertx.vertx[];
79

When Vert. x được phân cụm, dữ liệu mà bạn đưa vào bản đồ có thể truy cập cục bộ cũng như trên bất kỳ thành viên nào khác của cụm

Important

In clustered mode, asynchronous shared maps rely on distributed data structures provided by the cluster manager. Beware that the latency relative to asynchronous shared map operations can be much higher in clustered than in local mode

If your application doesn’t need data to be shared with every other node, you can retrieve a local-only map

Vertx vertx = Vertx.vertx[];
80

Putting data in a map

You put data in a map with


 io.vertx
 vertx-core
 4.3.7
568

The actual put is asynchronous and the handler is notified once it is complete

Vertx vertx = Vertx.vertx[];
81

Getting data from a map

You get data from a map with


 io.vertx
 vertx-core
 4.3.7
569

The actual get is asynchronous and the handler is notified with the result some time later

Vertx vertx = Vertx.vertx[];
82

Other map operations

You can also remove entries from an asynchronous map, clear them and get the size

See the


 io.vertx
 vertx-core
 4.3.7
570 for a detailed list of map operations

Asynchronous locks


 io.vertx
 vertx-core
 4.3.7
571 allow you to obtain exclusive locks locally or across the cluster. This is useful when you want to do something or access a resource on only one node of a cluster at any one time

Asynchronous locks have an asynchronous API unlike most lock APIs which block the calling thread until the lock is obtained

To obtain a lock use


 io.vertx
 vertx-core
 4.3.7
572. This won’t block, but when the lock is available, the handler will be called with an instance of

 io.vertx
 vertx-core
 4.3.7
573, signalling that you now own the lock

While you own the lock, no other caller, locally or on the cluster, will be able to obtain the lock

When you’ve finished with the lock, you call


 io.vertx
 vertx-core
 4.3.7
574 to release it, so another caller can obtain it

Vertx vertx = Vertx.vertx[];
83

You can also get a lock with a timeout. If it fails to obtain the lock within the timeout the handler will be called with a failure

Vertx vertx = Vertx.vertx[];
84

See the


 io.vertx
 vertx-core
 4.3.7
575 for a detailed list of lock operations

Important

In clustered mode, asynchronous locks rely on distributed data structures provided by the cluster manager. Beware that the latency relative to asynchronous shared lock operations can be much higher in clustered than in local mode

If your application doesn’t need the lock to be shared with every other node, you can retrieve a local-only lock

Vertx vertx = Vertx.vertx[];
85

Asynchronous counters

It’s often useful to maintain an atomic counter locally or across the different nodes of your application

You can do this with


 io.vertx
 vertx-core
 4.3.7
576

You obtain an instance with


 io.vertx
 vertx-core
 4.3.7
577

Vertx vertx = Vertx.vertx[];
86

Once you have an instance you can retrieve the current count, atomically increment it, decrement and add a value to it using the various methods

Xem


 io.vertx
 vertx-core
 4.3.7
578 để biết danh sách chi tiết các hoạt động truy cập

Important

In clustered mode, asynchronous counters rely on distributed data structures provided by the cluster manager. Beware that the latency relative to asynchronous shared counter operations can be much higher in clustered than in local mode

If your application doesn’t need the counter to be shared with every other node, you can retrieve a local-only counter

Vertx vertx = Vertx.vertx[];
87

Using the file system with Vert. x

The Vert. x


 io.vertx
 vertx-core
 4.3.7
579 object provides many operations for manipulating the file system

There is one file system object per Vert. x instance, and you obtain it with


 io.vertx
 vertx-core
 4.3.7
580

A blocking and a non blocking version of each operation is provided. Các phiên bản không chặn có một trình xử lý được gọi khi thao tác hoàn tất hoặc xảy ra lỗi

Đây là một ví dụ về một bản sao không đồng bộ của một tập tin

Vertx vertx = Vertx.vertx[];
88

The blocking versions are named


 io.vertx
 vertx-core
 4.3.7
581 and return the results or throw exceptions directly. In many cases, depending on the operating system and file system, some of the potentially blocking operations can return quickly, which is why we provide them, but it’s highly recommended that you test how long they take to return in your particular application before using them from an event loop, so as not to break the Golden Rule

Here’s the copy using the blocking API

Vertx vertx = Vertx.vertx[];
89

Many operations exist to copy, move, truncate, chmod and many other file operations. Chúng tôi sẽ không liệt kê tất cả ở đây, vui lòng tham khảo


 io.vertx
 vertx-core
 4.3.7
582 để biết danh sách đầy đủ

Let’s see a couple of examples using asynchronous methods

Vertx vertx = Vertx.vertx[];
90

Asynchronous files

Vert. x provides an asynchronous file abstraction that allows you to manipulate a file on the file system

You open an


 io.vertx
 vertx-core
 4.3.7
145 as follows

Vertx vertx = Vertx.vertx[];
91


 io.vertx
 vertx-core
 4.3.7
584 implements

 io.vertx
 vertx-core
 4.3.7
585 and

 io.vertx
 vertx-core
 4.3.7
586 so you can pipe files to and from other stream objects such as net sockets, http requests and responses, and WebSockets

They also allow you to read and write directly to them

Random access writes

To use an


 io.vertx
 vertx-core
 4.3.7
584 for random access writing you use the

 io.vertx
 vertx-core
 4.3.7
588 method

The parameters to the method are

  • 
     io.vertx
     vertx-core
     4.3.7
    
    589. the buffer to write

  • 
     io.vertx
     vertx-core
     4.3.7
    
    590. an integer position in the file where to write the buffer. If the position is greater or equal to the size of the file, the file will be enlarged to accommodate the offset

  • 
     io.vertx
     vertx-core
     4.3.7
    
    591. the result handler

Here is an example of random access writes

Vertx vertx = Vertx.vertx[];
92

Random access reads

To use an


 io.vertx
 vertx-core
 4.3.7
584 for random access reads you use the

 io.vertx
 vertx-core
 4.3.7
593 method

The parameters to the method are

  • 
     io.vertx
     vertx-core
     4.3.7
    
    589. the buffer into which the data will be read

  • 
     io.vertx
     vertx-core
     4.3.7
    
    595. an integer offset into the buffer where the read data will be placed

  • 
     io.vertx
     vertx-core
     4.3.7
    
    590. the position in the file where to read data from

  • 
     io.vertx
     vertx-core
     4.3.7
    
    597. the number of bytes of data to read

  • 
     io.vertx
     vertx-core
     4.3.7
    
    591. the result handler

Here’s an example of random access reads

Vertx vertx = Vertx.vertx[];
93

Opening Options

When opening an


 io.vertx
 vertx-core
 4.3.7
584, you pass an
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
000 instance. These options describe the behavior of the file access. For instance, you can configure the file permissions with the
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
001,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
002 and
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
003 methods

You can also configure the behavior if the open file already exists with

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
004 and
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
005

Bạn cũng có thể đánh dấu tệp sẽ bị xóa khi đóng hoặc khi tắt JVM bằng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
006

Flushing data to underlying storage

In the

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
007, you can enable/disable the automatic synchronisation of the content on every write using
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
008. In that case, you can manually flush any writes from the OS cache by calling the
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
009 method

This method can also be called with a handler which will be called when the flush is complete

Using AsyncFile as ReadStream and WriteStream


 io.vertx
 vertx-core
 4.3.7
584 implements

 io.vertx
 vertx-core
 4.3.7
585 and

 io.vertx
 vertx-core
 4.3.7
586. You can then use them with a pipe to pipe data to and from other read and write streams. For example, this would copy the content to another

 io.vertx
 vertx-core
 4.3.7
584

Vertx vertx = Vertx.vertx[];
94

You can also use the pipe to write file content into HTTP responses, or more generally in any


 io.vertx
 vertx-core
 4.3.7
586

Accessing files from the classpath

When vert. x không thể tìm thấy tệp trên hệ thống tệp, nó cố giải quyết tệp từ đường dẫn lớp. Lưu ý rằng các đường dẫn tài nguyên đường dẫn lớp không bao giờ bắt đầu bằng _____3015

Do Java không cung cấp quyền truy cập không đồng bộ vào tài nguyên đường dẫn lớp, tệp được sao chép vào hệ thống tệp trong luồng worker khi tài nguyên đường dẫn lớp được truy cập lần đầu tiên và được cung cấp từ đó một cách không đồng bộ. Khi cùng một tài nguyên được truy cập lần thứ hai, tệp từ hệ thống tệp được cung cấp trực tiếp từ hệ thống tệp. Nội dung ban đầu được cung cấp ngay cả khi tài nguyên đường dẫn lớp thay đổi [e. g. trong một hệ thống phát triển]

Hành vi lưu trữ này có thể được đặt trên tùy chọn

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
016. Giá trị mặc định của tùy chọn này là
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
19 trừ khi thuộc tính hệ thống
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
018 được xác định

Theo mặc định, đường dẫn tệp được lưu vào bộ nhớ cache là

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
019 và có thể được tùy chỉnh bằng cách đặt thuộc tính hệ thống
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
020. Khi sử dụng thuộc tính này, lưu ý rằng nó phải tham chiếu đến tiền tố thư mục trong một vị trí có thể đọc/ghi của quy trình, chẳng hạn.
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
021 [Lưu ý rằng không có UUID]

Mỗi đỉnh. x sẽ nối thêm UUID của chính nó để giữ bộ đệm độc lập với các ứng dụng khác nhau chạy trên cùng một máy

Toàn bộ tính năng giải quyết đường dẫn lớp có thể bị vô hiệu hóa trên toàn hệ thống bằng cách đặt thuộc tính hệ thống

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
022 thành
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
19

Ghi chú

các thuộc tính hệ thống này được đánh giá một lần khi lớp
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
024 được tải, vì vậy các thuộc tính này phải được đặt trước khi tải lớp này hoặc dưới dạng thuộc tính hệ thống JVM khi khởi chạy nó

Nếu bạn muốn tắt tính năng phân giải đường dẫn lớp cho một ứng dụng cụ thể nhưng vẫn bật tính năng này theo mặc định trên toàn hệ thống, bạn có thể thực hiện việc này thông qua tùy chọn

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
025

Đóng một AsyncFile

Để đóng một


 io.vertx
 vertx-core
 4.3.7
584 gọi phương thức
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
027. Quá trình đóng không đồng bộ và nếu bạn muốn được thông báo khi quá trình đóng hoàn tất, bạn có thể chỉ định hàm xử lý làm đối số

Ổ cắm gói dữ liệu [UDP]

Sử dụng Giao thức gói dữ liệu người dùng [UDP] với Vert. x is a piece of cake

UDP là một phương thức vận chuyển không có kết nối, về cơ bản có nghĩa là bạn không có kết nối liên tục với một máy ngang hàng từ xa

Thay vào đó, bạn có thể gửi và nhận các gói và địa chỉ từ xa được chứa trong mỗi gói

Bên cạnh đó, UDP này không an toàn như TCP để sử dụng, điều đó có nghĩa là không có gì đảm bảo rằng một gói Datagram gửi sẽ nhận được điểm cuối của nó.

Đảm bảo duy nhất là nó sẽ nhận được đầy đủ hoặc hoàn toàn không

Ngoài ra, bạn thường không thể gửi dữ liệu lớn hơn kích thước MTU của giao diện mạng, điều này là do mỗi gói sẽ được gửi dưới dạng một gói

Tuy nhiên, hãy lưu ý ngay cả khi kích thước gói nhỏ hơn MTU thì nó vẫn có thể bị lỗi

Ở kích thước nào nó sẽ bị lỗi tùy thuộc vào Hệ điều hành, v.v. Vì vậy, quy tắc ngón tay cái là cố gắng gửi các gói nhỏ

Do bản chất của UDP, nó phù hợp nhất với các Ứng dụng mà bạn được phép loại bỏ các gói [ví dụ như ứng dụng giám sát]

Lợi ích là nó có chi phí hoạt động ít hơn rất nhiều so với TCP, có thể được xử lý bởi NetServer và NetClient [xem bên trên]

Tạo một DatagramSocket

Để sử dụng UDP, trước tiên bạn cần tạo một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028. Không thành vấn đề ở đây nếu bạn chỉ muốn gửi dữ liệu hoặc gửi và nhận

Vertx vertx = Vertx.vertx[];
95

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028 được trả lại sẽ không bị ràng buộc với một cổng cụ thể. Đây không phải là vấn đề nếu bạn chỉ muốn gửi dữ liệu [chẳng hạn như máy khách], nhưng sẽ có nhiều vấn đề hơn trong phần tiếp theo

Gửi gói Datagram

Như đã đề cập trước đây, Giao thức gói dữ liệu người dùng [UDP] gửi dữ liệu trong các gói đến các đồng nghiệp từ xa nhưng không được kết nối với chúng theo kiểu liên tục

Điều này có nghĩa là mỗi gói có thể được gửi đến một máy ngang hàng từ xa khác nhau

Sending packets is as easy as shown here

Vertx vertx = Vertx.vertx[];
96

Nhận gói Datagram

Nếu bạn muốn nhận các gói, bạn cần liên kết

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028 bằng cách gọi
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
031 trên đó

Bằng cách này, bạn sẽ có thể nhận được

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
032 lượt nghe

Bên cạnh đó, bạn cũng muốn đặt một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
033 sẽ được gọi cho mỗi
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
034 nhận được

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
034 có các phương pháp sau

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    036. InetSocketAddress đại diện cho người gửi gói tin

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    037. Bộ đệm chứa dữ liệu nhận được

Vì vậy, để lắng nghe một địa chỉ và cổng cụ thể, bạn sẽ thực hiện một số thao tác như được hiển thị tại đây

Vertx vertx = Vertx.vertx[];
97

Xin lưu ý rằng ngay cả khi {code AsyncResult} thành công, điều đó chỉ có nghĩa là nó có thể được ghi trên ngăn xếp mạng, nhưng không đảm bảo rằng nó đã từng hoặc sẽ đến được với máy ngang hàng từ xa

Nếu bạn cần một sự đảm bảo như vậy thì bạn muốn sử dụng TCP với một số logic bắt tay được xây dựng ở trên cùng

phát đa hướng

Gửi gói Multicast

Multicast cho phép nhiều ổ cắm nhận cùng một gói. Điều này hoạt động bằng cách để các ổ cắm tham gia cùng một nhóm phát đa hướng mà sau đó bạn có thể gửi các gói

Chúng tôi sẽ xem xét cách bạn có thể tham gia Nhóm Multicast và nhận các gói trong phần tiếp theo

Sending multicast packets is not different from sending normal Datagram packets. Sự khác biệt là bạn chuyển địa chỉ nhóm phát đa hướng sang phương thức gửi

Đây là chương trình ở đây

Vertx vertx = Vertx.vertx[];
98

Tất cả các ổ cắm đã tham gia nhóm phát đa hướng 230. 0. 0. 1 sẽ nhận được gói tin

Nhận gói Multicast

Nếu bạn muốn nhận các gói cho nhóm Multicast cụ thể, bạn cần liên kết

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028 bằng cách gọi
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
039 trên đó để tham gia nhóm Multicast

Bằng cách này, bạn sẽ nhận được Gói dữ liệu đã được gửi đến địa chỉ và cổng mà

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028 lắng nghe và cả những gói được gửi đến nhóm Multicast

Bên cạnh đó, bạn cũng muốn đặt Trình xử lý sẽ được gọi cho mỗi DatagramPacket nhận được

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
034 có các phương pháp sau

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    042. InetSocketAddress đại diện cho người gửi gói tin

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    043. Bộ đệm chứa dữ liệu nhận được

Vì vậy, để nghe trên một địa chỉ và cổng cụ thể, đồng thời nhận các gói cho nhóm Multicast 230. 0. 0. 1 bạn sẽ làm một cái gì đó như được hiển thị ở đây

Vertx vertx = Vertx.vertx[];
99

Bỏ nghe/rời nhóm Multicast

Đôi khi có những trường hợp bạn muốn nhận các gói cho một nhóm Multicast trong một thời gian giới hạn

Trong tình huống này, trước tiên bạn có thể bắt đầu lắng nghe họ và sau đó bỏ nghe.

This is shown here

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
00

Chặn phát đa hướng

Bên cạnh việc bỏ nghe một địa chỉ Multicast, bạn cũng có thể chặn phát đa hướng cho một địa chỉ người gửi cụ thể

Xin lưu ý rằng điều này chỉ hoạt động trên một số Hệ điều hành và phiên bản kernel. Vì vậy, vui lòng kiểm tra tài liệu Hệ điều hành nếu nó được hỗ trợ

Đây là một tính năng chuyên gia

Để chặn phát đa hướng từ một địa chỉ cụ thể, bạn có thể gọi

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
044 trên DatagramSocket như được hiển thị tại đây

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
01

Thuộc tính DatagramSocket

Khi tạo một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028, bạn có thể đặt nhiều thuộc tính để thay đổi hành vi của nó với đối tượng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
046. Chúng được liệt kê ở đây

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    047 Đặt kích thước bộ đệm gửi theo byte

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    048 Đặt kích thước bộ đệm nhận TCP theo byte

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    049 Nếu đúng thì các địa chỉ ở trạng thái TIME_WAIT có thể được sử dụng lại sau khi chúng đã bị đóng

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    050

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    051 Đặt hoặc xóa tùy chọn ổ cắm SO_BROADCAST. Khi tùy chọn này được đặt, các gói Datagram [UDP] có thể được gửi đến địa chỉ quảng bá của giao diện cục bộ

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    052 Đặt hoặc xóa tùy chọn ổ cắm IP_MULTICAST_LOOP. When this option is set, multicast packets will also be received on the local interface

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    053 Đặt tùy chọn ổ cắm IP_MULTICAST_TTL. TTL là viết tắt của "Time to Live", nhưng trong ngữ cảnh này, nó chỉ định số bước nhảy IP mà một gói được phép đi qua, đặc biệt đối với lưu lượng phát đa hướng. Mỗi bộ định tuyến hoặc cổng chuyển tiếp một gói sẽ giảm TTL. Nếu TTL bị giảm xuống 0 bởi một bộ định tuyến, nó sẽ không được chuyển tiếp

DatagramSocket Địa chỉ cục bộ

Bạn có thể tìm ra địa chỉ cục bộ của ổ cắm [i. e. địa chỉ của phía bên này của Ổ cắm UDP] bằng cách gọi

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
054. Điều này sẽ chỉ trả về một
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
055 nếu bạn đã ràng buộc
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028 với
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
039 trước đó, nếu không nó sẽ trả về giá trị rỗng

Đóng một DatagramSocket

Bạn có thể đóng socket bằng cách gọi phương thức

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
058. Thao tác này sẽ đóng ổ cắm và giải phóng tất cả tài nguyên

máy khách DNS

Thường thì bạn sẽ thấy mình trong các tình huống cần lấy thông tin DNS theo kiểu không đồng bộ. Thật không may, điều này không thể thực hiện được với API được cung cấp cùng với Máy ảo Java. Vì Vert này. x cung cấp API riêng cho độ phân giải DNS hoàn toàn không đồng bộ

Để có được một phiên bản DnsClient, bạn sẽ tạo một phiên bản mới thông qua phiên bản Vertx

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
02

Bạn cũng có thể tạo ứng dụng khách với các tùy chọn và định cấu hình thời gian chờ truy vấn

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
03

Tạo ứng dụng khách không có đối số hoặc bỏ qua địa chỉ máy chủ sẽ sử dụng địa chỉ của máy chủ được sử dụng nội bộ để giải quyết địa chỉ không chặn

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
04

tra cứu

Cố gắng tra cứu bản ghi A [ipv4] hoặc AAAA [ipv6] cho một tên nhất định. Cái đầu tiên được trả về sẽ được sử dụng, do đó, nó hoạt động giống như cách bạn có thể được sử dụng khi sử dụng "nslookup" trên hệ điều hành của mình

Để tra cứu bản ghi A/AAAA cho "vertx. io" bạn thường sử dụng nó như

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
05

tra cứu4

Cố gắng tra cứu bản ghi A [ipv4] cho một tên nhất định. Cái đầu tiên được trả về sẽ được sử dụng, do đó, nó hoạt động giống như cách bạn có thể được sử dụng khi sử dụng "nslookup" trên hệ điều hành của mình

Để tra cứu bản ghi A cho "vertx. io" bạn thường sử dụng nó như

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
06

tra cứu6

Hãy thử tra cứu bản ghi AAAA [ipv6] cho một tên đã cho. Cái đầu tiên được trả về sẽ được sử dụng, do đó, nó hoạt động giống như cách bạn có thể được sử dụng khi sử dụng "nslookup" trên hệ điều hành của mình

Để tra cứu bản ghi A cho "vertx. io" bạn thường sử dụng nó như

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
07

giải quyếtA

Cố gắng giải quyết tất cả các bản ghi A [ipv4] cho một tên đã cho. Điều này khá giống với việc sử dụng "đào" trên các hệ điều hành giống như unix

To lookup all the A records for "vertx. io" bạn thường làm

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
08

giải quyếtAAAA

Cố gắng giải quyết tất cả các bản ghi AAAA [ipv6] cho một tên đã cho. Điều này khá giống với việc sử dụng "đào" trên các hệ điều hành giống như unix

Để tra cứu tất cả các bản ghi AAAAA cho "vertx. io" bạn thường làm

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
09

giải quyếtCNAME

Cố gắng giải quyết tất cả các bản ghi CNAME cho một tên đã cho. Điều này khá giống với việc sử dụng "đào" trên các hệ điều hành giống như unix

Để tra cứu tất cả các bản ghi CNAME cho "vertx. io" bạn thường làm

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
10

giải quyếtMX

Cố gắng giải quyết tất cả các bản ghi MX cho một tên nhất định. Các bản ghi MX được sử dụng để xác định Máy chủ thư nào chấp nhận email cho một miền nhất định

Để tra cứu tất cả các bản ghi MX cho "vertx. io" bạn thường làm

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
11

Xin lưu ý rằng Danh sách sẽ chứa

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
059 được sắp xếp theo mức độ ưu tiên của chúng, có nghĩa là các bản ghi MX có mức độ ưu tiên nhỏ hơn sẽ xuất hiện trước trong Danh sách

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
059 cho phép bạn truy cập mức độ ưu tiên và tên của bản ghi MX bằng các phương thức cung cấp cho nó như

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
12

giải quyếtTXT

Cố gắng giải quyết tất cả các bản ghi TXT cho một tên nhất định. Bản ghi TXT thường được sử dụng để xác định thông tin bổ sung cho miền

Để giải quyết tất cả các bản ghi TXT cho "vertx. io", bạn có thể sử dụng một cái gì đó dọc theo những dòng này

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
13

giải quyếtNS

Cố gắng giải quyết tất cả các bản ghi NS cho một tên nhất định. Bản ghi NS chỉ định Máy chủ DNS nào lưu trữ thông tin DNS cho một miền nhất định

Để giải quyết tất cả các bản ghi NS cho "vertx. io", bạn có thể sử dụng một cái gì đó dọc theo những dòng này

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
14

giải quyếtSRV

Cố gắng giải quyết tất cả các bản ghi SRV cho một tên nhất định. Bản ghi SRV được sử dụng để xác định thông tin bổ sung như cổng và tên máy chủ của dịch vụ. Một số giao thức cần thêm thông tin này

Để tra cứu tất cả các bản ghi SRV cho "vertx. io" you would typically do

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
15

Xin lưu ý rằng Danh sách sẽ chứa các Bản ghi Srv được sắp xếp theo mức độ ưu tiên của chúng, có nghĩa là các Bản ghi Srv có mức độ ưu tiên nhỏ hơn sẽ xuất hiện trước trong Danh sách

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
061 cho phép bạn truy cập tất cả thông tin có trong bản ghi SRV

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
16

Vui lòng tham khảo tài liệu API để biết chi tiết chính xác

giải quyếtPTR

Cố gắng giải quyết bản ghi PTR cho một tên nhất định. Bản ghi PTR ánh xạ địa chỉ ip thành tên

Để giải quyết bản ghi PTR cho ipaddress 10. 0. 0. 1 bạn sẽ sử dụng khái niệm PTR của "1. 0. 0. 10. trong addr. arpa"

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
17

tra cứu ngược

Hãy thử tra cứu ngược lại địa chỉ ip. Điều này về cơ bản giống như giải quyết bản ghi PTR, nhưng cho phép bạn chỉ chuyển vào ipaddress chứ không phải chuỗi truy vấn PTR hợp lệ

Để thực hiện tra cứu ngược cho ipaddress 10. 0. 0. 1 làm một cái gì đó tương tự như thế này

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
18

Error handling

Như bạn đã thấy trong các phần trước, DnsClient cho phép bạn chuyển vào Trình xử lý sẽ được thông báo bằng AsyncResult sau khi truy vấn hoàn tất. Trong trường hợp có lỗi, nó sẽ được thông báo với một DnsException sẽ tạo ra một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
062 cho biết lý do tại sao độ phân giải không thành công. DnsResponseCode này có thể được sử dụng để kiểm tra nguyên nhân chi tiết hơn

DnsResponseCodes có thể là

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    063 Không tìm thấy bản ghi cho một truy vấn nhất định

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    064 Lỗi định dạng

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    065 Lỗi máy chủ

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    066 Lỗi tên

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    067 Không được triển khai bởi Máy chủ DNS

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    068 Máy chủ DNS từ chối truy vấn

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    069 Tên miền không nên tồn tại

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    070 Bản ghi tài nguyên không nên tồn tại

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    071 RRSET không tồn tại

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    072 Tên không có trong khu vực

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    073 Cơ chế mở rộng không hợp lệ cho phiên bản

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    074 Chữ ký xấu

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    075 Khóa sai

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    076 Dấu thời gian không hợp lệ

All of those errors are "generated" by the DNS Server itself

Bạn có thể lấy DnsResponseCode từ DnsException như

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
19

Dòng

Có một số đối tượng trong Vert. x cho phép các mục được đọc và viết

Trong Vert. x, lệnh gọi ghi trả về ngay lập tức và ghi được xếp hàng đợi nội bộ

Không khó để thấy rằng nếu bạn ghi vào một đối tượng nhanh hơn tốc độ ghi dữ liệu vào tài nguyên cơ bản của nó, thì hàng đợi ghi có thể phát triển không giới hạn - cuối cùng dẫn đến cạn kiệt bộ nhớ

Để giải quyết vấn đề này, một số đối tượng trong Vert cung cấp khả năng điều khiển luồng đơn giản [áp suất ngược]. API x

Bất kỳ đối tượng nhận biết điều khiển luồng nào có thể được ghi vào triển khai

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
90, trong khi bất kỳ đối tượng điều khiển luồng nào có thể đọc từ được cho là triển khai
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89

Hãy lấy một ví dụ mà chúng ta muốn đọc từ một


 io.vertx
 vertx-core
 4.3.7
585 sau đó ghi dữ liệu vào một

 io.vertx
 vertx-core
 4.3.7
586

Một ví dụ rất đơn giản sẽ đọc từ một

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74 sau đó viết lại cho cùng một
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082 - vì
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082 thực hiện cả

 io.vertx
 vertx-core
 4.3.7
585 và

 io.vertx
 vertx-core
 4.3.7
586. Lưu ý rằng điều này hoạt động giữa bất kỳ đối tượng tuân thủ

 io.vertx
 vertx-core
 4.3.7
585 và

 io.vertx
 vertx-core
 4.3.7
586 nào, bao gồm các yêu cầu HTTP, phản hồi HTTP, tệp I/O không đồng bộ, WebSockets, v.v.

Một cách ngây thơ để làm điều này là lấy trực tiếp dữ liệu đã được đọc và ghi ngay vào tệp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
20

Có một vấn đề với ví dụ trên. nếu dữ liệu được đọc từ ổ cắm nhanh hơn dữ liệu có thể được ghi trở lại ổ cắm, dữ liệu sẽ tích tụ trong hàng đợi ghi của

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082, cuối cùng sẽ hết RAM. Điều này có thể xảy ra, chẳng hạn nếu máy khách ở đầu kia của ổ cắm không đọc đủ nhanh, gây áp lực ngược lên kết nối một cách hiệu quả

Since

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082 implements

 io.vertx
 vertx-core
 4.3.7
586, we can check if the

 io.vertx
 vertx-core
 4.3.7
586 is full before writing to it

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
21

Ví dụ này sẽ không hết RAM nhưng cuối cùng chúng ta sẽ mất dữ liệu nếu hàng đợi ghi đầy. Điều chúng tôi thực sự muốn làm là tạm dừng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082 khi hàng đợi ghi đã đầy

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
22

Chúng tôi gần như ở đó, nhưng không hoàn toàn. Hiện tại,

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082 bị tạm dừng khi tệp đầy, nhưng chúng tôi cũng cần hủy tạm dừng khi hàng đợi ghi đã xử lý hồ sơ tồn đọng của nó

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
23

Và chúng tôi đã có nó. Trình xử lý sự kiện

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
095 sẽ được gọi khi hàng đợi ghi sẵn sàng chấp nhận nhiều dữ liệu hơn, điều này sẽ tiếp tục
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
082 cho phép đọc nhiều dữ liệu hơn

Muốn làm điều này là khá phổ biến trong khi viết Vert. x, vì vậy chúng tôi đã thêm phương pháp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
097 để thực hiện tất cả công việc khó khăn này cho bạn. Bạn chỉ cần cho nó ăn

 io.vertx
 vertx-core
 4.3.7
586 và sử dụng nó

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
24

Điều này thực hiện chính xác điều tương tự như ví dụ dài dòng hơn, cộng với việc nó xử lý các lỗi và kết thúc luồng. đích


 io.vertx
 vertx-core
 4.3.7
586 kết thúc khi đường ống hoàn thành thành công hay thất bại

Bạn có thể được thông báo khi hoạt động hoàn tất

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
25

Khi bạn xử lý một đích không đồng bộ, bạn có thể tạo một phiên bản

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
100 để tạm dừng nguồn và tiếp tục nó khi nguồn được dẫn đến đích

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
26

When you need to abort the transfer, you need to close it

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
27

Khi đường ống được đóng lại, trình xử lý luồng không được đặt và


 io.vertx
 vertx-core
 4.3.7
585 đã tiếp tục

Như đã thấy ở trên, theo mặc định, đích đến luôn kết thúc khi luồng kết thúc, bạn có thể kiểm soát hành vi này trên đối tượng đường ống

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    102 kiểm soát hành vi khi xảy ra lỗi

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    103 kiểm soát hành vi khi luồng đọc kết thúc

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    104 kiểm soát hành vi trong mọi trường hợp

Đây là một ví dụ ngắn

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
28

Bây giờ chúng ta hãy xem xét các phương pháp trên


 io.vertx
 vertx-core
 4.3.7
585 và

 io.vertx
 vertx-core
 4.3.7
586 chi tiết hơn

ReadStream


 io.vertx
 vertx-core
 4.3.7
585 được triển khai bởi

 io.vertx
 vertx-core
 4.3.7
200,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
028,

 io.vertx
 vertx-core
 4.3.7
196,

 io.vertx
 vertx-core
 4.3.7
113,

 io.vertx
 vertx-core
 4.3.7
071,
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
05,
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74,

 io.vertx
 vertx-core
 4.3.7
154,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
116,

 io.vertx
 vertx-core
 4.3.7
145

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    118. đặt trình xử lý sẽ nhận các mục từ ReadStream

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    119. tạm dừng luồng. Khi bị tạm dừng, sẽ không có mục nào được nhận trong trình xử lý

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    120. tìm nạp một lượng mục cụ thể từ luồng. Trình xử lý sẽ được gọi nếu có bất kỳ mục nào đến. Fetches are cumulative

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    121. tiếp tục truyền phát. Trình xử lý sẽ được gọi nếu có bất kỳ mục nào đến. Tiếp tục tương đương với việc tìm nạp các mục
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    122

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    123. được gọi khi có ngoại lệ xảy ra trên ReadStream

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    124. được gọi khi kết thúc luồng. Điều này có thể xảy ra khi đạt đến EOF nếu ReadStream đại diện cho một tệp hoặc khi kết thúc yêu cầu nếu đó là yêu cầu HTTP hoặc khi kết nối bị đóng nếu đó là ổ cắm TCP

Luồng đọc đang ở chế độ chảy hoặc tìm nạp

  • initially the stream is in flowing mode

  • khi luồng ở chế độ chảy, các phần tử được gửi đến trình xử lý

  • khi luồng ở chế độ tìm nạp, chỉ số lượng phần tử được yêu cầu sẽ được gửi tới trình xử lý

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
119,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
121 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
120 thay đổi chế độ

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    128 đặt chế độ chảy

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    129 đặt chế độ tìm nạp và đặt lại yêu cầu thành
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    69

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    131 yêu cầu một số lượng phần tử cụ thể và thêm nó vào nhu cầu thực tế

GhiStream


 io.vertx
 vertx-core
 4.3.7
586 được triển khai bởi

 io.vertx
 vertx-core
 4.3.7
196,

 io.vertx
 vertx-core
 4.3.7
077

 io.vertx
 vertx-core
 4.3.7
154,
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74 và

 io.vertx
 vertx-core
 4.3.7
145

Chức năng

  • HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    77. ghi một đối tượng vào WriteStream. Phương pháp này sẽ không bao giờ chặn. Các ghi được xếp hàng đợi nội bộ và được ghi không đồng bộ vào tài nguyên cơ bản

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    139. đặt số lượng đối tượng tại đó hàng đợi ghi được coi là đầy và phương thức
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    140 trả về
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    19. Lưu ý rằng, khi hàng đợi ghi được coi là đầy, nếu gọi ghi thì dữ liệu vẫn được chấp nhận và xếp hàng. Con số thực tế phụ thuộc vào việc triển khai luồng, đối với
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    76, kích thước đại diện cho số byte thực được ghi chứ không phải số lượng bộ đệm

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    140. trả về
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    19 nếu hàng đợi ghi được coi là đầy

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    145. Sẽ được gọi nếu một ngoại lệ xảy ra trên
    
     io.vertx
     vertx-core
     4.3.7
    
    586

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    095. Trình xử lý sẽ được gọi nếu
    
     io.vertx
     vertx-core
     4.3.7
    
    586 được coi là không còn đầy

Trình phân tích bản ghi

Trình phân tích cú pháp bản ghi cho phép bạn dễ dàng phân tích cú pháp các giao thức được phân tách bằng một chuỗi byte hoặc bản ghi có kích thước cố định. Nó chuyển đổi một chuỗi bộ đệm đầu vào thành một chuỗi bộ đệm có cấu trúc như đã định cấu hình [có kích thước cố định hoặc các bản ghi riêng biệt]

Ví dụ: nếu bạn có một giao thức văn bản ASCII đơn giản được phân tách bằng '\n' và đầu vào như sau

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
29

Trình phân tích bản ghi sẽ tạo ra

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
30

Hãy xem mã liên quan

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
31

Bạn cũng có thể tạo các khối có kích thước cố định như sau

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
32

Để biết thêm chi tiết, hãy xem lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
149

Trình phân tích cú pháp Json

Bạn có thể dễ dàng phân tích các cấu trúc JSON nhưng điều đó yêu cầu cung cấp nội dung JSON cùng một lúc, nhưng có thể không thuận tiện khi bạn cần phân tích các cấu trúc rất lớn

Trình phân tích cú pháp JSON không chặn là trình phân tích cú pháp hướng sự kiện có thể xử lý các cấu trúc rất lớn. Nó biến đổi một chuỗi bộ đệm đầu vào thành một chuỗi các sự kiện phân tích cú pháp JSON

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
33

Trình phân tích cú pháp không chặn và các sự kiện phát ra được điều khiển bởi bộ đệm đầu vào

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
34

Phân tích cú pháp theo hướng sự kiện cung cấp nhiều quyền kiểm soát hơn nhưng phải trả giá bằng việc xử lý các sự kiện chi tiết, điều này đôi khi có thể gây bất tiện. Trình phân tích cú pháp JSON cho phép bạn xử lý các cấu trúc JSON dưới dạng giá trị khi muốn

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
35

Chế độ giá trị có thể được đặt và bỏ đặt trong quá trình phân tích cú pháp cho phép bạn chuyển đổi giữa các sự kiện chi tiết hoặc sự kiện giá trị đối tượng JSON

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
36

You can do the same with arrays as well

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
37

Bạn cũng có thể giải mã POJO

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
38

Bất cứ khi nào trình phân tích cú pháp không xử lý được bộ đệm, một ngoại lệ sẽ được đưa ra trừ khi bạn đặt một trình xử lý ngoại lệ

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
39

Trình phân tích cú pháp cũng phân tích các luồng json

  • các luồng json được nối.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    150

  • luồng json được phân tách bằng dòng.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    151

Để biết thêm chi tiết, hãy xem lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
152

Chỉ an toàn

Hầu hết Vert. các đối tượng x an toàn để truy cập từ các chủ đề khác nhau. Tuy nhiên, hiệu suất được tối ưu hóa khi chúng được truy cập từ cùng ngữ cảnh mà chúng được tạo từ

Ví dụ: nếu bạn đã triển khai một cột tạo ra một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
153 cung cấp các phiên bản
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
74 trong trình xử lý của nó, thì tốt nhất là luôn truy cập phiên bản ổ cắm đó từ vòng lặp sự kiện của cột đó

Nếu bạn dính vào Vert tiêu chuẩn. x và tránh chia sẻ các đối tượng giữa các đỉnh thì đây sẽ là trường hợp mà bạn không cần phải suy nghĩ về nó

Running blocking code

Trong một thế giới hoàn hảo, sẽ không có chiến tranh hay nạn đói, tất cả các API sẽ được viết không đồng bộ và những chú thỏ con sẽ tay trong tay với những chú cừu non băng qua đồng cỏ xanh đầy nắng

Nhưng…​ thế giới thực không như vậy. [Gần đây bạn có xem tin tức không?]

Thực tế là, nhiều, nếu không muốn nói là hầu hết các thư viện, đặc biệt là trong hệ sinh thái JVM có các API đồng bộ và nhiều phương thức có khả năng bị chặn. Một ví dụ điển hình là API JDBC - nó vốn đã đồng bộ và cho dù nó có cố gắng thế nào, Vert. x không thể rắc bụi pixie ma thuật lên nó để làm cho nó không đồng bộ

Chúng tôi sẽ không viết lại mọi thứ thành không đồng bộ chỉ trong một đêm, vì vậy chúng tôi cần cung cấp cho bạn cách sử dụng API chặn "truyền thống" một cách an toàn trong Vert. ứng dụng x

Như đã thảo luận trước đây, bạn không thể gọi các thao tác chặn trực tiếp từ vòng lặp sự kiện, vì điều đó sẽ ngăn không cho nó thực hiện bất kỳ công việc hữu ích nào khác. Vì vậy, làm thế nào bạn có thể làm điều này?

Nó được thực hiện bằng cách gọi

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
155 chỉ định cả mã chặn sẽ thực thi và trình xử lý kết quả sẽ được gọi lại không đồng bộ khi mã chặn đã được thực thi

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
40

Warning

Mã chặn nên chặn trong một khoảng thời gian hợp lý [i. e không quá vài giây]. Hoạt động chặn dài hoặc hoạt động bỏ phiếu [i. e một chuỗi quay trong các sự kiện bỏ phiếu vòng lặp theo kiểu chặn] bị loại trừ. Khi thao tác chặn kéo dài hơn 10 giây, một thông báo sẽ được in trên bảng điều khiển bởi trình kiểm tra luồng bị chặn. Các hoạt động chặn dài nên sử dụng một luồng chuyên dụng do ứng dụng quản lý, có thể tương tác với các đỉnh bằng cách sử dụng bus sự kiện hoặc
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
91

Theo mặc định, nếu execBlocking được gọi nhiều lần từ cùng một ngữ cảnh [e. g. cùng một thể hiện cột] thì các khối thực thi khác nhau được thực thi tuần tự [i. e. lân lượt tưng ngươi một]

Nếu bạn không quan tâm đến việc đặt hàng, bạn có thể gọi

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
155 chỉ định
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
20 làm đối số cho
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
159. Trong trường hợp này, bất kỳ execBlocking nào cũng có thể được thực thi song song trên nhóm công nhân

Một cách khác để chạy mã chặn là sử dụng một worker verticle

Một worker verticle luôn được thực thi với một thread từ worker pool

Theo mã chặn mặc định được thực thi trên Vert. nhóm công nhân x, được định cấu hình với

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
160

Các nhóm bổ sung có thể được tạo cho các mục đích khác nhau

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
41

Phải đóng worker executor khi không cần thiết nữa

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
42

Khi một số công nhân được tạo có cùng tên, họ sẽ chia sẻ cùng một nhóm. Nhóm công nhân bị hủy khi tất cả người thực thi công nhân sử dụng nó bị đóng

Khi một người thi hành được tạo trong một Verticle, Vert. x sẽ tự động đóng nó cho bạn khi Verticle không được triển khai

Người thực thi công nhân có thể được cấu hình khi tạo

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
43

Ghi chú

cấu hình được đặt khi nhóm công nhân được tạo

Chỉ số SPI

Theo mặc định Vert. x không ghi lại bất kỳ số liệu nào. Thay vào đó, nó cung cấp một SPI để những người khác triển khai có thể được thêm vào đường dẫn lớp. The metrics SPI is an advanced feature which allows implementers to capture events from Vert. x để thu thập số liệu. Để biết thêm thông tin về điều này, vui lòng tham khảo

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
161

Bạn cũng có thể chỉ định nhà máy số liệu theo chương trình nếu nhúng Vert. x sử dụng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
162

Dòng lệnh 'vertx'

Lệnh

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85 dùng để tương tác với Vert. x từ dòng lệnh. Công dụng chính của nó là chạy Vert. x cột sống. Để làm điều này, bạn cần tải xuống và cài đặt Vert. x và thêm thư mục cài đặt
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
81 vào biến môi trường
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
82 của bạn. Ngoài ra, hãy đảm bảo rằng bạn có Java JDK trên
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
82 của mình

Vert. x supports Java from 8 to 17

Ghi chú

Cần có JDK để hỗ trợ quá trình biên dịch mã Java nhanh chóng

Chạy dọc

Bạn có thể chạy Vert thô. x đỉnh trực tiếp từ dòng lệnh bằng cách sử dụng

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
84. Dưới đây là một vài ví dụ về lệnh
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
168

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
44

  1. Triển khai một cột JavaScript

  2. Triển khai một cột dọc Groovy

  3. Triển khai một cột dọc Ruby

  4. Deploys an already compiled Java verticle. Classpath root là thư mục hiện tại

  5. Triển khai một cột dọc được đóng gói trong một Jar, jar cần phải nằm trong đường dẫn lớp

  6. Biên dịch nguồn Java và triển khai nó

Như bạn có thể thấy trong trường hợp của Java, tên có thể là tên lớp đủ điều kiện của cột hoặc bạn có thể chỉ định trực tiếp tệp Nguồn Java và Vert. x biên dịch nó cho bạn

Bạn cũng có thể thêm tiền tố vào cột dọc với tên của ngôn ngữ triển khai để sử dụng. Ví dụ: nếu cột dọc là một lớp Groovy đã biên dịch, bạn thêm tiền tố vào nó bằng _____3169 để Vert. x biết đó là lớp Groovy không phải lớp Java

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
45

Lệnh

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
84 có thể nhận một vài tham số tùy chọn, chúng là

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    171 - Cung cấp Vert. tùy chọn x.
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    172 là tên của tệp JSON đại diện cho Vert. x hoặc chuỗi JSON. Đây là tùy chọn

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    173 - Cung cấp một số cấu hình cho ngành dọc.
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    174 là tên của tệp JSON đại diện cho cấu hình cho cột dọc hoặc chuỗi JSON. Đây là tùy chọn

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    175 - Đường dẫn để tìm kiếm dọc và bất kỳ tài nguyên nào khác được sử dụng bởi dọc. Điều này mặc định là
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    176 [thư mục hiện tại]. If your verticle references other scripts, classes or other resources [e. g. jar] thì hãy chắc chắn rằng chúng nằm trên đường dẫn này. Đường dẫn có thể chứa nhiều mục nhập đường dẫn được phân tách bằng
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    177 [dấu hai chấm] hoặc
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    178 [dấu chấm phẩy] tùy thuộc vào hệ điều hành. Mỗi mục nhập đường dẫn có thể là đường dẫn tuyệt đối hoặc tương đối đến thư mục chứa tập lệnh hoặc tên tệp tuyệt đối hoặc tương đối cho tệp jar hoặc zip. Một đường dẫn ví dụ có thể là
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    179. Luôn sử dụng đường dẫn để tham chiếu bất kỳ tài nguyên nào mà cột dọc của bạn yêu cầu. Không đặt chúng trên đường dẫn lớp hệ thống vì điều này có thể gây ra sự cố cách ly giữa các đỉnh được triển khai

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    180 - Số trường hợp của đỉnh để khởi tạo. Mỗi phiên bản verticle hoàn toàn là một luồng duy nhất để mở rộng ứng dụng của bạn trên các lõi có sẵn, bạn có thể muốn triển khai nhiều hơn một phiên bản. Nếu bỏ qua một trường hợp duy nhất sẽ được triển khai

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    181 - Tùy chọn này xác định xem cột dọc có phải là cột dọc công nhân hay không

  • request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    80 - Tùy chọn này xác định xem Vert. x sẽ cố gắng tạo thành một cụm với Vert khác. x trên mạng. Phân cụm Vert. phiên bản x cho phép Vert. x để tạo thành một bus sự kiện phân tán với các nút khác. Mặc định là
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    20 [không phân cụm]

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    184 - Nếu tùy chọn
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    185 cũng đã được chỉ định thì tùy chọn này sẽ xác định cổng nào sẽ bị ràng buộc để liên lạc cụm với Vert khác. trường hợp x. Default is
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    69 - which means 'choose a free random port'. Bạn thường không cần chỉ định tham số này trừ khi bạn thực sự cần liên kết với một cổng cụ thể

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    187 - Nếu tùy chọn
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    185 cũng đã được chỉ định thì tùy chọn này sẽ xác định địa chỉ máy chủ nào sẽ bị ràng buộc để liên lạc cụm với Vert khác. trường hợp x. Nếu không được đặt, bus sự kiện theo cụm sẽ cố gắng liên kết với cùng một máy chủ với trình quản lý cụm bên dưới. Phương án cuối cùng, một địa chỉ sẽ được chọn trong số các giao diện mạng có sẵn

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    189 - Nếu tùy chọn
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    185 cũng đã được chỉ định thì tùy chọn này sẽ xác định cổng nào sẽ được quảng cáo để liên lạc cụm với Vert khác. trường hợp x. Mặc định là
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    191, có nghĩa là giống như
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    192

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    193 - Nếu tùy chọn
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    185 cũng đã được chỉ định thì tùy chọn này sẽ xác định địa chỉ máy chủ nào sẽ được quảng cáo để liên lạc cụm với Vert khác. trường hợp x. Nếu không được chỉ định, Vert. x sử dụng giá trị của
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    195

  • request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    79 - nếu được chỉ định, cột dọc sẽ được triển khai dưới dạng triển khai có tính sẵn sàng cao [HA]. Xem phần liên quan để biết thêm chi tiết

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    197 - được sử dụng cùng với
    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    79. Nó chỉ định số lượng nút tối thiểu trong cụm để bất kỳ ID triển khai HA nào hoạt động. Mặc định là 0

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    199 - được sử dụng cùng với
    request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
    79. Nó chỉ định nhóm HA mà nút này sẽ tham gia. There can be multiple HA groups in a cluster. Các nút sẽ chỉ chuyển đổi dự phòng sang các nút khác trong cùng một nhóm. Giá trị mặc định là `__DEFAULT__`

Bạn cũng có thể đặt thuộc tính hệ thống bằng cách sử dụng.

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
201

Dưới đây là một số ví dụ

Chạy một máy chủ dọc JavaScript. js với cài đặt mặc định

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
46

Chạy 10 phiên bản của một cột dọc Java được biên dịch sẵn chỉ định đường dẫn lớp

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
47

Chạy 10 phiên bản của một đỉnh Java bằng tệp nguồn

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
48

Chạy 20 phiên bản của công nhân viên ruby

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
49

Chạy hai cột JavaScript trên cùng một máy và để chúng nhóm lại với nhau và bất kỳ máy chủ nào khác trên mạng

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
50

Chạy một cột dọc Ruby chuyển cho nó một số cấu hình

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
51

Where

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
202 might contain something like

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
52

The config will be available inside the verticle via the core API

Khi sử dụng tính năng sẵn sàng cao của vert. x, bạn có thể muốn tạo một phiên bản trần của vert. x. Phiên bản này không triển khai bất kỳ đỉnh nào khi được khởi chạy, nhưng sẽ nhận được một chiều dọc nếu một nút khác của cụm chết. Để tạo một phiên bản trống, hãy khởi chạy

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
53

Tùy thuộc vào cấu hình cụm của bạn, bạn có thể phải thêm các tham số

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
195 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
192

Thực hiện một Vert. ứng dụng x được đóng gói dưới dạng hũ mỡ

Một lọ chất béo là một lọ thực thi nhúng các phụ thuộc của nó. Điều này có nghĩa là bạn không cần phải có Vert. x được cài đặt sẵn trên máy mà bạn thực thi jar. Giống như bất kỳ jar Java thực thi nào, nó có thể được thực thi với

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
54

Không có gì thực sự Vert. x cụ thể về điều này, bạn có thể làm điều này với bất kỳ ứng dụng Java nào

Bạn có thể tạo lớp chính của riêng mình và chỉ định lớp đó trong tệp kê khai, nhưng bạn nên viết mã của mình dưới dạng các cột dọc và sử dụng Vert. x Lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 [
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
206] là lớp chính của bạn. Đây là cùng một lớp chính được sử dụng khi chạy Vert. x tại dòng lệnh và do đó cho phép bạn chỉ định các đối số dòng lệnh, chẳng hạn như
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
93 để mở rộng ứng dụng của bạn dễ dàng hơn

To deploy your verticle in a fatjar like this you must have a manifest with

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    208 được đặt thành
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    206

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    210 chỉ định cột chính [tên lớp đủ điều kiện hoặc tên tệp tập lệnh]

Bạn cũng có thể cung cấp các đối số dòng lệnh thông thường mà bạn sẽ chuyển đến

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
84

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
55

Ghi chú

Vui lòng tham khảo các ví dụ về cột dọc Maven/Gradle đơn giản nhất và Maven/Gradle trong kho lưu trữ ví dụ để biết các ví dụ về xây dựng ứng dụng dưới dạng fatjars

Theo mặc định, một lọ chất béo thực thi lệnh

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
168

Đang hiển thị phiên bản của Vert. x

Để hiển thị đỉnh. phiên bản x, chỉ cần khởi chạy

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
56

Các lệnh khác

Dòng lệnh

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
214 cũng cung cấp các lệnh khác ngoài
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
168 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
216

Bạn có thể tạo một phiên bản

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
217 bằng cách sử dụng

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
57

Bạn cũng có thể khởi động một ứng dụng ở chế độ nền bằng cách sử dụng

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
58

Nếu

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
218 không được đặt, một id ngẫu nhiên sẽ được tạo và in trên dấu nhắc lệnh. Bạn có thể chuyển các tùy chọn
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
168 cho lệnh
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
220

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
59

Sau khi khởi chạy ở chế độ nền, bạn có thể dừng nó bằng lệnh

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
221

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
60

Bạn cũng có thể liệt kê các đỉnh. ứng dụng x được khởi chạy trong nền bằng cách sử dụng

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
61

Lệnh

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
220,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
221 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
224 cũng có sẵn từ công cụ
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85. Lệnh start` hỗ trợ một số tùy chọn

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    226. id ứng dụng, sử dụng UUID ngẫu nhiên nếu không được đặt

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    227. các tùy chọn Máy ảo Java, sử dụng biến môi trường
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    228 nếu không được đặt

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    229. chuyển hướng các luồng lỗi và đầu ra của quy trình được sinh ra sang các luồng quy trình gốc

Nếu các giá trị tùy chọn chứa khoảng trắng, đừng quên bọc giá trị trong khoảng từ

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
230 [dấu ngoặc kép]

Khi lệnh

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
220 tạo ra một quy trình mới, các tùy chọn java được chuyển đến JVM sẽ không được truyền bá, vì vậy bạn phải sử dụng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
227 để định cấu hình JVM [
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
233,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
234…]. Nếu bạn sử dụng biến môi trường
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
235, hãy chắc chắn rằng nó chứa tất cả các lọ cần thiết [lõi đỉnh, lọ của bạn và tất cả các phần phụ thuộc]

Bộ lệnh có thể mở rộng, tham khảo phần Mở rộng đỉnh. phần Trình khởi chạy x

Triển khai lại trực tiếp

Khi phát triển, có thể thuận tiện để tự động triển khai ứng dụng của bạn khi thay đổi tệp. Công cụ dòng lệnh

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85 và nói chung là lớp
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 cung cấp tính năng này. Here are some examples

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
62

Quy trình bố trí lại được thực hiện như sau. Đầu tiên, ứng dụng của bạn được khởi chạy dưới dạng ứng dụng nền [với lệnh

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
220]. Khi thay đổi tệp phù hợp, quá trình sẽ dừng lại và ứng dụng được khởi động lại. Điều này tránh rò rỉ, khi quá trình được khởi động lại

Để kích hoạt triển khai lại trực tiếp, hãy chuyển tùy chọn

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
239 cho lệnh
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
168.
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
239 cho biết bộ tệp cần xem. Bộ này có thể sử dụng các mẫu kiểu Ant [với
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
242,

 io.vertx
 vertx-core
 4.3.7
046 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
244]. Bạn có thể chỉ định một số bộ bằng cách tách chúng bằng dấu phẩy [
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
245]. Các mẫu có liên quan đến thư mục làm việc hiện tại

Các tham số được truyền cho lệnh

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
168 được truyền cho ứng dụng. Các tùy chọn Máy ảo Java có thể được định cấu hình bằng cách sử dụng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
247. Chẳng hạn, để truyền tham số
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
248 hoặc thuộc tính hệ thống, bạn cần sử dụng.
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
249

Tùy chọn

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
250 xác định với lớp chính, ứng dụng là trình khởi chạy. Nó nói chung là ________ 3205, nhưng bạn đã sử dụng chính của mình

Tính năng triển khai lại có thể được sử dụng trong IDE của bạn

  • Eclipse - tạo cấu hình Run, sử dụng lớp chính

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    206. In the Program arguments area [in the Arguments tab], write
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    253. Bạn cũng có thể thêm các tham số khác. Việc triển khai lại hoạt động trơn tru khi Eclipse biên dịch dần các tệp của bạn khi lưu

  • IntelliJ - tạo cấu hình Chạy [Ứng dụng], đặt lớp Chính thành

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    206. Trong lập luận Chương trình viết.
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    255. Để kích hoạt triển khai lại, bạn cần tạo dự án hoặc mô-đun một cách rõ ràng [Menu Build → Make project]

Để gỡ lỗi ứng dụng của bạn, hãy tạo cấu hình chạy của bạn dưới dạng ứng dụng từ xa và định cấu hình trình gỡ lỗi bằng cách sử dụng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
247. Tuy nhiên, đừng quên cắm lại trình gỡ lỗi sau mỗi lần triển khai lại vì một quy trình mới được tạo mỗi lần

Bạn cũng có thể kết nối quá trình xây dựng của mình trong chu kỳ triển khai lại

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
63

Tùy chọn "triển khai lại" chỉ định một lệnh được gọi sau khi tắt ứng dụng và trước khi khởi động lại. Vì vậy, bạn có thể kết nối công cụ xây dựng của mình nếu nó cập nhật một số tạo phẩm thời gian chạy. Chẳng hạn, bạn có thể khởi chạy

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
257 hoặc
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
258 để cập nhật tài nguyên của mình. Đừng quên rằng việc truyền tham số cho ứng dụng của bạn yêu cầu tham số
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
247

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
64

Tính năng triển khai lại cũng hỗ trợ các cài đặt sau

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    260. khoảng thời gian kiểm tra hệ thống tệp [tính bằng mili giây], theo mặc định là 250 mili giây

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    261. lượng thời gian [tính bằng mili giây] để chờ giữa 2 lần triển khai lại, theo mặc định là 1000 mili giây

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    262. lượng thời gian chờ đợi sau khi dừng ứng dụng [trước khi khởi chạy lệnh người dùng]. Điều này hữu ích trên Windows, nơi quá trình này không bị hủy ngay lập tức. Thời gian được tính bằng mili giây. 0 mili giây theo mặc định

Quản lý cụm

In Vert. x, trình quản lý cụm được sử dụng cho các chức năng khác nhau bao gồm

  • Khám phá và thành viên nhóm của Vert. x nút trong một cụm

  • Duy trì danh sách người đăng ký chủ đề rộng của cụm [để chúng tôi biết nút nào quan tâm đến địa chỉ xe buýt sự kiện nào]

  • Hỗ trợ bản đồ phân tán

  • Khóa phân tán

  • Bộ đếm phân tán

Trình quản lý cụm không xử lý vận chuyển giữa các nút trên bus sự kiện, điều này được thực hiện trực tiếp bởi Vert. x với các kết nối TCP

Trình quản lý cụm mặc định được sử dụng trong Vert. x là bản phân phối sử dụng Hazelcast nhưng điều này có thể dễ dàng thay thế bằng cách triển khai khác như Vert. trình quản lý cụm x có thể cắm được

Trình quản lý cụm phải triển khai giao diện

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
33. Vert. x định vị các trình quản lý cụm trong thời gian chạy bằng cách sử dụng chức năng Trình tải dịch vụ Java để định vị các phiên bản của
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
33 trên đường dẫn lớp

Nếu bạn đang sử dụng Vert. x tại dòng lệnh và bạn muốn sử dụng phân cụm, bạn phải đảm bảo thư mục

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
265 của Vert. x chứa jar trình quản lý cụm của bạn

Nếu bạn đang sử dụng Vert. x từ dự án Maven hoặc Gradle, chỉ cần thêm trình quản lý cụm làm phụ thuộc cho dự án của bạn

You can also specify cluster managers programmatically if embedding Vert. x sử dụng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
266

ghi nhật ký

Vert. x sử dụng API ghi nhật ký nội bộ của nó và hỗ trợ các chương trình phụ trợ ghi nhật ký khác nhau

Phần phụ trợ ghi nhật ký được chọn như sau

  1. phần phụ trợ được biểu thị bằng thuộc tính hệ thống

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    267 nếu có hoặc,

  2. Ghi nhật ký JDK khi tệp

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    268 nằm trong đường dẫn lớp hoặc,

  3. một chương trình phụ trợ có trong đường dẫn lớp, theo thứ tự ưu tiên sau

    1. SLF4J

    2. Nhật ký4J

    3. Nhật ký4J2

Nếu không thì Vert. x mặc định ghi nhật ký JDK

Cấu hình với thuộc tính hệ thống

Đặt thuộc tính hệ thống

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
267 thành

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    270 cho SLF4J hoặc,

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    271 cho Log4J2 hoặc,

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    272 để ghi nhật ký JDK

cấu hình tự động

Khi không có thuộc tính hệ thống

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
267 nào được đặt, Vert. x will try to find the most appropriate logger

  • sử dụng SLF4J khi có sẵn trên đường dẫn lớp với triển khai thực tế [i. e.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    274 không phải là phiên bản của
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    275]

  • mặt khác, hãy sử dụng Log4j2 khi có sẵn trên đường dẫn lớp

  • nếu không thì sử dụng JUL

Định cấu hình ghi nhật ký JUL

Tệp cấu hình ghi nhật ký JUL có thể được chỉ định theo cách JUL thông thường, bằng cách cung cấp thuộc tính hệ thống có tên

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
276 với giá trị là tệp cấu hình của bạn. Để biết thêm thông tin về điều này và cấu trúc của tệp cấu hình JUL, vui lòng tham khảo tài liệu ghi nhật ký JDK

Vert. x cũng cung cấp một cách thuận tiện hơn một chút để chỉ định tệp cấu hình mà không phải đặt thuộc tính hệ thống. Chỉ cần cung cấp tệp cấu hình JUL có tên

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
268 trên đường dẫn lớp của bạn [e. g. bên trong fatjar của bạn] và Vert. x sẽ sử dụng nó để định cấu hình JUL

khai thác gỗ netty

Netty không dựa vào cấu hình ghi nhật ký bên ngoài [e. g thuộc tính hệ thống]. Thay vào đó, nó thực hiện cấu hình ghi nhật ký dựa trên các thư viện ghi nhật ký có thể nhìn thấy từ các lớp Netty

  • sử dụng thư viện

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    278 nếu nó hiển thị

  • mặt khác, sử dụng

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    279 nếu nó hiển thị

  • mặt khác, sử dụng

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    280 nếu nó hiển thị

  • nếu không thì dự phòng cho

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    281

Ghi chú

The eagle eyes among you might have noticed that Vert. x follows the same order of preference

Việc triển khai trình ghi nhật ký có thể bị buộc thực hiện cụ thể bằng cách đặt trực tiếp triển khai trình ghi nhật ký nội bộ của Netty trên

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
282

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
65

Xử lý sự cố

Cảnh báo SLF4J khi khởi động

Nếu khi bạn khởi động ứng dụng của mình, bạn thấy thông báo sau

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
66

Điều đó có nghĩa là bạn có SLF4J-API trong đường dẫn lớp của mình nhưng không có ràng buộc thực tế. Thư được ghi bằng SLF4J sẽ bị hủy. Bạn nên thêm một ràng buộc vào đường dẫn lớp của mình. Kiểm tra https. //www. slf4j. tổ chức/thủ công. html#swapping để chọn một ràng buộc và cấu hình nó

Xin lưu ý rằng Netty tìm kiếm jar SLF4-API và sử dụng nó theo mặc định

Thiết lập lại kết nối bởi ngang hàng

Nếu nhật ký của bạn hiển thị một loạt

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
67

Điều đó có nghĩa là máy khách đang đặt lại kết nối HTTP thay vì đóng nó. Thông báo này cũng cho biết rằng bạn có thể chưa sử dụng hết tải trọng [kết nối đã bị cắt trước khi bạn có thể]

Host name resolution

Vert. x sử dụng trình phân giải địa chỉ để phân giải tên Máy chủ thành địa chỉ IP thay vì trình phân giải chặn tích hợp JVM

Tên máy chủ phân giải thành địa chỉ IP bằng cách sử dụng

  • tập tin hosts của hệ điều hành

  • mặt khác, truy vấn DNS đối với danh sách máy chủ

Theo mặc định, nó sẽ sử dụng danh sách các địa chỉ máy chủ DNS của hệ thống từ môi trường, nếu không thể truy xuất danh sách đó, nó sẽ sử dụng các máy chủ DNS công cộng của Google là

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
283 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
284

Máy chủ DNS cũng có thể được định cấu hình khi tạo phiên bản

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
16

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
68

Cổng mặc định của máy chủ DNS là

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
286, khi máy chủ sử dụng một cổng khác, cổng này có thể được đặt bằng dấu hai chấm phân cách.
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
287

Ghi chú

đôi khi có thể mong muốn sử dụng trình phân giải tích hợp JVM, thuộc tính hệ thống JVM -Dvertx. disableDnsResolver=true kích hoạt hành vi này

chuyển đổi dự phòng

Khi máy chủ không trả lời kịp thời, trình giải quyết sẽ thử cái tiếp theo từ danh sách, tìm kiếm bị giới hạn bởi _______ 3288 [giá trị mặc định là _______ 3289 truy vấn]

Truy vấn DNS được coi là không thành công khi trình phân giải không nhận được câu trả lời chính xác trong vòng ____3290 mili giây [giá trị mặc định là ____3291 giây]

Xoay vòng danh sách máy chủ

Theo mặc định, lựa chọn máy chủ dns sử dụng máy chủ đầu tiên, các máy chủ còn lại được sử dụng để chuyển đổi dự phòng

Thay vào đó, bạn có thể định cấu hình

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
292 thành
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
19 để trình phân giải thực hiện lựa chọn vòng tròn. Nó phân tán tải truy vấn giữa các máy chủ và tránh tất cả các tra cứu để tấn công máy chủ đầu tiên của danh sách

Failover still applies and will use the next server in the list

Ánh xạ máy chủ

Tệp máy chủ của hệ điều hành được sử dụng để thực hiện tra cứu tên máy chủ cho địa chỉ ipad

Có thể sử dụng tệp máy chủ thay thế

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
69

Tìm kiếm miền

Theo mặc định, trình phân giải sẽ sử dụng các miền tìm kiếm DNS của hệ thống từ môi trường. Ngoài ra, một danh sách miền tìm kiếm rõ ràng có thể được cung cấp

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
70

Khi danh sách miền tìm kiếm được sử dụng, ngưỡng cho số lượng dấu chấm là

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
294 hoặc được tải từ
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
295 trên Linux, nó có thể được định cấu hình thành một giá trị cụ thể với
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
296

cấu hình MacOS

MacOS has a specific native extension to get the name server configuration of the system based on Apple’s open source mDNSResponder. When this extension is not present, Netty logs the following warning.

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
71

Tiện ích mở rộng này không bắt buộc vì sự vắng mặt của nó không ngăn Vert. x để thực thi, nhưng vẫn được khuyến nghị

You can use add it to your classpath to improve the integration and remove the warning

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
72

Tính khả dụng cao và chuyển đổi dự phòng

Vert. x cho phép bạn chạy các đỉnh của mình với sự hỗ trợ về tính khả dụng cao [HA]. Trong trường hợp đó, khi một đỉnh. phiên bản x đang chạy một phiên bản dọc chết đột ngột, phiên bản dọc được di chuyển sang một phiên bản verx khác. Bụi cây. phiên bản x phải ở trong cùng một cụm

chuyển đổi dự phòng tự động

Khi đứng. x chạy khi bật HA, nếu một đỉnh. x trong đó một đỉnh chạy không thành công hoặc bị chết, thì dọc được triển khai tự động trên một đỉnh khác. x phiên bản của cụm. Chúng tôi gọi đây là chuyển đổi dự phòng theo chiều dọc

Để chạy đỉnh. x khi bật HA, chỉ cần thêm cờ

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
79 vào dòng lệnh

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
5

Bây giờ để HA hoạt động, bạn cần nhiều hơn một Vert. x instances in the cluster, so let’s say you have another Vert. x mà bạn đã bắt đầu, chẳng hạn

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
74

Nếu Vert. x đang chạy

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
298 hiện đã chết [bạn có thể kiểm tra điều này bằng cách tắt tiến trình với
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
299], phiên bản Vert. x đang chạy
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
300 sẽ tự động triển khai
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
301 nên giờ đây Vert. x đang chạy cả hai đỉnh

Ghi chú

việc di chuyển chỉ có thể thực hiện được nếu đỉnh thứ hai. x có quyền truy cập vào tệp dọc [ở đây ________ 3298]

Important

Xin lưu ý rằng việc đóng Vert hoàn toàn. x sẽ không gây ra chuyển đổi dự phòng, e. g.
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
303 hoặc
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
304

Bạn cũng có thể bắt đầu trần Vert. trường hợp x - tôi. e. các phiên bản ban đầu không chạy bất kỳ đỉnh nào, chúng cũng sẽ chuyển đổi dự phòng cho các nút trong cụm. Để bắt đầu một phiên bản trống, bạn chỉ cần làm

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
75

Khi sử dụng công tắc

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
79, bạn không cần cung cấp công tắc
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
80, vì một cụm được giả định nếu bạn muốn HA

Ghi chú

tùy thuộc vào cấu hình cụm của bạn, bạn có thể cần tùy chỉnh cấu hình trình quản lý cụm [Hazelcast theo mặc định] và/hoặc thêm các tham số
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
195 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
192

nhóm HA

When running a Vert. x với HA, bạn cũng có thể tùy chọn chỉ định một nhóm HA. Một nhóm HA biểu thị một nhóm các nút hợp lý trong cụm. Chỉ các nút có cùng nhóm HA mới chuyển đổi dự phòng sang nhau. Nếu bạn không chỉ định nhóm HA, nhóm mặc định

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
309 sẽ được sử dụng

Để chỉ định một nhóm HA, bạn sử dụng công tắc

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
199 khi chạy dọc, e. g

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
76

Hãy xem một ví dụ

Trong một thiết bị đầu cuối đầu tiên

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
77

Trong thiết bị đầu cuối thứ hai, hãy chạy một đỉnh khác bằng cách sử dụng cùng một nhóm

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
78

Cuối cùng, trong thiết bị đầu cuối thứ ba, khởi chạy một đỉnh khác bằng cách sử dụng một nhóm khác

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
79

Nếu chúng ta giết cá thể ở nhà ga 1, nó sẽ chuyển sang cá thể ở nhà ga 2, chứ không phải cá thể ở nhà ga 3 vì nó có một nhóm khác

Nếu chúng ta kill instance ở terminal 3, nó sẽ không bị fail vì không có ver nào khác. x trong nhóm đó

Xử lý phân vùng mạng - Quorum

Việc triển khai HA cũng hỗ trợ đại biểu. A quorum is the minimum number of votes that a distributed transaction has to obtain in order to be allowed to perform an operation in a distributed system

Khi bắt đầu một Vert. x, bạn có thể hướng dẫn nó rằng nó yêu cầu một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
311 trước khi triển khai bất kỳ triển khai HA nào. Trong bối cảnh này, đại biểu là số nút tối thiểu cho một nhóm cụ thể trong cụm. Thông thường, bạn đã chọn kích thước đại biểu của mình thành
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
312 trong đó
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
313 là số nút trong nhóm. Nếu có ít hơn
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
314 nút trong cụm, việc triển khai HA sẽ không triển khai. Họ sẽ triển khai lại nếu/khi đạt được số đại biểu quy định trở lại. Bằng cách này, bạn có thể ngăn chặn các phân vùng mạng, một. k. a. chia não

Có thêm thông tin về đại biểu ở đây

Để chạy đỉnh. x với số đại biểu mà bạn chỉ định

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
197 trên dòng lệnh, e. g

Trong một thiết bị đầu cuối đầu tiên

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
80

Tại thời điểm này, Vert. x sẽ bắt đầu nhưng chưa triển khai mô-đun [chưa] vì chỉ có một nút trong cụm chứ không phải 3

Trong một thiết bị đầu cuối thứ hai

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
81

Tại thời điểm này, Vert. x sẽ bắt đầu nhưng chưa triển khai mô-đun vì chỉ có hai nút trong cụm chứ không phải 3

Trong bảng điều khiển thứ ba, bạn có thể bắt đầu một phiên bản khác của vert. x

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
82

vâng. - chúng tôi có ba nút, đó là một đại biểu. Tại thời điểm này, các mô-đun sẽ tự động triển khai trên tất cả các phiên bản

Nếu bây giờ chúng ta đóng hoặc hủy một trong các nút, các mô-đun sẽ tự động ngừng triển khai trên các nút khác, vì không còn đủ đại biểu

Số đại biểu cũng có thể được sử dụng cùng với các nhóm ha. Trong trường hợp đó, đại biểu được giải quyết cho từng nhóm cụ thể

phương tiện giao thông bản địa

Vert. x có thể chạy với các phương tiện truyền tải gốc [nếu có] trên BSD [OSX] và Linux

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
83

Ghi chú

ưu tiên vận chuyển gốc sẽ không ngăn ứng dụng thực thi [ví dụ: nếu thiếu JAR]. Nếu ứng dụng của bạn yêu cầu vận chuyển bản địa, bạn cần kiểm tra
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
316

Vận chuyển Linux bản địa

Bạn cần thêm phần phụ thuộc sau vào đường dẫn lớp của mình

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
84

Bản địa trên Linux cung cấp cho bạn các tùy chọn kết nối mạng bổ sung

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    317

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    318

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    319

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    320

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    321

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
85

Vận chuyển BSD bản địa

Bạn cần thêm phần phụ thuộc sau vào đường dẫn lớp của mình

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
86

MacOS Sierra trở lên được hỗ trợ

Bản địa trên BSD cung cấp cho bạn các tùy chọn kết nối mạng bổ sung

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    317

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
87

Ổ cắm tên miền

Người bản địa cung cấp hỗ trợ ổ cắm tên miền cho máy chủ

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
88

hoặc cho http

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
89

Cũng như khách hàng

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
90

hoặc cho http

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
91

Ghi chú bảo mật

Vert. x là một bộ công cụ, không phải là một khung cố định nơi chúng tôi buộc bạn phải làm mọi việc theo một cách nhất định. Điều này mang lại cho bạn sức mạnh tuyệt vời với tư cách là một nhà phát triển nhưng đi kèm với đó là trách nhiệm lớn

Như với bất kỳ bộ công cụ nào, bạn có thể viết các ứng dụng không an toàn, vì vậy bạn phải luôn cẩn thận khi phát triển ứng dụng của mình, đặc biệt nếu ứng dụng đó được hiển thị công khai [e. g. qua mạng]

Ứng dụng web

Nếu viết một ứng dụng web, bạn nên sử dụng Vert. x-Web thay vì Vert. x core trực tiếp để phục vụ tài nguyên và xử lý tệp tải lên

Vert. x-Web bình thường hóa đường dẫn trong các yêu cầu để ngăn các máy khách độc hại tạo URL để truy cập các tài nguyên bên ngoài thư mục gốc của web

Tương tự như vậy đối với tệp tải lên Vert. x-Web cung cấp chức năng tải lên một vị trí đã biết trên đĩa và không phụ thuộc vào tên tệp do máy khách cung cấp trong quá trình tải lên mà có thể được tạo thủ công để tải lên một vị trí khác trên đĩa

Vert. Bản thân lõi x không cung cấp các kiểm tra như vậy, do đó, với tư cách là nhà phát triển, bạn sẽ tự thực hiện chúng

Lưu lượng xe buýt sự kiện nhóm

Khi phân cụm xe buýt sự kiện giữa các Vert khác nhau. x trên mạng, lưu lượng được gửi không được mã hóa qua dây, do đó, không sử dụng điều này nếu bạn có dữ liệu bí mật cần gửi và Vert của bạn. nút x không nằm trên mạng đáng tin cậy

Thực tiễn tốt nhất về bảo mật tiêu chuẩn

Bất kỳ dịch vụ nào cũng có thể có lỗ hổng tiềm ẩn cho dù nó được viết bằng Vert. x hoặc bất kỳ bộ công cụ nào khác, vì vậy hãy luôn tuân theo phương pháp hay nhất về bảo mật, đặc biệt nếu dịch vụ của bạn được công khai

Ví dụ: bạn phải luôn chạy chúng trong DMZ và với tài khoản người dùng có quyền hạn chế để hạn chế mức độ thiệt hại trong trường hợp dịch vụ bị xâm phạm

Vert. x API giao diện dòng lệnh

Vert. x Core cung cấp API để phân tích đối số dòng lệnh được truyền cho chương trình. Nó cũng có thể in các thông báo trợ giúp nêu chi tiết các tùy chọn có sẵn cho công cụ dòng lệnh. Ngay cả khi các tính năng như vậy ở xa Vert. x, API này được sử dụng trong lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 mà bạn có thể sử dụng trong fat-jar và trong các công cụ dòng lệnh
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85. Ngoài ra, đó là ngôn ngữ đa ngôn ngữ [có thể được sử dụng từ bất kỳ ngôn ngữ được hỗ trợ nào] và được sử dụng trong Vert. x Vỏ

Vert. x CLI cung cấp một mô hình để mô tả giao diện dòng lệnh của bạn, nhưng cũng là một trình phân tích cú pháp. Trình phân tích cú pháp này hỗ trợ các loại cú pháp khác nhau

  • Tùy chọn giống như POSIX [tức là.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    325]

  • GNU thích các tùy chọn dài [nghĩa là.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    326]

  • Các thuộc tính giống như Java [tức là.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    327]

  • Các tùy chọn ngắn có giá trị kèm theo [tức là.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    328]

  • Tùy chọn dài với dấu gạch nối đơn [nghĩa là.

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    329]

Sử dụng api CLI là một quy trình gồm 3 bước

  1. Định nghĩa giao diện dòng lệnh

  2. Phân tích cú pháp dòng lệnh người dùng

  3. Truy vấn / thẩm vấn

Giai đoạn định nghĩa

Mỗi giao diện dòng lệnh phải xác định tập hợp các tùy chọn và đối số sẽ được sử dụng. Nó cũng yêu cầu một cái tên. API CLI sử dụng các lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
330 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
331 để mô tả các tùy chọn và đối số

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
92

Như bạn có thể thấy, bạn có thể tạo một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
332 mới bằng cách sử dụng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
333. Chuỗi đã truyền là tên của CLI. Sau khi tạo, bạn có thể đặt tóm tắt và mô tả. Phần tóm tắt dự định ngắn [một dòng], trong khi phần mô tả có thể chứa nhiều chi tiết hơn. Mỗi tùy chọn và đối số cũng được thêm vào đối tượng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
334 bằng cách sử dụng các phương thức
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
335 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
336

Tùy chọn

Một

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
330 là một tham số dòng lệnh được xác định bởi một khóa có trong dòng lệnh của người dùng. Tùy chọn ít nhất phải có tên dài hoặc tên ngắn. Tên dài thường được sử dụng với tiền tố
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
338, trong khi tên ngắn được sử dụng với một
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
339. Tên phân biệt chữ hoa chữ thường; . Các tùy chọn có thể nhận được một mô tả hiển thị trong cách sử dụng [xem bên dưới]. Quyền chọn có thể nhận 0, 1 hoặc nhiều giá trị. Tùy chọn nhận giá trị 0 là
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
340 và phải được khai báo bằng cách sử dụng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
341. Theo mặc định, các tùy chọn nhận một giá trị duy nhất, tuy nhiên, bạn có thể định cấu hình tùy chọn để nhận nhiều giá trị bằng cách sử dụng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
342

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
93

Tùy chọn có thể được đánh dấu là bắt buộc. Một tùy chọn bắt buộc không được đặt trong dòng lệnh của người dùng sẽ đưa ra một ngoại lệ trong quá trình phân tích cú pháp

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
94

Các tùy chọn không bắt buộc có thể có giá trị mặc định. Giá trị này sẽ được sử dụng nếu người dùng không đặt tùy chọn trong dòng lệnh

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
95

Một tùy chọn có thể được ẩn bằng phương pháp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
343. Tùy chọn ẩn không được liệt kê trong cách sử dụng, nhưng vẫn có thể được sử dụng trong dòng lệnh của người dùng [đối với người dùng thành thạo]

Nếu giá trị tùy chọn bị giới hạn ở một bộ cố định, bạn có thể đặt các lựa chọn được chấp nhận khác nhau

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
96

Các tùy chọn cũng có thể được khởi tạo từ dạng JSON của chúng

Tranh luận

Không giống như các tùy chọn, các đối số không có khóa và được xác định bởi chỉ mục của chúng. Ví dụ, trong

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
344,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
345 là một đối số

Các đối số không có tên, được xác định bằng cách sử dụng chỉ mục dựa trên 0. Tham số đầu tiên có chỉ số

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
69

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
97

Nếu bạn không đặt chỉ số đối số, máy tính sẽ tự động sử dụng thứ tự khai báo

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
98

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
347 là tùy chọn và được sử dụng trong thông báo sử dụng

Là tùy chọn,

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
331 có thể

  • được ẩn bằng cách sử dụng

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    349

  • bắt buộc sử dụng

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    350

  • có giá trị mặc định bằng cách sử dụng

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    351

  • nhận một số giá trị bằng cách sử dụng

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    352 - chỉ đối số cuối cùng mới có thể có nhiều giá trị

Các đối số cũng có thể được khởi tạo từ dạng JSON của chúng

thế hệ sử dụng

Khi phiên bản

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
332 của bạn được định cấu hình, bạn có thể tạo thông báo sử dụng

Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
99

Nó tạo ra một thông báo sử dụng như thế này

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
00

Nếu bạn cần điều chỉnh thông báo sử dụng, hãy kiểm tra lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
354

Parsing Stage

Khi phiên bản

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
332 của bạn được định cấu hình, bạn có thể phân tích cú pháp dòng lệnh của người dùng để đánh giá từng tùy chọn và đối số

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
01

Phương thức

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
356 trả về một đối tượng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
357 chứa các giá trị. Theo mặc định, nó xác thực dòng lệnh của người dùng và kiểm tra xem từng tùy chọn và đối số bắt buộc đã được đặt chưa cũng như số lượng giá trị mà mỗi tùy chọn nhận được. Bạn có thể tắt xác thực bằng cách chuyển
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
20 làm tham số thứ hai của
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
359. Điều này hữu ích nếu bạn muốn kiểm tra xem một đối số hoặc tùy chọn có xuất hiện ngay cả khi dòng lệnh được phân tích cú pháp không hợp lệ

Bạn có thể kiểm tra xem

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
357 có hợp lệ hay không bằng cách sử dụng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
361

Giai đoạn truy vấn / thẩm vấn

Sau khi được phân tích cú pháp, bạn có thể truy xuất các giá trị của các tùy chọn và đối số từ đối tượng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
357 được phương thức
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
356 trả về

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
02

Một trong các tùy chọn của bạn có thể được đánh dấu là "trợ giúp". Nếu dòng lệnh của người dùng bật tùy chọn "trợ giúp", quá trình xác thực sẽ không thất bại, nhưng bạn có cơ hội kiểm tra xem người dùng có yêu cầu trợ giúp không

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
03

Các tùy chọn và đối số đã nhập

Các lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
330 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
331 được mô tả không được gõ, nghĩa là chỉ nhận các giá trị Chuỗi.
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
366 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
367 cho phép bạn chỉ định một loại, vì vậy giá trị thô [Chuỗi] được chuyển đổi thành loại đã chỉ định

Thay vì

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
330 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
331, hãy sử dụng
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
366 và
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
367 trong định nghĩa
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
332

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
04

Sau đó, bạn có thể truy xuất các giá trị đã chuyển đổi như sau

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
05

Bụi cây. x CLI có thể chuyển đổi thành các lớp

  • có một hàm tạo với một đối số

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    373, chẳng hạn như
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    374 hoặc
    HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    38

  • với phương thức tĩnh

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    376 hoặc
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    377

  • với phương thức tĩnh

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    378, chẳng hạn như kiểu nguyên thủy và kiểu liệt kê

Ngoài ra, bạn có thể triển khai

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
379 của riêng mình và hướng dẫn CLI sử dụng trình chuyển đổi này

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
06

Đối với boolean, các giá trị boolean được đánh giá là

HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
19.
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
381,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
382,
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
294,
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
19

Nếu một trong các tùy chọn của bạn có loại là

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
385, nó sẽ tự động tính toán tập hợp các lựa chọn

Sử dụng chú thích

Bạn cũng có thể xác định CLI của mình bằng chú thích. Định nghĩa được thực hiện bằng cách sử dụng chú thích trên lớp và trên các phương thức setter

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
07

Sau khi được chú thích, bạn có thể xác định

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
332 và thêm các giá trị bằng cách sử dụng

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
08

Bụi cây. x Trình khởi chạy

The vert. x

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 được sử dụng trong fat jar làm lớp chính và bởi tiện ích dòng lệnh
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
85. Nó thực thi một tập hợp các lệnh như run, bare, start…​

Mở rộng đỉnh. x Trình khởi chạy

Bạn có thể mở rộng bộ lệnh bằng cách triển khai

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
389 của riêng mình [chỉ trong Java]

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
09

Bạn cũng cần triển khai

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
390

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
10

Sau đó, tạo

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
391 và thêm một dòng cho biết tên đầy đủ của nhà máy

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
11

Xây dựng jar chứa lệnh. Đảm bảo bao gồm tệp SPI [______3392]

Sau đó, đặt jar chứa lệnh vào đường dẫn lớp của fat-jar của bạn [hoặc bao gồm nó bên trong] hoặc trong thư mục

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
265 của đỉnh của bạn. x và bạn sẽ có thể thực thi

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
12

Sử dụng Trình khởi chạy trong lọ chất béo

Để sử dụng lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 trong một lọ chất béo, chỉ cần đặt
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
208 của MANIFEST thành
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
206. Ngoài ra, hãy đặt mục nhập
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
210 MANIFEST thành tên của cột chính của bạn

By default, it executed the

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
168 command. Tuy nhiên, bạn có thể định cấu hình lệnh mặc định bằng cách đặt mục nhập
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
399 MANIFEST. Lệnh mặc định được sử dụng nếu hũ mỡ được khởi chạy mà không có lệnh

Phân loại Trình khởi chạy

Bạn cũng có thể tạo một lớp con của

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 để bắt đầu ứng dụng của mình. Lớp học đã được thiết kế để dễ dàng mở rộng

Một phân lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 có thể

  • tùy chỉnh đỉnh. x cấu hình trong

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    402

  • lấy đỉnh. x được tạo bởi lệnh "run" hoặc "bare" bằng cách ghi đè

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    403

  • định cấu hình cột dọc và lệnh mặc định với

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    404 và
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    405

  • thêm/xóa lệnh sử dụng

    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    406 và
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    407

Trình khởi chạy và mã thoát

Khi bạn sử dụng lớp

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
205 làm lớp chính, nó sẽ sử dụng mã thoát sau

  • HttpServerResponse response = request.response[];
    response.putHeader["Content-Type", "text/plain"];
    response.write["some text"];
    response.end[];
    69 nếu quá trình kết thúc suôn sẻ hoặc nếu một lỗi chưa được phát hiện được đưa ra

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    294 cho lỗi mục đích chung

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    411 nếu Vert. x không thể được khởi tạo

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    412 nếu không thể bắt đầu, tìm thấy hoặc dừng quá trình sinh sản. Mã lỗi này được sử dụng bởi lệnh
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    220 và
    dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    221

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    415 nếu cấu hình hệ thống không đáp ứng yêu cầu hệ thống [shc as java not found]

  • dependencies {
     compile 'io.vertx:vertx-core:4.3.7'
    }
    416 nếu không thể triển khai cột dọc chính

Định cấu hình Vert. bộ đệm x

Khi Vert. x cần đọc một tệp từ đường dẫn lớp [được nhúng trong tệp mỡ, trong tệp jar ở dạng đường dẫn lớp hoặc tệp nằm trên đường dẫn lớp], nó sao chép tệp đó vào thư mục bộ đệm. Lý do đằng sau điều này rất đơn giản. đọc tệp từ jar hoặc từ luồng đầu vào đang bị chặn. Vì vậy, để tránh phải trả giá mỗi lần, Vert. x sao chép tệp vào thư mục bộ đệm của nó và đọc nó từ đó mỗi lần đọc tiếp theo. Hành vi này có thể được cấu hình

Đầu tiên, theo mặc định, Vert. x sử dụng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
417 làm thư mục bộ đệm. Nó tạo một thư mục duy nhất bên trong thư mục này để tránh xung đột. Vị trí này có thể được định cấu hình bằng cách sử dụng thuộc tính hệ thống
dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
020. Chẳng hạn, nếu thư mục làm việc hiện tại không thể ghi được [chẳng hạn như trong ngữ cảnh vùng chứa bất biến], hãy khởi chạy ứng dụng của bạn với

request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
13

Important

thư mục phải được ghi

Khi bạn đang chỉnh sửa các tài nguyên như HTML, CSS hoặc JavaScript, cơ chế bộ đệm này có thể gây khó chịu vì nó chỉ phục vụ phiên bản đầu tiên của tệp [và vì vậy bạn sẽ không thấy các chỉnh sửa của mình nếu bạn tải lại trang của mình]. Để tránh hành vi này, hãy khởi chạy ứng dụng của bạn với

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
419. Với cài đặt này, Vert. x vẫn sử dụng bộ đệm, nhưng luôn làm mới phiên bản được lưu trong bộ đệm với nguồn ban đầu. Vì vậy, nếu bạn chỉnh sửa một tệp được cung cấp từ đường dẫn lớp và làm mới trình duyệt của mình, Vert. x đọc nó từ đường dẫn lớp, sao chép nó vào thư mục bộ đệm và phục vụ nó từ đó. Không sử dụng cài đặt này trong quá trình sản xuất, nó có thể giết chết màn trình diễn của bạn

Cuối cùng, bạn có thể tắt hoàn toàn bộ đệm bằng cách sử dụng

dependencies {
 compile 'io.vertx:vertx-core:4.3.7'
}
420. Cài đặt này không phải là không có hậu quả. Vert. x sẽ không thể đọc bất kỳ tệp nào từ đường dẫn lớp [chỉ từ hệ thống tệp]. Hãy thật cẩn thận khi sử dụng cài đặt này

Chủ Đề