教學課程:使用子通訊協定在 WebSocket 用戶端之間發佈和訂閱訊息
在建置聊天應用程式教學課程中,您已了解如何使用 WebSocket API 搭配 Azure Web PubSub 傳送和接收資料。 您可以看到,用戶端與服務通訊時不需要通訊協定。 例如,您可以使用 WebSocket.send()
傳送任何類型的資料,然後伺服器會按照原狀接收資料。 WebSocket API 流程易於使用,但功能有限。 例如,您無法在將事件傳送至伺服器時指定事件名稱,或將訊息發佈至其他用戶端,而不是將它傳送至您的伺服器。 在本教學課程中,您會了解如何使用子通訊協定來擴充用戶端的功能。
在本教學課程中,您會了解如何:
- 建立 Web PubSub 服務執行個體
- 產生建立 WebSocket 連線的完整 URL
- 使用子通訊協定在 WebSocket 用戶端之間發佈訊息
如果您沒有 Azure 訂閱,請在開始之前,先建立 Azure 免費帳戶。
必要條件
- 此設定需要 2.22.0 版或更新版本的 Azure CLI。 如果您是使用 Azure Cloud Shell,就已安裝最新版本。
重要
原始 連接字串 只會針對示範目的出現在本文中。
連接字串包含應用程式存取 Azure Web PubSub 服務所需的授權資訊。 連接字串內的存取金鑰類似於服務的根密碼。 在生產環境中,請一律保護您的存取金鑰。 使用 Azure 金鑰保存庫,安全地管理和輪替密鑰,並使用保護連線WebPubSubServiceClient
。
避免將存取金鑰散發給其他使用者、寫入程式碼,或將其以純文字儲存在他人可以存取的位置。 如果您認為金鑰可能已遭盜用,請輪替金鑰。
建立 Azure Web PubSub 執行個體
建立資源群組
資源群組是在其中部署與管理 Azure 資源的邏輯容器。 使用 az group create 命令,在 eastus
位置中建立名為 myResourceGroup
的資源群組。
az group create --name myResourceGroup --location EastUS
建立 Web PubSub 執行個體
執行 az extension add 以安裝 webpubsub 延伸模組,或將該延伸模組升級至目前版本。
az extension add --upgrade --name webpubsub
使用 Azure CLI az webpubsub create 命令,在您已建立的資源群組中建立 Web PubSub。 下列命令會在 EastUS 的資源群組 myResourceGroup 下建立免費 Web PubSub 資源:
重要
每個 Web PubSub 資源都必須有唯一的名稱。 使用下列範例中的 Web PubSub 名稱取代 <your-unique-resource-name>。
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
此命令的輸出顯示新建資源的屬性。 請記下下列兩個屬性:
- 資源名稱:您提供給上述
--name
參數的名稱。
- hostName:在此範例中,主機名稱為
<your-unique-resource-name>.webpubsub.azure.com/
。
此時,您的 Azure 帳戶是唯一獲得授權在此新資源上執行任何作業的帳戶。
取得 ConnectionString 以供後續使用
原始 連接字串 只針對示範目的出現在本文中。 在生產環境中,請一律保護您的存取金鑰。 使用 Azure 金鑰保存庫,安全地管理和輪替密鑰,並使用保護連線WebPubSubServiceClient
。
使用 Azure CLI az webpubsub key 命令取得服務的 ConnectionString。 使用您的 Azure Web PubSub 執行個體名稱取代 <your-unique-resource-name>
預留位置。
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
複製連接字串以供後續使用。
複製擷取的 ConnectionString,以稍後在本教學課程中用來做為 <connection_string>
的值。
設定專案
必要條件
使用子通訊協定
用戶端可以使用特定的子通訊協定來啟動 WebSocket 連線。 Azure Web PubSub 服務支援名為 json.webpubsub.azure.v1
的子通訊協定,可讓用戶端直接透過 Web PubSub 服務發佈/訂閱,而不是往返上游伺服器。 如需有關子通訊協定的詳細資訊,請參閱 Azure Web PubSub 支援的 JSON WebSocket 子通訊協定 (部分機器翻譯)。
如果您使用其他通訊協定名稱,服務會忽略它們並在連線事件處理常式中傳遞至伺服器,讓您可以建置自己的通訊協定。
現在,讓我們使用 json.webpubsub.azure.v1
子通訊協定建立 Web 應用程式。
安裝相依性
mkdir logstream
cd logstream
dotnet new web
dotnet add package Microsoft.Extensions.Azure
dotnet add package Azure.Messaging.WebPubSub
mkdir logstream
cd logstream
npm init -y
npm install --save express
npm install --save ws
npm install --save node-fetch
npm install --save @azure/web-pubsub
mkdir logstream
cd logstream
# Create venv
python -m venv env
# Active venv
source ./env/bin/activate
pip install azure-messaging-webpubsubservice
您會使用 Javalin Web 架構來裝載網頁。
首先,讓我們使用 Maven 建立新的應用程式 logstream-webserver
,並切換至 logstream-webserver 資料夾:
mvn archetype:generate --define interactiveMode=n --define groupId=com.webpubsub.tutorial --define artifactId=logstream-webserver --define archetypeArtifactId=maven-archetype-quickstart --define archetypeVersion=1.4
cd logstream-webserver
讓我們將 Azure Web PubSub SDK 和 javalin
Web 架構相依性新增至 pom.xml
的 dependencies
節點:
javalin
:適用於 JAVA 的簡單 Web 架構
slf4j-simple
:適用於 JAVA 的記錄器
azure-messaging-webpubsub
:使用 Azure Web PubSub 的服務用戶端 SDK
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-messaging-webpubsub</artifactId>
<version>1.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.javalin/javalin -->
<dependency>
<groupId>io.javalin</groupId>
<artifactId>javalin</artifactId>
<version>3.13.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
建立伺服器端來裝載 /negotiate
API 和網頁。
使用下列程式碼更新 Program.cs
。
- 使用
AddAzureClients
新增服務用戶端,並從設定中讀取連接字串。
- 在
app.Run();
前面加上 app.UseStaticFiles();
以支援靜態檔案。
- 然後更新
app.MapGet
,以產生具有 /negotiate
要求的用戶端存取權杖。
using Azure.Messaging.WebPubSub;
using Microsoft.Extensions.Azure;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAzureClients(s =>
{
s.AddWebPubSubServiceClient(builder.Configuration["Azure:WebPubSub:ConnectionString"], "stream");
});
var app = builder.Build();
app.UseStaticFiles();
app.MapGet("/negotiate", async context =>
{
var service = context.RequestServices.GetRequiredService<WebPubSubServiceClient>();
var response = new
{
url = service.GetClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" }).AbsoluteUri
};
await context.Response.WriteAsJsonAsync(response);
});
app.Run();
建立 server.js
並新增下列程式碼:
const express = require('express');
const { WebPubSubServiceClient } = require('@azure/web-pubsub');
let service = new WebPubSubServiceClient(process.env.WebPubSubConnectionString, 'stream');
const app = express();
app.get('/negotiate', async (req, res) => {
let token = await service.getClientAccessToken({
roles: ['webpubsub.sendToGroup.stream', 'webpubsub.joinLeaveGroup.stream']
});
res.send({
url: token.url
});
});
app.use(express.static('public'));
app.listen(8080, () => console.log('server started'));
建立 server.py
來裝載 /negotiate
API 和網頁。
import json
import sys
from http.server import HTTPServer, SimpleHTTPRequestHandler
from azure.messaging.webpubsubservice import WebPubSubServiceClient
service = WebPubSubServiceClient.from_connection_string(sys.argv[1], hub='stream')
class Request(SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.path = 'public/index.html'
return SimpleHTTPRequestHandler.do_GET(self)
elif self.path == '/negotiate':
roles = ['webpubsub.sendToGroup.stream',
'webpubsub.joinLeaveGroup.stream']
token = service.get_client_access_token(roles=roles)
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({
'url': token['url']
}).encode())
if __name__ == '__main__':
if len(sys.argv) != 2:
print('Usage: python server.py <connection-string>')
exit(1)
server = HTTPServer(('localhost', 8080), Request)
print('server started')
server.serve_forever()
讓我們瀏覽至 /src/main/java/com/webpubsub/tutorial 目錄、在您的編輯器中開啟 App.java 檔案,使用 Javalin.create
提供靜態檔案:
package com.webpubsub.tutorial;
import com.azure.messaging.webpubsub.WebPubSubServiceClient;
import com.azure.messaging.webpubsub.WebPubSubServiceClientBuilder;
import com.azure.messaging.webpubsub.models.GetClientAccessTokenOptions;
import com.azure.messaging.webpubsub.models.WebPubSubClientAccessToken;
import io.javalin.Javalin;
public class App {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Expecting 1 arguments: <connection-string>");
return;
}
// create the service client
WebPubSubServiceClient service = new WebPubSubServiceClientBuilder()
.connectionString(args[0])
.hub("chat")
.buildClient();
// start a server
Javalin app = Javalin.create(config -> {
config.addStaticFiles("public");
}).start(8080);
// Handle the negotiate request and return the token to the client
app.get("/negotiate", ctx -> {
GetClientAccessTokenOptions option = new GetClientAccessTokenOptions();
option.addRole("webpubsub.sendToGroup.stream");
option.addRole("webpubsub.joinLeaveGroup.stream");
WebPubSubClientAccessToken token = service.getClientAccessToken(option);
// return JSON string
ctx.result("{\"url\":\"" + token.getUrl() + "\"}");
return;
});
}
}
視您的設定而定,您可能需要在 pom.xml 中明確將程式設計語言層級設定為 JAVA 8。 新增下列程式碼片段:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
建立網頁
使用下列內容建立 HTML 頁面,並將其儲存為 wwwroot/index.html
:
使用下列內容建立 HTML 頁面,並將其儲存為 public/index.html
:
使用下列內容建立 HTML 頁面,並將其儲存為 public/index.html
:
使用下列內容建立 HTML 頁面,並將其儲存至 /src/main/resources/public/index.html:
<html>
<body>
<div id="output"></div>
<script>
(async function () {
let res = await fetch('/negotiate')
let data = await res.json();
let ws = new WebSocket(data.url, 'json.webpubsub.azure.v1');
ws.onopen = () => {
console.log('connected');
};
let output = document.querySelector('#output');
ws.onmessage = event => {
let d = document.createElement('p');
d.innerText = event.data;
output.appendChild(d);
};
})();
</script>
</body>
</html>
上述程式碼會連線至服務,並將收到的任何訊息列印至頁面。 主要的變更是我們在建立 WebSocket 連線時指定子通訊協定。
執行伺服器
我們使用適用於 .NET Core 的 Secret Manager 工具來設定連接字串。 執行下列命令,使用在前一個步驟中擷取的命令取代 <connection_string>
,並在瀏覽器中開啟 http://localhost:5000/index.html:
dotnet user-secrets init
dotnet user-secrets set Azure:WebPubSub:ConnectionString "<connection-string>"
dotnet run
現在執行下列命令,使用在前一個步驟中擷取的 ConnectionString 取代 <connection-string>
,並在瀏覽器中開啟 http://localhost:8080:
export WebPubSubConnectionString="<connection-string>"
node server
現在執行下列命令,使用在前一個步驟中擷取的 ConnectionString 取代 <connection-string>
,並在瀏覽器中開啟 http://localhost:8080:
python server.py "<connection-string>"
現在執行下列命令,使用在前一個步驟中擷取的 ConnectionString 取代 <connection-string>
,並在瀏覽器中開啟 http://localhost:8080:
mvn compile & mvn package & mvn exec:java -Dexec.mainClass="com.webpubsub.tutorial.App" -Dexec.cleanupDaemonThreads=false -Dexec.args="'<connection_string>'"
如果您使用 Chrome,您可以按 F12 或以滑鼠右鍵按一下 -> [檢查] -> [開發人員工具],然後選取 [網路] 索引標籤。載入網頁,您可以看到 WebSocket 連線已建立。 選取以檢查 WebSocket 連線,您可以看到用戶端中已收到下列 connected
事件訊息。 您可以看到您可以取得針對此用戶端產生的 connectionId
。
{"type":"system","event":"connected","userId":null,"connectionId":"<the_connection_id>"}
您可以看到,透過在子通訊協定的協助,您可以在連線為 connected
時取得連線的一些中繼資料。
用戶端現在會收到 JSON 訊息,而不是純文字。 JSON 訊息包含更多詳細資訊,例如訊息的類型和來源。 因此,您可以使用此資訊對訊息進行更多處理 (例如,如果訊息來自不同的來源,則以不同的樣式顯示訊息),您可以在後面的區段中找到。
從用戶端發佈訊息
在建置聊天應用程式教學課程中,當用戶端透過 WebSocket 連線傳送訊息至 Web PubSub 服務時,服務會在伺服器端觸發使用者事件。 使用子通訊協定時,用戶端會藉由傳送 JSON 訊息擁有更多功能。 例如,您可以透過 Web PubSub 服務直接從用戶端將訊息發佈至其他用戶端。
如果您想要將大量資料即時串流至其他用戶端,這會很有用。 讓我們使用此功能建置記錄串流應用程式,將主控台記錄即時串流至瀏覽器。
建立串流程式
建立 stream
程式:
mkdir stream
cd stream
dotnet new console
使用下列內容更新 Program.cs
:
using System;
using System.Net.Http;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace stream
{
class Program
{
private static readonly HttpClient http = new HttpClient();
static async Task Main(string[] args)
{
// Get client url from remote
var stream = await http.GetStreamAsync("http://localhost:5000/negotiate");
var url = (await JsonSerializer.DeserializeAsync<ClientToken>(stream)).url;
var client = new ClientWebSocket();
client.Options.AddSubProtocol("json.webpubsub.azure.v1");
await client.ConnectAsync(new Uri(url), default);
Console.WriteLine("Connected.");
var streaming = Console.ReadLine();
while (streaming != null)
{
if (!string.IsNullOrEmpty(streaming))
{
var message = JsonSerializer.Serialize(new
{
type = "sendToGroup",
group = "stream",
data = streaming + Environment.NewLine,
});
Console.WriteLine("Sending " + message);
await client.SendAsync(Encoding.UTF8.GetBytes(message), WebSocketMessageType.Text, true, default);
}
streaming = Console.ReadLine();
}
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default);
}
private sealed class ClientToken
{
public string url { get; set; }
}
}
}
使用下列內容建立 stream.js
。
const WebSocket = require('ws');
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
async function main() {
let res = await fetch(`http://localhost:8080/negotiate`);
let data = await res.json();
let ws = new WebSocket(data.url, 'json.webpubsub.azure.v1');
let ackId = 0;
ws.on('open', () => {
process.stdin.on('data', data => {
ws.send(JSON.stringify({
type: 'sendToGroup',
group: 'stream',
ackId: ++ackId,
dataType: 'text',
data: data.toString()
}));
});
});
ws.on('message', data => console.log("Received: %s", data));
process.stdin.on('close', () => ws.close());
}
main();
上述程式碼會建立與服務的 WebSocket 連線,然後每當它收到某些資料時,就會使用 ws.send()
來發佈資料。 如果要發佈給其他人,您只需將 type
設定為 sendToGroup
並在訊息中指定群組名稱。
開啟 stream
程式的另一個 bash 視窗,並安裝 websockets
相依性:
mkdir stream
cd stream
# Create venv
python -m venv env
# Active venv
source ./env/bin/activate
pip install websockets
使用下列內容建立 stream.py
。
import asyncio
import sys
import threading
import time
import websockets
import requests
import json
async def connect(url):
async with websockets.connect(url, subprotocols=['json.webpubsub.azure.v1']) as ws:
print('connected')
id = 1
while True:
data = input()
payload = {
'type': 'sendToGroup',
'group': 'stream',
'dataType': 'text',
'data': str(data + '\n'),
'ackId': id
}
id = id + 1
await ws.send(json.dumps(payload))
await ws.recv()
if __name__ == '__main__':
res = requests.get('http://localhost:8080/negotiate').json()
try:
asyncio.get_event_loop().run_until_complete(connect(res['url']))
except KeyboardInterrupt:
pass
上述程式碼會建立與服務的 WebSocket 連線,然後每當它收到某些資料時,就會使用 ws.send()
來發佈資料。 如果要發佈給其他人,您只需將 type
設定為 sendToGroup
並在訊息中指定群組名稱。
讓我們使用另一個終端機,回到根資料夾來建立串流主控台應用程式 logstream-streaming
,並切換至 logstream-streaming 資料夾:
mvn archetype:generate --define interactiveMode=n --define groupId=com.webpubsub.quickstart --define artifactId=logstream-streaming --define archetypeArtifactId=maven-archetype-quickstart --define archetypeVersion=1.4
cd logstream-streaming
讓我們將 HttpClient 相依性新增至 pom.xml
的 dependencies
節點:
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
現在讓我們使用 WebSocket 來連線到服務。 讓我們瀏覽至 /src/main/java/com/webpubsub/quickstart 目錄、在編輯器中開啟 App.java 檔案,並將程式碼取代為:
package com.webpubsub.quickstart;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.WebSocket;
import java.util.concurrent.CompletionStage;
import com.google.gson.Gson;
public class App
{
public static void main( String[] args ) throws IOException, InterruptedException
{
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/negotiate"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
Gson gson = new Gson();
String url = gson.fromJson(response.body(), Entity.class).url;
WebSocket ws = HttpClient.newHttpClient().newWebSocketBuilder().subprotocols("json.webpubsub.azure.v1")
.buildAsync(URI.create(url), new WebSocketClient()).join();
int id = 0;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String streaming = reader.readLine();
App app = new App();
while (streaming != null && !streaming.isEmpty()){
String frame = gson.toJson(app.new GroupMessage(streaming + "\n", ++id));
System.out.println("Sending: " + frame);
ws.sendText(frame, true);
streaming = reader.readLine();
}
}
private class GroupMessage{
public String data;
public int ackId;
public final String type = "sendToGroup";
public final String group = "stream";
GroupMessage(String data, int ackId){
this.data = data;
this.ackId = ackId;
}
}
private static final class WebSocketClient implements WebSocket.Listener {
private WebSocketClient() {
}
@Override
public void onOpen(WebSocket webSocket) {
System.out.println("onOpen using subprotocol " + webSocket.getSubprotocol());
WebSocket.Listener.super.onOpen(webSocket);
}
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
System.out.println("onText received " + data);
return WebSocket.Listener.super.onText(webSocket, data, last);
}
@Override
public void onError(WebSocket webSocket, Throwable error) {
System.out.println("Bad day! " + webSocket.toString());
WebSocket.Listener.super.onError(webSocket, error);
}
}
private static final class Entity {
public String url;
}
}
- 瀏覽至包含 pom.xml 檔案的目錄,然後使用下列命令執行專案
mvn compile & mvn package & mvn exec:java -Dexec.mainClass="com.webpubsub.quickstart.App" -Dexec.cleanupDaemonThreads=false
您可以看到,這裡有個新的概念「群組」。 群組是中樞中的邏輯概念,您可以在其中將訊息發佈至連線群組。 在中樞中,您可以有多個群組,而一個用戶端可以同時訂閱多個群組。 使用子通訊協定時,您只能發佈至群組,而不是廣播至整個中樞。 如需有關字詞的詳細資訊,請參閱基本概念。
因為我們在這裡使用群組,所以在 ws.onopen
回呼內建立 WebSocket 連線時,我們也需要更新網頁 index.html
以加入群組。
let ackId = 0;
ws.onopen = () => {
console.log('connected');
ws.send(JSON.stringify({
type: 'joinGroup',
group: 'stream',
ackId: ++ackId
}));
};
您可以看到,用戶端透過傳送 joinGroup
類型的訊息來加入群組。
此外,請稍微更新 ws.onmessage
回呼邏輯,以剖析 JSON 回應,並僅列印來自 stream
群組的訊息,使其做為即時串流印表機。
ws.onmessage = event => {
let message = JSON.parse(event.data);
if (message.type === 'message' && message.group === 'stream') {
let d = document.createElement('span');
d.innerText = message.data;
output.appendChild(d);
window.scrollTo(0, document.body.scrollHeight);
}
};
基於安全性考慮,用戶端預設無法自行發佈或訂閱群組。 因此,您會注意到,我們在產生權杖時為用戶端設定 roles
:
當 GenerateClientAccessUri
在 Startup.cs
中時,設定 roles
,如下所示:
service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
當 getClientAccessToken
在 server.js
中時,新增 roles
,如下所示:
app.get('/negotiate', async (req, res) => {
let token = await service.getClientAccessToken({
roles: ['webpubsub.sendToGroup.stream', 'webpubsub.joinLeaveGroup.stream']
});
...
});
在產生存取權杖的流程中,在 server.py
中為用戶端設定正確的角色:
roles = ['webpubsub.sendToGroup.stream',
'webpubsub.joinLeaveGroup.stream']
token = service.get_client_access_token(roles=roles)
在產生存取權杖的流程中,在 App.java
中為用戶端設定正確的角色:
GetClientAccessTokenOptions option = new GetClientAccessTokenOptions();
option.addRole("webpubsub.sendToGroup.stream");
option.addRole("webpubsub.joinLeaveGroup.stream");
WebPubSubClientAccessToken token = service.getClientAccessToken(option);
最後,也套用一些樣式到 index.html
,使其妥善地顯示。
<html>
<head>
<style>
#output {
white-space: pre;
font-family: monospace;
}
</style>
</head>
現在,執行下列程式碼並輸入任何文字,這些文字會即時顯示在瀏覽器中:
ls -R | dotnet run
# Or call `dir /s /b | dotnet run` when you are using CMD under Windows
或者,您可以放慢速度,以便看到資料即時串流至瀏覽器:
for i in $(ls -R); do echo $i; sleep 0.1; done | dotnet run
您可以在這裡找到此教學課程的完整程式碼範例。
node stream
或者,您也可以使用此應用程式管道,從另一個主控台應用程式傳送任何輸出,並將其串流至瀏覽器。 例如:
ls -R | node stream
# Or call `dir /s /b | node stream` when you are using CMD under Windows
或者,您可以放慢速度,以便看到資料即時串流至瀏覽器:
for i in $(ls -R); do echo $i; sleep 0.1; done | node stream
您可以在這裡找到此教學課程的完整程式碼範例。
現在,執行 python stream.py
並輸入任何文字,這些文字會即時顯示在瀏覽器中。
或者,您也可以使用此應用程式管道,從另一個主控台應用程式傳送任何輸出,並將其串流至瀏覽器。 例如:
ls -R | python stream.py
# Or call `dir /s /b | python stream.py` when you are using CMD under Windows
或者,您可以放慢速度,以便看到資料即時串流至瀏覽器:
for i in $(ls -R); do echo $i; sleep 0.1; done | python stream.py
您可以在這裡找到此教學課程的完整程式碼範例。
現在,執行下列程式碼並輸入任何文字,這些文字會即時顯示在瀏覽器中。
mvn compile & mvn package & mvn exec:java -Dexec.mainClass="com.webpubsub.quickstart.App" -Dexec.cleanupDaemonThreads=false
您可以在這裡找到此教學課程的完整程式碼範例。
下一步
此教學課程提供如何連線至 Web PubSub 服務,以及如何將訊息發佈至已連線用戶端的基本概念。
請查看其他教學課程,以進一步了解如何使用此服務。