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
14 của bạn]request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
io.vertx
vertx-core
4.3.7
Gradle [trong tệp
15 của bạn]request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
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 nhauChỉ đị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ácTạ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
0Hoặc để nhận một yêu cầu HTTP
io.vertx
vertx-core
4.3.7
1Some 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 loopThe 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
2Vert. 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 Vertxkế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ạiBạ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
5Ghi 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ứcrequest.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ứcthậ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"];
22dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
0thậ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ạiXem 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'
}
1Có 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"];
26Future composition
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
27 có thể được sử dụng để xâu chuỗi tương laikhi 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'
}
2In this example, 3 operations are chained together
a file is created
dữ liệu được ghi trong tập tin này
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 failBeyond 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"];
35Future 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 faileddependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
3The 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 successOn 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"];
44Alternatively, you can pass a list [potentially empty] of futures
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
4While 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 faileddependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
5A list of futures can be used also
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
6Thà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ôngdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
7A list of futures can be used also
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
8CompletionStage 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 operationsWe 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 independencies {
compile 'io.vertx:vertx-core:4.3.7'
}
9We 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 variantsthe first variant takes just a
51 and calls therequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50 methods from the thread that resolves therequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
51 instance, andrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
biến thể thứ hai lấy thêm tham số
61 để gọi các phương thứcrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
50 trên Vert. x contextrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
Important
In most cases the variant with arequest.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 clientsHere 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 contextVertx vertx = Vertx.vertx[];
0Verticles
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 interfaceThey 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"];
69Here’s an example verticle
Vertx vertx = Vertx.vertx[];
1Normally 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 methodBạ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[];
2Similarly, 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[];
3INFO. 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 VerticlesThese 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"];
71Vertx vertx = Vertx.vertx[];
4Worker 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 yourselfGhi chú
Deploying Verticle instances is Java onlyVertx vertx = Vertx.vertx[];
5You 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[];
6Rules 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[];
7If no prefix is present, Vert. x will look for a suffix and use that to lookup the factory, e. g
Vertx vertx = Vertx.vertx[];
8If 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 wishWaiting 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[];
9The 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"];
76Un-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]];
0Specifying 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]];
1This 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]];
2This 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 followsVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
3Accessing environment variables in a Verticle
Environment variables and system properties are accessible using the Java API
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
4High 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 switchVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
5When enabling high availability, no need to add
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
80More 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"];
82Vert. 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óngYou can now run verticles by using the
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
84 command. Here are some examplesVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
6You can even run Java source verticles without compiling them first
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
7Vert. 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 lineCausing 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 downThis 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 poolTo retrieve the context, use the
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
90 methodVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
8If 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]];
9When 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"];
0When 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"];
91request.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 configurationExecuting 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 handlerrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
2The 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"];
94There 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 cancelledThe 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 timerrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
3Cancelling timers
To cancel a periodic timer, call
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
97 specifying the timer id. For examplerequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
4Automatic 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 verticleA different worker pool can be specified in deployment options
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
5The Event Bus
The
request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
99 is the nervous system of Vert. xThere 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[];
00The 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 messagesHowever, 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 sendThe 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"];
6There 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 examplerequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
7When 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[];
04The 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[];
05This 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 examplerequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
8When 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 objectrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
9Un-registering Handlers
To unregister a handler, call
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
08If 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[];
09HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
0Publishing 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 toHttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
1That 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[];
11HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
2Setting 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ảnHttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
3Message 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[];
13The
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 publishedThe headers of the message are available with
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
15Acknowledging 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 busIn 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[];
18When 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[];
4The sender
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
5The 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
19 nếu tin nhắn được duy trì thành công trong bộ nhớ hoặcHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
20 nếu khôngHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
A message consumer which processes an order might acknowledge with
19 when the order has been successfully processed so it can be deleted from the databaseHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
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[];
12If 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
23HttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
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 itMessage 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 messageHttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
6If 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[];
7You unregister a message codec with
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
26Message 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
27 hoặcHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
các loại triển khai giao diện
28HttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
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ậtBạ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
31, andHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
32HttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
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[];
8You 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 managerClustering 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[];
9Automatic 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
00The 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 hostWhen used in containers, you can also configure the public host and port
io.vertx
vertx-core
4.3.7
01JSON
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 objectsA 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
02You can create a JSON object from a map as follows
io.vertx
vertx-core
4.3.7
03Putting 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 objectThe method invocations can be chained because of the fluent API
io.vertx
vertx-core
4.3.7
04Getting 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
05Mapping 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
06Note 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, etcHowever, 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 formJSON 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 JSONA 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
07Adding 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
08Getting 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
09Encoding 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 formTạ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
10Json 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
11After 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
12You 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[];
53bộ đệ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[];
54Bộ đệ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
13Create 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
14Tạ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
15Create a buffer from a byte[]
io.vertx
vertx-core
4.3.7
16Create 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
17Ghi 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ộ đệmAppending 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 typesThe 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
18Random 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 dataThe buffer will always expand as necessary to accommodate the data
io.vertx
vertx-core
4.3.7
19Reading 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
20Working 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 consumptionIn the following example, value 200 is set at specified position with just one byte
io.vertx
vertx-core
4.3.7
21The 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 + 1Copying 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 bufferSlicing 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 buffersBuffer 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
22Configuring 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
23Start 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 alternativesTo tell the server to listen at the host and port as specified in the options
io.vertx
vertx-core
4.3.7
24Or 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
25The 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 thatThe 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
26Listening 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 onTo 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
27Getting 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
28When 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[];
74This 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 socketThis 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
29Writing 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
50Write 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
51Handling 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ắmYou 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 handshakeEvent 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[];
82Local 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[];
84The 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[];
86Sending 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 systemPlease 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
52Streaming 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 streamsSee 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[];
91The 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 resourcesThe 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
53Automatic 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
54hoặ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
55Once 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
56Configuring 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
57Making 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
58Configuring 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[];
98Ghi 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
59By 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'
}
00Here is the output of a simple HTTP server
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
01By 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'
}
02Here is the same output with simple buffer format
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
03Clients can also log network activity
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
04Network 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 mindlogging 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 clientsEnabling SSL/TLS on the server
SSL/TLS is enabled with
io.vertx
vertx-core
4.3.7
003By 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'
}
05Alternatively you can read the key store yourself as a buffer and provide that directly
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
06Key/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 storesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
07Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
08Another way of providing server private key and certificate separately using
io.vertx
vertx-core
4.3.7
006 filesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
09Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
10Vert. 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 misuseFinally, 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'
}
11Specifying 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'
}
12Alternatively you can read the trust store yourself as a buffer and provide that directly
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
13Certificate 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 storesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
14Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
15Another way of providing server certificate authority using a list
io.vertx
vertx-core
4.3.7
006 filesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
16Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
17Enabling 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à saidependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
18If
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 trustsBy 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'
}
19Likewise 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 succeeddependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
20Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
21Certificate 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 storesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
22Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
23Another way of providing server certificate authority using a list
io.vertx
vertx-core
4.3.7
006 filesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
24Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
25Chỉ đị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
013dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
26Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
27Key/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 storesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
28Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
29Another way of providing server private key and certificate separately using
io.vertx
vertx-core
4.3.7
006 filesdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
30Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
31Keep 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 insecureIt 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 configurationsdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
32The client can also be configured to trust all certificates
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
33Note that self-signed certificates also work for other TCP protocols like HTTPS
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
34Revoking 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 usedependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
35Cấu hình bộ đệm cũng được hỗ trợ
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
36Configuring the Cipher suite
By default, the TLS configuration will use the list of Cipher suites of the SSL engine
JDK SSL engine when
026 is usedio.vertx vertx-core 4.3.7
OpenSSL engine when
027 is usedio.vertx vertx-core 4.3.7
This Cipher suite can be configured with a suite of enabled ciphers
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
37When 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 configurationConfiguring 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'
}
38Protocol 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 configurationSSL 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
032 options when it is setio.vertx vertx-core 4.3.7
nếu không thì
026io.vertx vertx-core 4.3.7
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
39Server 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
034io.vertx vertx-core 4.3.7
the certificate CN or SAN DNS certificate to match a wildcard name, e. g
035io.vertx vertx-core 4.3.7
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
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 doneio.vertx vertx-core 4.3.7
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 pairsJava 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ậpdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
41The 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'
}
42It 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 implementationUsing a proxy for client connections
The
io.vertx
vertx-core
4.3.7
042 supports either a HTTP/1. x CONNECT, SOCKS4a or SOCKS5 proxyThe 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 passwordHere’s an example
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
43The 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 domainsdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
44Using 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 classpathdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
45dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
46Writing 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'
}
47Configuring 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 itdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
48Configuring 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
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 directlyio.vertx vertx-core 4.3.7
To handle
io.vertx
vertx-core
4.3.7
049 requests, TLS must be enabled along with
io.vertx
vertx-core
4.3.7
054dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
49ALPN 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 soTo 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 prefaceWarning
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
050When 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
064.io.vertx vertx-core 4.3.7
065 as recommended by the HTTP/2 RFCio.vertx vertx-core 4.3.7
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'
}
50See 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 alternativesTo tell the server to listen at the host and port as specified in the options
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
51Or 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'
}
52The 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
068The 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 exampledependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
53Getting notified of incoming requests
To be notified when a request arrives you need to set a
io.vertx
vertx-core
4.3.7
070dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
54Handling 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 requestThe 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 thingsEach 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 objectHere’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'
}
55Request version
The version of HTTP specified in the request can be retrieved with
io.vertx
vertx-core
4.3.7
078Request 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 requestNote 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 URIFor 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
082Request query
Use
io.vertx
vertx-core
4.3.7
083 to return the query part of the URIFor example, if the request URI was
io.vertx
vertx-core
4.3.7
084Sau đó, truy vấn sẽ là
io.vertx
vertx-core
4.3.7
085Request headers
Use
io.vertx
vertx-core
4.3.7
075 to return the headers of the HTTP requestThis 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 keyIt also has case-insensitive keys, that means you can do the following
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
56Request host
Use
io.vertx
vertx-core
4.3.7
088 to return the host of the HTTP requestFor 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 returnedRequest parameters
Use
io.vertx
vertx-core
4.3.7
074 to return the parameters of the HTTP requestJust 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 nameThô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
094Then the parameters would contain the following
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
57Note 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 hereRemote address
The address of the sender of the request can be retrieved with
io.vertx
vertx-core
4.3.7
096Absolute 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
097End 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 readReading 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 exampledependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
58The 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 bodyTrong 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'
}
59This 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 receiveddependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
60Streaming 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 instanceXem 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 đọcdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
61Form 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
111Handling 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 requestThis 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 instancedependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
62File 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'
}
63The 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 explanationIf you just want to upload the file to disk somewhere you can use
io.vertx
vertx-core
4.3.7
116dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
64Warning
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 informationHandling 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 cookiesTo 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
120The 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 propertiesSame 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
122Same 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'
}
65Handling 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 serverYou need to have Brotli4j on the classpath to decompress Brotli
Maven [trong
14 của bạn]request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
66Gradle [trong tệp
15 của bạn]request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
67When 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 exampledependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
68HTTP/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
076You 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
130Use
io.vertx
vertx-core
4.3.7
131 to set a different codeYou can also specify a custom status message with
io.vertx
vertx-core
4.3.7
132If 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 clientWriting 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 operationsThese 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'
}
69With 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'
}
70With 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'
}
71Writing 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
134The 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 worryEnding HTTP responses
Once you have finished with the HTTP response you should
io.vertx
vertx-core
4.3.7
136 itThis can be done in several ways
With no arguments, the response is simply ended
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
72It 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 exampledependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
73Closing the underlying connection
You can close the underlying TCP connection with
io.vertx
vertx-core
4.3.7
138Non 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
139HTTP/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
140dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
74Or you can use
io.vertx
vertx-core
4.3.7
141dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
75Tấ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'
}
76Default 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 outWhen 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 streamTo add trailers to the response, add them directly to the
io.vertx
vertx-core
4.3.7
143dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
77Or use
io.vertx
vertx-core
4.3.7
144dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
78Serving 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 responseOr you could load it it one go using
io.vertx
vertx-core
4.3.7
146 and write it straight to the responseAlternatively, 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 filesHere’s a very simple web server that serves files from the file system using sendFile
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
79Sending 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
148Please 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 encryptionWarning
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 WebWhen 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'
}
80You 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'
}
81Piping 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
071Here’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'
}
82You 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[];
89Sending 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 setdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
83Writing 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 exampledependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
84These 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'
}
85By default, the
io.vertx
vertx-core
4.3.7
161 [0] error code is sent, another code can sent insteaddependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
86The 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
163dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
87Server 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'
}
88Khi 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 anymorePhươ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 sauHandling 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 TLSHandling 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 longYou 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
171HTTP 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
172By 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. xIf 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
175dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
89Be 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
177HTTP 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'
}
90Ghi chú
use
io.vertx
vertx-core
4.3.7
178 static methods to create
io.vertx
vertx-core
4.3.7
179Brotli and zstandard libraries need to be added to the classpath
Maven [trong
14 của bạn]request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
91Gradle [trong tệp
15 của bạn]request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
92When 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'
}
93Creating an HTTP client
You create an
io.vertx
vertx-core
4.3.7
182 instance with default options as followsdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
94If you want to configure options for the client, you create it as follows
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
95Vert. x supports HTTP/2 over TLS
io.vertx
vertx-core
4.3.7
049 and over TCP
io.vertx
vertx-core
4.3.7
050By 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
186For
io.vertx
vertx-core
4.3.7
049 requests, TLS must be enabled with Application-Layer Protocol Negotiationdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
96For
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/2dependencies {
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 serverThe 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 arrivesWhen 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 RFCLogging network client activity
For debugging purposes, network activity can be logged
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
98See 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'
}
99The 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[];
00Writing 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ư sauVertx vertx = Vertx.vertx[];
01The 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 keyYou can also write headers using
io.vertx
vertx-core
4.3.7
195Vertx vertx = Vertx.vertx[];
02If 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 serverYou 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
200Vertx vertx = Vertx.vertx[];
03You 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 setVertx 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 setVertx 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
207Vertx vertx = Vertx.vertx[];
06Streaming Request body
The
io.vertx
vertx-core
4.3.7
208 method send requests at onceSometimes 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 bodyHere are some examples of writing a POST request with a body
Vertx vertx = Vertx.vertx[];
07Methods exist to write strings in UTF-8 encoding and in any specific encoding and to write buffers
Vertx vertx = Vertx.vertx[];
08If 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 functionVertx vertx = Vertx.vertx[];
09When 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 wireThe 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 providedConsequently, 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 otherwiseIf 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 bodyIf 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-frontEnding 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 operationsEnding 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[];
10Or 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 argumentsVertx vertx = Vertx.vertx[];
11Using 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 instanceYou can pipe to it from any
HttpServerResponse response = request.response[];
response.putHeader["Content-Type", "text/plain"];
response.write["some text"];
response.end[];
89 instanceFor, example, you could pipe a file on disk to a http request body as follows
Vertx vertx = Vertx.vertx[];
12Chunked 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
224In 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-frontVertx vertx = Vertx.vertx[];
13Request 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
227Nế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 exampleVertx vertx = Vertx.vertx[];
14Stream 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[];
15By default the NO_ERROR [0] error code is sent, another code can sent instead
Vertx vertx = Vertx.vertx[];
16The 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
230Vertx vertx = Vertx.vertx[];
17Handling 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 objectYou 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
234Vertx vertx = Vertx.vertx[];
18Using 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 instanceResponse headers and trailers
Http responses can contain headers. Use
io.vertx
vertx-core
4.3.7
238 to get the headersThe object returned is a
io.vertx
vertx-core
4.3.7
087 as HTTP headers can contain multiple values for single keysVertx vertx = Vertx.vertx[];
19Chunked 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
087Reading 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 bodyVertx vertx = Vertx.vertx[];
20If 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[];
21Or 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 readVertx vertx = Vertx.vertx[];
22Response 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 bodyRequest and response composition
The client interface is very simple and follows this pattern
197 a connectionio.vertx vertx-core 4.3.7
208 orio.vertx vertx-core 4.3.7
137/io.vertx vertx-core 4.3.7
210 the request to the serverio.vertx vertx-core 4.3.7
handle the beginning of the
200io.vertx vertx-core 4.3.7
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ạnThe 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-loopVertx vertx = Vertx.vertx[];
23Confining 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 racesVertx vertx = Vertx.vertx[];
24When 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[];
25If 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 involvedVertx vertx = Vertx.vertx[];
26Reading cookies from the response
You can retrieve the list of cookies from a response using
io.vertx
vertx-core
4.3.7
255Alternatively you can just parse the
io.vertx
vertx-core
4.3.7
256 headers yourself in the response30x 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 receivesa
258,io.vertx vertx-core 4.3.7
259,io.vertx vertx-core 4.3.7
260 orio.vertx vertx-core 4.3.7
261 status code along with a HTTP GET or HEAD methodio.vertx vertx-core 4.3.7
a
262 status code, in addition the directed request perform an HTTP GET methodio.vertx vertx-core 4.3.7
Here’s an example
Vertx vertx = Vertx.vertx[];
27The 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
264Vertx vertx = Vertx.vertx[];
28One 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[];
29The 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
267when
266 is returned, the original response is processedio.vertx vertx-core 4.3.7
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
199 methodio.vertx vertx-core 4.3.7
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 bodyThe 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 bodyThe 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 objectThis 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 requestThis is used in conjunction with `sendHead`to send the head of the request
Here’s an example
Vertx vertx = Vertx.vertx[];
30On 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 headerThis is done by setting the option
io.vertx
vertx-core
4.3.7
275If 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 bodyVertx vertx = Vertx.vertx[];
31You 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[];
32Creating HTTP tunnels
HTTP tunnels can be created with
io.vertx
vertx-core
4.3.7
278Vertx vertx = Vertx.vertx[];
33The 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 buffersClient 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[];
34If the client does not want to receive a pushed request, it can reset the stream
Vertx vertx = Vertx.vertx[];
35When 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[];
36Enabling 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 addedAccept-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 itIf 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 clientBy 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 trueWhen 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 responseThe maximum number of connections to pool for each server is configured using
io.vertx
vertx-core
4.3.7
288When 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 headerVertx vertx = Vertx.vertx[];
37You 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 millisecondsHTTP/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 disabledWhen 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 serverHTTP/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 usedWhen 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 usedVertx vertx = Vertx.vertx[];
38The 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 settingHTTP/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 instanceAlternatively 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 millisecondsHTTP connections
The
io.vertx
vertx-core
4.3.7
298 offers the API for dealing with HTTP connection events, lifecycle and settingsHTTP/2 implements fully the
io.vertx
vertx-core
4.3.7
298 APIHTTP/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 operationsServer connections
The
io.vertx
vertx-core
4.3.7
501 method returns the request connection on the serverVertx vertx = Vertx.vertx[];
39A connection handler can be set on the server to be notified of any incoming connection
Vertx vertx = Vertx.vertx[];
40Client connections
The
io.vertx
vertx-core
4.3.7
502 method returns the request connection on the clientVertx vertx = Vertx.vertx[];
39A connection handler can be set on the client to be notified when a connection has been established happens
Vertx vertx = Vertx.vertx[];
42Connection settings
The configuration of an HTTP/2 is configured by the
io.vertx
vertx-core
4.3.7
503 data objectEach 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 serverThe settings can be changed at any time after the connection is established
Vertx vertx = Vertx.vertx[];
43As 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[];
44Conversely the
io.vertx
vertx-core
4.3.7
506 is notified when the new remote settings are receivedVertx vertx = Vertx.vertx[];
45Ghi chú
this only applies to the HTTP/2 protocolConnection 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 endpointVertx vertx = Vertx.vertx[];
46Vert. 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[];
47The 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 protocolConnection 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 connectionVertx vertx = Vertx.vertx[];
48The
io.vertx
vertx-core
4.3.7
509 notifies when all streams have been closed, the connection is not yet closedIt’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[];
49Conversely, it is also possible to be notified when {@literal GOAWAY} are received
Vertx vertx = Vertx.vertx[];
50The
io.vertx
vertx-core
4.3.7
509 will be called when all current streams have been closed and the connection can be closedVertx vertx = Vertx.vertx[];
51This applies also when a {@literal GOAWAY} is received
Ghi chú
this only applies to the HTTP/2 protocolConnection close
Connection
io.vertx
vertx-core
4.3.7
296 closes the connectionit 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 closedClient 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[];
52You can also create a shared HTTP client in each verticle
Vertx vertx = Vertx.vertx[];
53The 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[];
54Server 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[];
55Dị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 strategyLet’s now imagine a client such as
Vertx vertx = Vertx.vertx[];
56Vert. x delegates the requests to one of the server sequentially
Vertx vertx = Vertx.vertx[];
57Consequently 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[];
58Using 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 methodVertx vertx = Vertx.vertx[];
59The
io.vertx
vertx-core
4.3.7
516 setting acts as the default client settingThe
io.vertx
vertx-core
4.3.7
517 overrides the default client settingsetting the value to
20 will disable SSL/TLS even if the client is configured to use SSL/TLSHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
setting the value to
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 reusedHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
Likewise
io.vertx
vertx-core
4.3.7
515 scheme also overrides the default client settingServer 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 instanceWhen 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
522Vertx vertx = Vertx.vertx[];
60You can choose to reject the WebSocket by calling
io.vertx
vertx-core
4.3.7
523Vertx vertx = Vertx.vertx[];
61You 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"];
50Vertx vertx = Vertx.vertx[];
62Ghi chú
the WebSocket will be automatically accepted after the handler is called unless the WebSocket’s handshake has been setUpgrading 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 requestVertx vertx = Vertx.vertx[];
63The 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 handshakeWebSockets on the client
The Vert. x
io.vertx
vertx-core
4.3.7
182 supports WebSocketsYou can connect a WebSocket to a server using one of the
io.vertx
vertx-core
4.3.7
533 operations and providing a handlerThe handler will be called with an instance of
io.vertx
vertx-core
4.3.7
154 when the connection has been madeVertx vertx = Vertx.vertx[];
64By 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 headerVertx vertx = Vertx.vertx[];
65You can also set a different header
Vertx vertx = Vertx.vertx[];
66Ghi chú
older versions of the WebSocket protocol use
io.vertx
vertx-core
4.3.7
536 insteadWriting 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[];
67If 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âyWriting 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
543Here’s an example for binary frames
Vertx vertx = Vertx.vertx[];
68In 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
545Here’s an example
Vertx vertx = Vertx.vertx[];
69Reading frames from WebSockets
To read frames from a WebSocket you use the
io.vertx
vertx-core
4.3.7
546The frame handler will be called with instances of
io.vertx
vertx-core
4.3.7
547 when a frame arrives, for exampleVertx vertx = Vertx.vertx[];
70Closing WebSockets
Use
io.vertx
vertx-core
4.3.7
548 to close the WebSocket connection when you have finished with itPiping 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 pipesWhen 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
553Using 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 passwordHere’s an example of using an HTTP proxy
Vertx vertx = Vertx.vertx[];
71When 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[];
72The 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[];
73Ghi 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 connectionYou 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 domainsVertx vertx = Vertx.vertx[];
74Handling 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[];
75Using 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 classpathdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
45Vertx vertx = Vertx.vertx[];
77Automatic 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 betweencá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 manualLocal 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 instanceThey only allow certain data types to be used as keys and values
immutable types [e. g. strings, booleans, … etc], or
types implementing the
561 interface [buffers, JSON arrays, JSON objects, or your own shareable objects]io.vertx vertx-core 4.3.7
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 performanceHere’s an example of using a shared local map
Vertx vertx = Vertx.vertx[];
78Asynchronous 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 nodeThis 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
27 interface [buffers, JSON arrays, JSON objects, or your own cluster serializable objects], orHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
các loại triển khai giao diện
28HttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
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[];
79When 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 modeIf your application doesn’t need data to be shared with every other node, you can retrieve a local-only map
Vertx vertx = Vertx.vertx[];
80Putting data in a map
You put data in a map with
io.vertx
vertx-core
4.3.7
568The actual put is asynchronous and the handler is notified once it is complete
Vertx vertx = Vertx.vertx[];
81Getting data from a map
You get data from a map with
io.vertx
vertx-core
4.3.7
569The actual get is asynchronous and the handler is notified with the result some time later
Vertx vertx = Vertx.vertx[];
82Other 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 operationsAsynchronous 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 timeAsynchronous 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 lockWhile 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 itVertx vertx = Vertx.vertx[];
83You 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[];
84See the
io.vertx
vertx-core
4.3.7
575 for a detailed list of lock operationsImportant
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 modeIf 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[];
85Asynchronous 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
576You obtain an instance with
io.vertx
vertx-core
4.3.7
577Vertx vertx = Vertx.vertx[];
86Once 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ậpImportant
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 modeIf 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[];
87Using 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 systemThere is one file system object per Vert. x instance, and you obtain it with
io.vertx
vertx-core
4.3.7
580A 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[];
88The 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 RuleHere’s the copy using the blocking API
Vertx vertx = Vertx.vertx[];
89Many 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[];
90Asynchronous 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 followsVertx 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 WebSocketsThey 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 methodThe parameters to the method are
589. the buffer to writeio.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 offsetio.vertx vertx-core 4.3.7
591. the result handlerio.vertx vertx-core 4.3.7
Here is an example of random access writes
Vertx vertx = Vertx.vertx[];
92Random 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 methodThe parameters to the method are
589. the buffer into which the data will be readio.vertx vertx-core 4.3.7
595. an integer offset into the buffer where the read data will be placedio.vertx vertx-core 4.3.7
590. the position in the file where to read data fromio.vertx vertx-core 4.3.7
597. the number of bytes of data to readio.vertx vertx-core 4.3.7
591. the result handlerio.vertx vertx-core 4.3.7
Here’s an example of random access reads
Vertx vertx = Vertx.vertx[];
93Opening 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 methodsYou 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'
}
005Bạ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'
}
006Flushing 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 methodThis 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
584Vertx vertx = Vertx.vertx[];
94You can also use the pipe to write file content into HTTP responses, or more generally in any
io.vertx
vertx-core
4.3.7
586Accessing 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 địnhTheo 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[];
19Ghi chú
các thuộc tính hệ thống này được đánh giá một lần khi lớpdependencies {
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ậnVertx vertx = Vertx.vertx[];
95dependencies {
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 theoGử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[];
96Nhậ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 ngheBê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 đượcdependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
034 có các phương pháp sau
036. InetSocketAddress đại diện cho người gửi gói tindependencies { compile 'io.vertx:vertx-core:4.3.7' }
037. Bộ đệm chứa dữ liệu nhận đượcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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[];
97Xin 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[];
98Tấ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 MulticastBằ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 MulticastBê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
042. InetSocketAddress đại diện cho người gửi gói tindependencies { compile 'io.vertx:vertx-core:4.3.7' }
043. Bộ đệm chứa dữ liệu nhận đượcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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[];
99Bỏ 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]];
00Chặ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 đâyVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
01Thuộ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
047 Đặt kích thước bộ đệm gửi theo bytedependencies { compile 'io.vertx:vertx-core:4.3.7' }
048 Đặt kích thước bộ đệm nhận TCP theo bytedependencies { 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ị đóngdependencies { compile 'io.vertx:vertx-core:4.3.7' }
050dependencies { 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 interfacedependencies { 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ếpdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ênmá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]];
02Bạ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]];
03Tạ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]];
04tra 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]];
05tra 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]];
06tra 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]];
07giả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]];
08giả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]];
09giả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]];
10giả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]];
11Xin 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áchdependencies {
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]];
12giả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]];
13giả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]];
14giả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]];
15Xin 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 SRVVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
16Vui 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]];
17tra 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]];
18Error 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ơnDnsResponseCodes có thể là
063 Không tìm thấy bản ghi cho một truy vấn nhất địnhdependencies { compile 'io.vertx:vertx-core:4.3.7' }
064 Lỗi định dạngdependencies { 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êndependencies { compile 'io.vertx:vertx-core:4.3.7' }
067 Không được triển khai bởi Máy chủ DNSdependencies { compile 'io.vertx:vertx-core:4.3.7' }
068 Máy chủ DNS từ chối truy vấndependencies { compile 'io.vertx:vertx-core:4.3.7' }
069 Tên miền không nên tồn tạidependencies { compile 'io.vertx:vertx-core:4.3.7' }
070 Bản ghi tài nguyên không nên tồn tạidependencies { compile 'io.vertx:vertx-core:4.3.7' }
071 RRSET không tồn tạidependencies { compile 'io.vertx:vertx-core:4.3.7' }
072 Tên không có trong khu vựcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
073 Cơ chế mở rộng không hợp lệ cho phiên bảndependencies { compile 'io.vertx:vertx-core:4.3.7' }
074 Chữ ký xấudependencies { compile 'io.vertx:vertx-core:4.3.7' }
075 Khóa saidependencies { compile 'io.vertx:vertx-core:4.3.7' }
076 Dấu thời gian không hợp lệdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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]];
19Dò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[];
89Hã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
586Mộ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'
}
082Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
20Có 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 itVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
21Ví 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 đã đầyVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
22Chú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]];
23Và 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ơnMuố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ạiBạn có thể được thông báo khi hoạt động hoàn tất
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
25Khi 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 đíchVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
26When you need to abort the transfer, you need to close it
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
27Khi đườ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ụcNhư đã 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
102 kiểm soát hành vi khi xảy ra lỗidependencies { compile 'io.vertx:vertx-core:4.3.7' }
103 kiểm soát hành vi khi luồng đọc kết thúcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
104 kiểm soát hành vi trong mọi trường hợpdependencies { compile 'io.vertx:vertx-core:4.3.7' }
Đây là một ví dụ ngắn
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
28Bâ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ơnReadStream
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
118. đặt trình xử lý sẽ nhận các mục từ ReadStreamdependencies { 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 cumulativedependencies { 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ụcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
122dependencies { compile 'io.vertx:vertx-core:4.3.7' }
123. được gọi khi có ngoại lệ xảy ra trên ReadStreamdependencies { 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 TCPdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ế độ
128 đặt chế độ chảydependencies { compile 'io.vertx:vertx-core:4.3.7' }
129 đặt chế độ tìm nạp và đặt lại yêu cầu thànhdependencies { compile 'io.vertx:vertx-core:4.3.7' }
69HttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
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ếdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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
145Chức năng
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ảnHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
139. đặt số lượng đối tượng tại đó hàng đợi ghi được coi là đầy và phương thứcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
140 trả vềdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ớiHttpServerResponse 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ộ đệmHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
140. trả vềdependencies { compile 'io.vertx:vertx-core:4.3.7' }
19 nếu hàng đợi ghi được coi là đầyHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
145. Sẽ được gọi nếu một ngoại lệ xảy ra trêndependencies { compile 'io.vertx:vertx-core:4.3.7' }
586io.vertx vertx-core 4.3.7
095. Trình xử lý sẽ được gọi nếudependencies { compile 'io.vertx:vertx-core:4.3.7' }
586 được coi là không còn đầyio.vertx vertx-core 4.3.7
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]];
29Trình phân tích bản ghi sẽ tạo ra
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
30Hãy xem mã liên quan
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
31Bạ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'
}
149Trì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]];
33Trì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]];
34Phâ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]];
35Chế độ 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]];
36You can do the same with arrays as well
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
37Bạn cũng có thể giải mã POJO
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
38Bấ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]];
39Trì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.
150dependencies { compile 'io.vertx:vertx-core:4.3.7' }
luồng json được phân tách bằng dòng.
151dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Để biết thêm chi tiết, hãy xem lớp
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
152Chỉ 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 thiVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
40Warning
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ặcrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
91Theo 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ânMộ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'
}
160Cá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]];
41Phải đóng worker executor khi không cần thiết nữa
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
42Khi 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]];
43Ghi chú
cấu hình được đặt khi nhóm công nhân được tạoChỉ 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'
}
161Bạ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'
}
162Dò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ìnhVert. 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óngChạ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'
}
168Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
44Triển khai một cột JavaScript
Triển khai một cột dọc Groovy
Triển khai một cột dọc Ruby
Deploys an already compiled Java verticle. Classpath root là thư mục hiện tại
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
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]];
45Lệ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à
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ọndependencies { 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ọndependencies { 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ằngdependencies { compile 'io.vertx:vertx-core:4.3.7' }
177 [dấu hai chấm] hoặcdependencies { 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 khaidependencies { 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 khaidependencies { 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ôngdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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àrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
20 [không phân cụm]HttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
184 - Nếu tùy chọndependencies { 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 isdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ểHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
187 - Nếu tùy chọndependencies { 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ẵndependencies { compile 'io.vertx:vertx-core:4.3.7' }
189 - Nếu tùy chọndependencies { 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' }
192dependencies { compile 'io.vertx:vertx-core:4.3.7' }
193 - Nếu tùy chọndependencies { 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ủadependencies { compile 'io.vertx:vertx-core:4.3.7' }
195dependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ếtrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
197 - được sử dụng cùng vớidependencies { compile 'io.vertx:vertx-core:4.3.7' }
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à 0request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
199 - được sử dụng cùng vớidependencies { compile 'io.vertx:vertx-core:4.3.7' }
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__`request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
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'
}
201Dướ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]];
46Chạ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]];
47Chạ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]];
48Chạy 20 phiên bản của công nhân viên ruby
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
49Chạ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]];
50Chạ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]];
51Where
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
202 might contain something likeVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
52The 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]];
53Tù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'
}
192Thự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]];
54Khô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ơnTo deploy your verticle in a fatjar like this you must have a manifest with
208 được đặt thànhdependencies { compile 'io.vertx:vertx-core:4.3.7' }
206dependencies { 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]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
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"];
84Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
55Ghi 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 fatjarsTheo 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]];
56Cá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'
}
216Bạ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ụngVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
57Bạ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]];
58Nế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'
}
220Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
59Sau 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'
}
221Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
60Bạ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]];
61Lệ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
226. id ứng dụng, sử dụng UUID ngẫu nhiên nếu không được đặtdependencies { 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ườngdependencies { compile 'io.vertx:vertx-core:4.3.7' }
228 nếu không được đặtdependencies { 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ốcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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 examplesVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
62Quy 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ạiCá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'
}
249Tù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ìnhTí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
206. In the Program arguments area [in the Arguments tab], writedependencies { 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ưudependencies { compile 'io.vertx:vertx-core:4.3.7' }
IntelliJ - tạo cấu hình Chạy [Ứng dụng], đặt lớp Chính thành
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]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Để 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ầnBạ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]];
63Tù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'
}
247Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
64Tính năng triển khai lại cũng hỗ trợ các cài đặt sau
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âydependencies { 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âydependencies { 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 địnhdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ớpNế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ạnNế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'
}
266ghi 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
phần phụ trợ được biểu thị bằng thuộc tính hệ thống
267 nếu có hoặc,dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Ghi nhật ký JDK khi tệp
268 nằm trong đường dẫn lớp hoặc,dependencies { compile 'io.vertx:vertx-core:4.3.7' }
một chương trình phụ trợ có trong đường dẫn lớp, theo thứ tự ưu tiên sau
SLF4J
Nhật ký4J
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
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ý JDKdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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 loggersử dụng SLF4J khi có sẵn trên đường dẫn lớp với triển khai thực tế [i. e.
274 không phải là phiên bản củadependencies { compile 'io.vertx:vertx-core:4.3.7' }
275]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ý JDKVert. 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 JULkhai 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
278 nếu nó hiển thịdependencies { compile 'io.vertx:vertx-core:4.3.7' }
mặt khác, sử dụng
279 nếu nó hiển thịdependencies { compile 'io.vertx:vertx-core:4.3.7' }
mặt khác, sử dụng
280 nếu nó hiển thịdependencies { compile 'io.vertx:vertx-core:4.3.7' }
nếu không thì dự phòng cho
281dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Ghi chú
The eagle eyes among you might have noticed that Vert. x follows the same order of preferenceViệ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'
}
282Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
65Xử 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'
}
284Má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"];
16Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
68Cổ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'
}
287Ghi 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àychuyể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áchFailover 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]];
69Tì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]];
70Khi 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'
}
296cấ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]];
71Tiệ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]];
72Tí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ệnhVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
5Bâ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]];
74Nế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 đỉnhGhi 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'
}
304Bạ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]];
75Khi 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 HAGhi 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'
}
192nhó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. gVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
76Hã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]];
77Trong 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]];
78Cuố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]];
79Nế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ãoCó 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. gTrong một thiết bị đầu cuối đầu tiên
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
80Tạ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]];
81Tạ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]];
82vâ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]];
83Ghi 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 tradependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
316Vậ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]];
84Bả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
317dependencies { compile 'io.vertx:vertx-core:4.3.7' }
318dependencies { compile 'io.vertx:vertx-core:4.3.7' }
319dependencies { compile 'io.vertx:vertx-core:4.3.7' }
320dependencies { compile 'io.vertx:vertx-core:4.3.7' }
321dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
85Vậ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]];
86MacOS 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
317dependencies { compile 'io.vertx:vertx-core:4.3.7' }
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]];
88hoặc cho http
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
89Cũng như khách hàng
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
90hoặc cho http
Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
91Ghi 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à.
325]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
GNU thích các tùy chọn dài [nghĩa là.
326]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Các thuộc tính giống như Java [tức là.
327]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Các tùy chọn ngắn có giá trị kèm theo [tức là.
328]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Tùy chọn dài với dấu gạch nối đơn [nghĩa là.
329]dependencies { compile 'io.vertx:vertx-core:4.3.7' }
Sử dụng api CLI là một quy trình gồm 3 bước
Định nghĩa giao diện dòng lệnh
Phân tích cú pháp dòng lệnh người dùng
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]];
92Như 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'
}
336Tù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'
}
342Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
93Tù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]];
94Cá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]];
95Mộ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]];
96Cá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[];
69Vertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
97Nế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]];
98dependencies {
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ụngLà 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
349dependencies { compile 'io.vertx:vertx-core:4.3.7' }
bắt buộc sử dụng
350dependencies { compile 'io.vertx:vertx-core:4.3.7' }
có giá trị mặc định bằng cách sử dụng
351dependencies { compile 'io.vertx:vertx-core:4.3.7' }
nhận một số giá trị bằng cách sử dụng
352 - chỉ đối số cuối cùng mới có thể có nhiều giá trịdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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ụngVertx vertx = Vertx.vertx[new VertxOptions[].setWorkerPoolSize[40]];
99Nó 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"];
00Nế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'
}
354Parsing 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"];
01Phươ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'
}
361Giai đ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"];
02Mộ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"];
03Cá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ỉ địnhThay 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'
}
332request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
04Sau đó, 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"];
05Bụ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ố
373, chẳng hạn nhưdependencies { compile 'io.vertx:vertx-core:4.3.7' }
374 hoặcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
38HttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
với phương thức tĩnh
376 hoặcdependencies { compile 'io.vertx:vertx-core:4.3.7' }
377dependencies { compile 'io.vertx:vertx-core:4.3.7' }
với phương thức tĩnh
378, chẳng hạn như kiểu nguyên thủy và kiểu liệt kêdependencies { compile 'io.vertx:vertx-core:4.3.7' }
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àyrequest.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[];
19Nế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ọnSử 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"];
07Sau 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ụngrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
08Bụ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"];
09Bạn cũng cần triển khai
dependencies {
compile 'io.vertx:vertx-core:4.3.7'
}
390request.response[].putHeader["Content-Type", "text/plain"].end["some text"];
10Sau đó, 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áyrequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
11Xâ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 thirequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
12Sử 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ạnBy 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ệnhPhâ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ộngMộ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
402dependencies { compile 'io.vertx:vertx-core:4.3.7' }
lấy đỉnh. x được tạo bởi lệnh "run" hoặc "bare" bằng cách ghi đè
403dependencies { compile 'io.vertx:vertx-core:4.3.7' }
định cấu hình cột dọc và lệnh mặc định với
404 vàdependencies { compile 'io.vertx:vertx-core:4.3.7' }
405dependencies { compile 'io.vertx:vertx-core:4.3.7' }
thêm/xóa lệnh sử dụng
406 vàdependencies { compile 'io.vertx:vertx-core:4.3.7' }
407dependencies { compile 'io.vertx:vertx-core:4.3.7' }
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
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 raHttpServerResponse response = request.response[]; response.putHeader["Content-Type", "text/plain"]; response.write["some text"]; response.end[];
294 cho lỗi mục đích chungdependencies { compile 'io.vertx:vertx-core:4.3.7' }
411 nếu Vert. x không thể được khởi tạodependencies { 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ệnhdependencies { compile 'io.vertx:vertx-core:4.3.7' }
220 vàdependencies { compile 'io.vertx:vertx-core:4.3.7' }
221dependencies { 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ínhdependencies { compile 'io.vertx:vertx-core:4.3.7' }
Đị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ớirequest.response[].putHeader["Content-Type", "text/plain"].end["some text"];
13Important
thư mục phải được ghiKhi 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ạnCuố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