如何使用 StreamWebSocket 進行連線 (HTML)
[ 本文的目標對象是撰寫 Windows 執行階段 App 的 Windows 8.x 和 Windows Phone 8.x 開發人員。如果您正在開發適用於 Windows 10 的 App,請參閱 最新文件 ]
本主題說明 如何在 Windows 執行階段應用程式使用 StreamWebSocket 傳送和接收資料的資料流。
StreamWebSocket 類別提供一個以訊息為基礎的 WebSocket 通訊協定資料流抽象概念。當需要在用戶端和伺服器之間傳輸大型檔案 (例如相片或電影) 時,這會很有用。伺服器必須支援 WebSocket 通訊協定。使用 StreamWebSocket 可讓每個讀取操作分別讀取訊息的各個區段,而不需要以單一操作讀取整個訊息 (如同使用 MessageWebSocket)。
StreamWebSocket 類別只支援二進位訊息。UTF-8 訊息必須使用 MessageWebSocket。
先決條件
下列範例使用 JavaScript,並且使用 WebSocket 範例做為依據。 如需使用 JavaScript 建立 Windows 執行階段應用程式的一般協助,請參閱使用 JavaScript 建立您的第一個 Windows 執行階段應用程式。另外,這個主題中使用 JavaScript Promise 來完成非同步操作。如需這種程式設計模式的詳細資訊,請參閱使用 Promise 在 JavaScript 的非同步程式設計。
若要確保 Windows 執行階段應用程式的網路可正常運作,您必須在專案 Package.appxmanifest 檔案中設定所需的任何網路功能。 如果應用程式需要以用戶端的形式連線到網際網路上的遠端服務,則需要 [網際網路 (用戶端)] 功能。如果應用程式需要以用戶端的形式連線到家用網路或工作場所網路的遠端服務,則需要 [家中\公司網路]**** 功能。
注意 在 Windows Phone,只有一個網路功能 ([網際網路 (用戶端與伺服器)]) 能啟用應用程式的所有網路存取功能。
如需詳細資訊,請參閱如何設定網路功能。
指示
1. 建立 StreamWebSocket 物件傳送和接收資料
本節中的程式碼會建立新的 StreamWebSocket、連線到 WebSocket 伺服器、傳送資料到伺服器以及接聽回應。
我們先驗證要使用的伺服器 URI 是否有效。接著,使用該 URI 連線到 WebSocket 伺服器,並等候接收來自伺服器的回應。
系統會先檢查輸入 URI 位址,以確定使用者傳送的是有效的 URI 位址。如果應用程式已經知道 WebSocket 伺服器的 URI,就不需要此步驟。
如果傳送到 Windows.Foundation.Uri 物件建構函式的統一資源識別元 (URI) 字串無效時,即會擲回例外狀況。
在 JavaScript 中,並未提供任何方法來嘗試和剖析 URI 的字串。若要在這個情況下擷取此例外狀況,可在建構 URI 的程式碼前後使用 try/catch 區塊。
此範例也會檢查 URI 中的 HTTP 配置為 WS 或 WSS,因為 StreamWebSocket 只支援這些配置。
如果我們有來自使用者輸入的有效 URI,應用程式就可以連線到 WebSocket 伺服器,也可以傳送和接收資料。
網路錯誤 (例如,連線中斷、連線失敗、HTTP 伺服器故障) 的例外狀況可能隨時發生。這些錯誤會造成擲出例外狀況。如果您的應用程式不處理例外狀況,它可能會造成您整個應用程式被執行階段終止。 您必須編寫程式碼,在呼叫大多數非同步網路方法時處理例外狀況。有時候,在例外狀況發生時,會重試網路方法,試圖解決問題。其他時候,您的應用程式需要規劃,在沒有網路連線的情況下,使用之前快取的資料繼續工作。如需處理網路例外狀況的詳細資訊,請參閱處理網路應用程式中的例外狀況。
注意 您可能想要對使用者顯示訊息,或將已發生的特定事件寫入記錄 (例如,已連線或發生錯誤時)。此範例會呼叫 displayStatus 函式,您需要此函式為應用程式進行實作。
注意 執行寫入和讀取作業的 writeOutgoing()
與 readIncoming
() 函式將在後續步驟中定義。
開啟 js 資料夾。開啟您要使用的 .js 檔案,然後新增下列程式碼。
// Define some variables we will use var streamWebSocket; var dataWriter; var dataReader; // The data to send var data = "Hello World"; var countOfDataSent; var countOfDataReceived; function start() { if (streamWebSocket) { // The WebSocket is already running. Go ahead and immediately return, // or display a message that indicates that it is running. return; } var webSocket = new Windows.Networking.Sockets.StreamWebSocket(); webSocket.onclosed = onClosed; // WebSocket server to test connections // If the scheme is wss:, then the server will // echo back what it receives var uriString = "wss://echo.websocket.org"; // We might get the uriString from the user so // we need to check that we have a valid URI var serverUri; try { serverUri = new Windows.Foundation.Uri(uriString); } catch (Exception) { displayStatus("Invalid URI, please re-enter a valid URI."); return; } if (serverUri.schemeName != "ws" && serverUri.schemeName != "wss") { displayStatus("Only 'ws' and 'wss' schemes supported. Please re-enter URI"); return; } // Asynchronous networking methods can throw execptions webSocket.connectAsync(uri).done(function () { diaplayStatus("Connected"); streamWebSocket = webSocket; dataWriter = new Windows.Storage.Streams.DataWriter(webSocket.outputStream); dataReader = new Windows.Storage.Streams.DataReader(webSocket.inputStream); // When buffering, return as soon as any data is available. dataReader.inputStreamOptions = Windows.Storage.Streams.InputStreamOptions.partial; countOfDataSent = 0; countOfDataReceived = 0; // Continuously send data to the server writeOutgoing(); // Continuously listen for a response readIncoming(); }, function (error) { var errorStatus = Windows.Networking.Sockets.WebSocketError.getStatus(error.number); if (errorStatus === Windows.Web.WebErrorStatus.cannotConnect || errorStatus === Windows.Web.WebErrorStatus.notFound || errorStatus === Windows.Web.WebErrorStatus.requestTimeout) { displayStatus("Cannot connect to the server"); } else { displayStatus("Failed to connect: " + getError(error)); } }); }
2. 傳送連出資料
本節中的程式碼可讓 WebSocket 物件傳送資料到伺服器。
注意 writeError()
函式將在後續步驟中定義。
將下列程式碼新增至 .js 檔案中以定義
writeOutgoing()
函式。function writeOutgoing() { try { var size = dataWriter.measureString(data); countOfDataSent += size; dataWriter.writeString(data); dataWriter.storeAsync().done(function () { // Add a 1 second delay so the user can see what's going on. setTimeout(writeOutgoing, 1000); }, writeError); } catch (error) { displayStatus("Sync write error: " + getError(error)); } }
3. 讀取連入資料
本節中的程式碼可讓 WebSocket 物件從伺服器讀取資料。
注意 readError()
函式將在後續步驟中定義。
將下列程式碼新增至 .js 檔案中以定義
readIncoming()
函式。function readIncoming(args) { // Buffer as much data as you require for your protocol. dataReader.loadAsync(100).done(function (sizeBytesRead) { countOfDataReceived += sizeBytesRead; var incomingBytes = new Array(sizeBytesRead); dataReader.readBytes(incomingBytes); // Do something with the data. // Alternatively you can use DataReader to read out individual booleans, // ints, strings, etc. // Start another read. readIncoming(); }, readError); }
4. 新增錯誤處理程式碼
您必須編寫程式碼,在呼叫大多數非同步網路方法時處理例外狀況。您的例外狀況處理常式可以抓取例外狀況發生原因的更詳細資訊,更清楚地了解失敗的情況並作出適當的決定。如需詳細資訊,請參閱如何處理網路應用程式中的例外狀況。
將程式碼新增至 .js 檔案,以定義可分別記錄寫入和讀取錯誤 (或是採取其他動作) 的
writeError()
和readError()
函式。您使用的特定實作可能會有所不同。function writeError(error) { // Add your code to handle write errors. } function readError(error) { // Add your code to handle read errors. }
5. 登錄 StreamWebSocket.Closed 事件的回呼
發生 StreamWebSocket.Closed 事件時,會呼叫登錄回呼並從 WebSocketClosedEventArgs 接收資料以關閉連線。
將下列程式碼新增至 .js 檔案。
function onClosed(args) { // You can add code to log or display the code and reason // for the closure (stored in args.code and args.reason) if (streamWebSocket) { streamWebSocket.close(); } streamWebSocket = null; }
摘要與後續步驟
在這個教學課程中,我們檢閱如何連線到 WebSocket 伺服器,以及如何使用 StreamWebSocket 傳送和接收資料。
如需示範如何使用 WebSocket 傳送和接收資料的完整範例,請參閱 WebSocket 範例。
相關主題
其他
使用 Promise 在 JavaScript 的非同步程式設計
使用 JavaScript 建立您的第一個 Windows 執行階段應用程式
參考
範例