Skip to content

14.2.3 Gửi tin nhắn kiểu fire-and-forget

Hãy tưởng tượng bạn đang ở trên một tàu vũ trụ vừa bị tấn công bởi một tàu địch. Bạn phát cảnh báo “báo động đỏ” toàn tàu để tất cả thành viên vào trạng thái chiến đấu. Bạn không cần phải chờ phản hồi từ hệ thống máy tính của tàu xác nhận trạng thái cảnh báo, cũng không có thời gian để chờ và đọc bất kỳ phản hồi nào trong tình huống như vậy. Bạn kích hoạt cảnh báo rồi chuyển sang xử lý những việc quan trọng hơn.

Đây là một ví dụ về mô hình fire-and-forget (gửi và quên). Mặc dù bạn có thể không quên rằng mình đang ở trạng thái báo động đỏ, nhưng trong hoàn cảnh đó, điều quan trọng hơn là xử lý khủng hoảng chiến đấu thay vì xử lý phản hồi từ việc kích hoạt cảnh báo.

Để mô phỏng tình huống này, chúng ta sẽ tạo một máy chủ RSocket xử lý trạng thái cảnh báo nhưng không trả về bất kỳ điều gì. Trước tiên, chúng ta cần định nghĩa một lớp đại diện cho payload của yêu cầu, chẳng hạn như lớp Alert trong đoạn mã sau.

Listing 14.6 Một lớp mô hình đại diện cho cảnh báo

java
package rsocket;

import java.time.Instant;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Alert {

  private Level level;
  private String orderedBy;
  private Instant orderedAt;

  public static enum Level {
    YELLOW, ORANGE, RED, BLACK
  }
}

Đối tượng Alert ghi lại mức độ cảnh báo, người ra lệnh cảnh báo và dấu thời gian khi cảnh báo được ra lệnh (được định nghĩa dưới dạng Instant). Một lần nữa, chúng ta sử dụng Lombok để tạo constructor và các phương thức truy cập nhằm giữ cho đoạn mã ngắn gọn.

Ở phía máy chủ, AlertController trong đoạn mã sau sẽ xử lý các thông điệp Alert.

Listing 14.7 Một controller RSocket để xử lý các cập nhật cảnh báo

java
package rsocket;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Controller
@Slf4j
public class AlertController {

  @MessageMapping("alert")
  public Mono<Void> setAlert(Mono<Alert> alertMono) {
    return alertMono
        .doOnNext(alert -> {
          log.info(alert.getLevel() + " alert"
          + " ordered by " + alert.getOrderedBy()
          + " at " + alert.getOrderedAt());
        })
        .thenEmpty(Mono.empty());
  }
}

Phương thức setAlert() xử lý các thông điệp Alert trên tuyến "alert". Để đơn giản (dù điều này vô dụng trong một tình huống chiến đấu thực tế), nó chỉ ghi log các cảnh báo. Nhưng điều quan trọng là phương thức này trả về Mono<Void>, nghĩa là không có phản hồi, do đó phương thức handler này hỗ trợ mô hình fire-and-forget.

Ở phía client, đoạn mã không khác nhiều so với mô hình request-response hoặc request-stream như minh họa dưới đây:

java
RSocketRequester tcp = requesterBuilder.tcp("localhost", 7000);
tcp
  .route("alert")
  .data(new Alert(
    Alert.Level.RED, "Craig", Instant.now()))
  .send()
  .subscribe();
log.info("Alert sent");

Tuy nhiên, lưu ý rằng thay vì gọi retrieveMono() hoặc retrieveFlux(), client chỉ đơn giản gọi send() mà không mong đợi phản hồi nào.

Bây giờ, hãy cùng xem cách xử lý mô hình giao tiếp channel, trong đó cả server và client đều gửi nhiều thông điệp cho nhau.

Released under the MIT License.