インスタント メッセージングの実現: ショート ポーリング、ロング ポーリング、SSE、WebSocket の違い
学習内容:
ショート ポーリング: ショート ポーリングは、クライアントとサーバー間の通信方法であり、クライアントはサーバーに定期的にリクエストを送信して、新しいメッセージを確認します。新しいメッセージがない場合、サーバーは空の応答を返します。このアプローチの欠点は、クライアントから送信されるリクエストの頻度が高く、ネットワークの輻輳やサーバーの負荷が高くなる可能性があることです。
ロング ポーリング: ロング ポーリングは、クライアントがリクエストを送信し、サーバーから新しいメッセージが利用可能になるか接続がタイムアウトになるまで接続を開いたままにする、改良されたポーリング方法です。このアプローチでは不要なリクエストが減りますが、依然として大量の HTTP リクエストを送信する必要があります。
SSE: SSE (Server-Sent Events) は、サーバーがクライアントにメッセージをプッシュできる一方向の通信プロトコルです。ポーリングとは異なり、クライアントは 1 つのリクエストを送信するだけでよく、サーバーはいつでも新しいメッセージを送信できます。このアプローチにより、ネットワーク トラフィックとサーバーの負荷が軽減されます。
WebSocket: WebSocket は、接続を開いた状態でサーバーとクライアントがリアルタイムで通信できるようにする双方向通信プロトコルです。WebSocket は、クライアントが新しいメッセージを取得するために大量の HTTP リクエストを送信する必要がないため、ネットワーク トラフィックとサーバーの負荷を軽減できます。
例:
ショート ポーリング: ソーシャル メディア アプリケーションのチャット機能は、ショート ポーリングを使用して新しいメッセージをチェックします。
ロング ポーリング: オンライン ゲームでは、プレーヤーはロング ポーリングを使用して、他のプレーヤーのリアルタイムの位置とアクションを取得します。
SSE: ニュース サイトは SSE を使用して、ユーザーがページを手動で更新することなく、ニュースの見出しや概要をユーザーにプッシュできます。
WebSocket: オンライン会議ソフトウェアは、WebSocket を使用してリアルタイムの音声およびビデオ通信、および会議中のドキュメントと画面の共有を行います。
ショート ポーリングとロング ポーリングは HTTP ベースのポーリング技術で、SSE は一方向の通信プロトコル、WebSocket は双方向の通信プロトコルです。WebSocket は他のテクノロジーと比べてパフォーマンスが高く、遅延が短いため、インスタント メッセージングに最適なテクノロジーとなっています。
WebSocket の使用方法:
1. WebSocket オブジェクトの作成: JavaScript の WebSocket API を使用して、クライアント側で WebSocket オブジェクトを作成できます。たとえば、次のコードを使用して WebSocket オブジェクトを作成し、サーバーに接続できます。
const socket = new WebSocket('ws://localhost:8080/my-websocket');
2. WebSocket イベントの処理: WebSocket オブジェクトには、接続ステータスの処理、データの送受信などに使用できる複数のイベントがあります。たとえば、次のコードを使用して WebSocket オブジェクトの open イベントをリッスンできます。
その一部を以下に示します内联代码片
。
socket.addEventListener('open', (event) => {
console.log('WebSocket 连接已打开');
});
3. データの送受信: WebSocket オブジェクトの send() メソッドを使用してサーバーにデータを送信したり、onmessage イベントを使用してサーバーからデータを受信したりできます。たとえば、次のコードを使用してメッセージを送信し、サーバーからの応答を処理できます。
socket.send('Hello, server!');
socket.addEventListener('message', (event) => {
console.log('服务器返回数据:', event.data);
});
4. WebSocket 接続を閉じます。WebSocket 接続が不要になった場合は、WebSocket オブジェクトの close() メソッドを使用して接続を閉じることができます。たとえば、WebSocket 接続は次のコードを使用して閉じることができます。
socket.close();
WebSocket 接続はサーバー側でもサポートされる必要があることに注意してください。サーバーは WebSocket プロトコルを実装し、クライアントの接続リクエストをリッスンする必要があります。さらに、WebSocket 接続は安全な HTTPS 接続で使用するか、ローカル開発環境で ws:// プロトコルを使用する必要があります。
WebSocketバックエンドスプリングブートの書き方
1.依存関係を追加する
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2. WebSocket 構成クラスを作成する
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myWebSocketHandler(), "/my-websocket")
.setAllowedOrigins("*");
}
@Bean
public WebSocketHandler myWebSocketHandler() {
return new MyWebSocketHandler();
}
}
この例では、WebSocket ハンドラー MyWebSocketHandler を作成し、「/my-websocket」パスの下に登録します。setAllowedOrigins("*") を使用すると、任意のオリジンからのクライアントが WebSocket に接続できるようになります。
3. WebSocket ハンドラーを作成する
public class MyWebSocketHandler implements WebSocketHandler {
private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.add(session);
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
for (WebSocketSession s : sessions) {
if (s.isOpen() && !s.getId().equals(session.getId())) {
s.sendMessage(message);
}
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session);
}
}
このハンドラーは、WebSocket に接続されているすべてのクライアントの WebSocketSessions のリストを維持します。新しいクライアントが WebSocket に接続するたびに、afterConnection確立() メソッドが呼び出され、新しいクライアントの WebSocketSession がリストに追加されます。クライアントがメッセージを送信すると、handleMessage() メソッドが呼び出され、メッセージが他のすべてのクライアントに転送されます。クライアントが切断されると、afterConnectionClosed() メソッドが呼び出され、切断されたクライアントがリストから削除されます。
4.WebSocketをテストする
const socket = new WebSocket("ws://localhost:8080/my-websocket");
socket.onmessage = (event) => {
console.log("收到消息:", event.data);
};
socket.send("Hello, world!");
クライアントがメッセージを送信すると、MyWebSocketHandler の handleMessage() メソッドが呼び出され、メッセージが他のすべてのクライアントに転送されます。