リアクティブなリアルタイムサービスの構築
Project Reactorの力を活用した、エンドツーエンドのリアクティブなリアルタイムサービスを開発します。
「リアクティブなリアルタイムサービスの構築」はCoddyKit上の無料WebSockets & Real-Time Systems with Springレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはWebSockets & Real-Time Systems with Spring学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 WebSockets & Real-Time Systems with Springコースには全4レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
Reactive Real-Time Services
Welcome! In this lesson, we'll build end-to-end reactive real-time services using Spring WebFlux and Project Reactor.
Reactive services are excellent for handling many concurrent connections efficiently. They offer better scalability and responsiveness compared to traditional blocking approaches.
Project Reactor: Flux & Mono
At the heart of reactive programming in Spring is Project Reactor. It provides two key types for handling data streams:
Flux: Represents a stream of 0 to N items. Think of it as a publisher that can emit multiple values over time.Mono: Represents a stream of 0 to 1 item. Useful for operations that return a single result or no result (likevoid).
These types allow us to compose asynchronous operations in a clear and non-blocking way.
WebFlux WebSocket Handlers
Spring WebFlux uses the WebSocketHandler interface to manage WebSocket connections. Its main method, handle(), takes a WebSocketSession and returns a Mono.
This Mono signifies that the handling process is complete once the reactive stream it represents finishes. We can use Flux inside to send continuous messages.
Designing a Reactive Data Source
To build a real-time service, we need a source of data. Let's create a simple Flux that emits a message periodically. This simulates a real-time data feed, like a stock ticker or a sensor reading.
We'll use Flux.interval() to generate events and map() to transform them into useful messages.
Implementing a Ticker Service
Here's a basic WebSocketHandler that sends a 'tick' message every second. It uses the Flux.interval() we discussed.
The session.send() method takes a Flux to push data to the client.
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketMessage;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
public class TimeTickerHandler implements WebSocketHandler {
@Override
public Mono<Void> handle(WebSocketSession session) {
// Send messages to the client
Flux<WebSocketMessage> output = Flux.interval(Duration.ofSeconds(1))
.map(i -> session.textMessage("Tick #" + i));
// Receive messages from the client (and ignore them for now)
// We use .then() to ensure the Mono<Void> completes only when the session closes.
Mono<Void> input = session.receive().then();
return session.send(output).and(input);
}
}
Full Runnable Ticker Service
To make our TimeTickerHandler runnable, we need a Spring Boot application. This example sets up the WebFlux server and registers our handler.
Access this via ws://localhost:8080/ticker in a WebSocket client (like Postman or a browser's DevTools console) to see it in action.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketMessage;
import org.springframework.web.reactive.socket.WebSocketSession;
import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class ReactiveTickerApplication {
public static void main(String[] args) {
SpringApplication.run(ReactiveTickerApplication.class, args);
}
@Bean
public SimpleUrlHandlerMapping webSocketHandlerMapping(WebSocketHandler webSocketHandler) {
Map<String, WebSocketHandler> map = new HashMap<>();
map.put("/ticker", webSocketHandler);
return new SimpleUrlHandlerMapping(map, 1);
}
@Bean
public WebSocketHandler webSocketHandler() {
return new WebSocketHandler() {
@Override
public Mono<Void> handle(WebSocketSession session) {
// Send a 'tick' message every second
Flux<WebSocketMessage> output = Flux.interval(Duration.ofSeconds(1))
.map(i -> session.textMessage("Tick #" + i + " at " + System.currentTimeMillis()));
// Handle incoming messages (e.g., echo them back, or process commands)
// For this example, we'll just log and then complete the input stream
Mono<Void> input = session.receive()
.doOnNext(msg -> System.out.println("Received: " + msg.getPayloadAsText()))
.then(); // ensures the Mono completes after processing all incoming
return session.send(output).and(input);
}
};
}
@Bean
public WebSocketHandlerAdapter handlerAdapter() {
return new WebSocketHandlerAdapter();
}
}
Handling Client Input
Our previous ticker only sent data. To make it truly interactive, we can also process messages coming from the client.
The session.receive() method returns a Flux that represents incoming messages. You can subscribe to this Flux to react to client input, for example, by filtering, transforming, or using the data to control the output stream.
Error Handling in Reactive Streams
Errors can occur in any part of a reactive pipeline. Project Reactor provides operators to handle these gracefully, preventing your application from crashing:
onErrorResume(): Recovers from an error by switching to an alternative publisher.doOnError(): Performs a side-effect (like logging) when an error occurs, then re-throws it or completes.retry(): Retries the sequence if an error occurs.
Using these helps build robust real-time services that can recover from transient issues.
Backpressure Management
Backpressure is crucial for reactive systems. It's a mechanism where a consumer can signal to a producer that it's receiving data too quickly and needs the producer to slow down.
Project Reactor handles backpressure automatically. When a client can't keep up, the WebSocket connection might buffer messages or eventually close, but the server-side Flux won't overwhelm itself or the network.
Reactive Service Concepts
Which of the following are key characteristics of building reactive real-time services with Spring WebFlux and Project Reactor?
Recap: Reactive Real-Time
We've explored how to build reactive real-time services using Spring WebFlux and Project Reactor.
- We saw how
Fluxcan generate continuous data streams. - We implemented a
WebSocketHandlerto push these streams to clients. - We configured a basic Spring Boot application to host our reactive WebSocket endpoint.
- We touched upon error handling and backpressure, vital for robust systems.
These principles enable highly scalable and responsive real-time applications.
よくある質問
「リアクティブなリアルタイムサービスの構築」レッスンは無料ですか?
はい。「リアクティブなリアルタイムサービスの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、WebSockets & Real-Time Systems with Springコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 WebSockets & Real-Time Systems with Springコースには全4レッスンが含まれています。
「リアクティブなリアルタイムサービスの構築」で何を学びますか?
Project Reactorの力を活用した、エンドツーエンドのリアクティブなリアルタイムサービスを開発します。 ブラウザで直接実行するハンズオンコードでWebSockets & Real-Time Systems with Springを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
WebSockets & Real-Time Systems with Springを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのWebSockets & Real-Time Systems with Springは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「リアクティブなリアルタイムサービスの構築」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このWebSockets & Real-Time Systems with Springレッスンでコードを書いて実行できますか?
はい。すべてのWebSockets & Real-Time Systems with Springレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- リアクティブプログラミング入門
- WebFlux WebSocketハンドラー
- リアクティブなリアルタイムサービスの構築
- リアクティブストリームにおけるバックプレッシャー処理