xml
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
id="client-websockets" title="Ktor 客戶端中的 WebSockets">
<show-structure for="chapter" depth="3"/>
<primary-label ref="client-plugin"/>
<tldr>
<p>
<b>所需依賴項</b>:<code>io.ktor:ktor-client-websockets</code>
</p>
<p>
<b>程式碼範例</b>:
<a href="https://github.com/ktorio/ktor-documentation/tree/3.2.3/codeSnippets/snippets/client-websockets">
client-websockets
</a>
</p>
</tldr>
<link-summary>
Websockets 插件允許您在伺服器與客戶端之間建立多向通訊會話。
</link-summary>
WebSocket 是一種協定,它透過單一 TCP 連線在用戶瀏覽器和伺服器之間提供全雙工通訊會話。這對於建立需要與伺服器進行即時資料傳輸的應用程式特別有用。
Ktor 在伺服器端和客戶端都支援 WebSocket 協定。
<p>客戶端的 WebSockets 插件允許您處理 WebSocket 會話,用於與伺服器交換訊息。</p>
<note>
<p>並非所有引擎都支援 WebSockets。有關支援引擎的概述,請參閱
<a href="client-engines.md#limitations">限制</a>。</p>
</note>
<tip>
<p>要了解伺服器端的 WebSocket 支援,請參閱 <Links href="/ktor/server-websockets" summary="The Websockets plugin allows you to create a multi-way communication session between a server and a client.">Ktor 伺服器中的 WebSockets</Links>。</p>
</tip>
<chapter title="新增依賴項" id="add_dependencies">
<p>要使用 <code>WebSockets</code>,您需要在構建腳本中包含 <code>ktor-client-websockets</code> 構件:</p>
<tabs group="languages">
<tab title="Gradle (Kotlin)" group-key="kotlin">
<code-block lang="Kotlin" code=" implementation("io.ktor:ktor-client-websockets:$ktor_version")"/>
</tab>
<tab title="Gradle (Groovy)" group-key="groovy">
<code-block lang="Groovy" code=" implementation "io.ktor:ktor-client-websockets:$ktor_version""/>
</tab>
<tab title="Maven" group-key="maven">
<code-block lang="XML" code=" <dependency> <groupId>io.ktor</groupId> <artifactId>ktor-client-websockets-jvm</artifactId> <version>${ktor_version}</version> </dependency>"/>
</tab>
</tabs>
<p>
您可以從 <Links href="/ktor/client-dependencies" summary="Learn how to add client dependencies to an existing project.">新增客戶端依賴項</Links> 了解更多關於 Ktor 客戶端所需的構件。
</p>
</chapter>
<chapter title="安裝 WebSockets" id="install_plugin">
<p>要安裝 <code>WebSockets</code> 插件,請將其傳遞給 <a href="#configure-client">客戶端配置塊</a> 內的 <code>install</code> 函數:</p>
<code-block lang="kotlin" code=" import io.ktor.client.* import io.ktor.client.engine.cio.* import io.ktor.client.plugins.websocket.* //... val client = HttpClient(CIO) { install(WebSockets) }"/>
</chapter>
<chapter title="配置" id="configure_plugin">
<p>您可以選擇在 <code>install</code> 塊中透過傳遞 <code>WebSockets.Config</code>
支援的屬性來配置插件。
</p>
<deflist>
<def id="maxFrameSize">
<title><code>maxFrameSize</code></title>
設定可以接收或傳送的最大 <code>Frame</code> 大小。
</def>
<def id="contentConverter">
<title><code>contentConverter</code></title>
設定用於序列化/反序列化的轉換器。
</def>
<def id="pingIntervalMillis">
<title><code>pingIntervalMillis</code></title>
以 <code>Long</code> 格式指定 ping 之間的持續時間。
</def>
<def id="pingInterval">
<title><code>pingInterval</code></title>
以 <code>Duration</code> 格式指定 ping 之間的持續時間。
</def>
</deflist>
<warning>
<p><code>pingInterval</code> 和 <code>pingIntervalMillis</code> 屬性不適用於
OkHttp 引擎。要為 OkHttp 設定 ping 間隔,您可以使用
<a href="#okhttp">引擎配置</a>:
</p>
<code-block lang="kotlin" code=" import io.ktor.client.engine.okhttp.OkHttp val client = HttpClient(OkHttp) { engine { preconfigured = OkHttpClient.Builder() .pingInterval(20, TimeUnit.SECONDS) .build() } }"/>
</warning>
<p>
在以下範例中,WebSockets 插件配置了 20 秒 (<code>20_000</code> 毫秒) 的 ping 間隔,以自動傳送 ping 幀並保持 WebSocket 連線活躍:
</p>
<code-block lang="kotlin" code=" val client = HttpClient(CIO) { install(WebSockets) { pingIntervalMillis = 20_000 } }"/>
</chapter>
<chapter title="使用 WebSocket 會話" id="working-wtih-session">
<p>客戶端的 WebSocket 會話由
<code>DefaultClientWebSocketSession</code>
介面表示。此介面公開了允許您傳送和接收 WebSocket 幀以及關閉會話的 API。
</p>
<chapter title="存取 WebSocket 會話" id="access-session">
<p>
<code>HttpClient</code> 提供了兩種主要方式來存取 WebSocket 會話:
</p>
<list>
<li>
<p><code>webSocket()</code> 函數接受 <code>DefaultClientWebSocketSession</code> 作為塊參數。</p>
<code-block lang="kotlin" code=" runBlocking { client.webSocket( method = HttpMethod.Get, host = "127.0.0.1", port = 8080, path = "/echo" ) { // this: DefaultClientWebSocketSession } }"/>
</li>
<li>
<code>webSocketSession()</code>
函數返回 <code>DefaultClientWebSocketSession</code> 實例,並允許您在 <code>runBlocking</code> 或 <code>launch</code> 作用域之外存取會話。
</li>
</list>
</chapter>
<chapter title="處理 WebSocket 會話" id="handle-session">
<p>在函數塊內,您為指定的路徑定義處理程式。以下函數和屬性在此塊中可用:</p>
<deflist>
<def id="send">
<title><code>send()</code></title>
使用 <code>send()</code> 函數向伺服器傳送文本內容。
</def>
<def id="outgoing">
<title><code>outgoing</code></title>
使用 <code>outgoing</code> 屬性存取用於傳送 WebSocket 幀的通道。幀由 <code>Frame</code> 類別表示。
</def>
<def id="incoming">
<title><code>incoming</code></title>
使用 <code>incoming</code> 屬性存取用於接收 WebSocket 幀的通道。幀由 <code>Frame</code> 類別表示。
</def>
<def id="close">
<title><code>close()</code></title>
使用 <code>close()</code> 函數傳送帶有指定原因的關閉幀。
</def>
</deflist>
</chapter>
<chapter title="幀類型" id="frame-types">
<p>
您可以檢查 WebSocket 幀的類型並據此處理。一些常見的幀類型包括:
</p>
<list>
<li><code>Frame.Text</code> 表示一個文本幀。使用
<code>Frame.Text.readText()</code> 讀取其內容。
</li>
<li><code>Frame.Binary</code> 表示一個二進制幀。使用 <code>Frame.Binary.readBytes()</code>
讀取其內容。
</li>
<li><code>Frame.Close</code> 表示一個關閉幀。使用 <code>Frame.Close.readReason()</code>
獲取會話關閉的原因。
</li>
</list>
</chapter>
<chapter title="範例" id="example">
<p>以下範例創建了 <code>echo</code> WebSocket 端點,並展示了如何向伺服器傳送和從伺服器接收訊息。</p>
<code-block lang="kotlin"
include-symbol="main" code="package com.example import io.ktor.client.* import io.ktor.client.engine.cio.* import io.ktor.client.plugins.websocket.* import io.ktor.http.* import io.ktor.websocket.* import kotlinx.coroutines.* import java.util.* fun main() { val client = HttpClient(CIO) { install(WebSockets) { pingIntervalMillis = 20_000 } } runBlocking { client.webSocket(method = HttpMethod.Get, host = "127.0.0.1", port = 8080, path = "/echo") { while(true) { val othersMessage = incoming.receive() as? Frame.Text println(othersMessage?.readText()) val myMessage = Scanner(System.`in`).next() if(myMessage != null) { send(myMessage) } } } } client.close() }"/>
<p>有關完整範例,
請參閱
<a href="https://github.com/ktorio/ktor-documentation/tree/3.2.3/codeSnippets/snippets/client-websockets">client-websockets</a>。
</p>
</chapter>
</chapter>
</topic>