客户端使用标准 WebSocket 协议连接到 Azure Web PubSub 服务。 可以使用 WebSocket 客户端支持的语言为服务编写客户端。 在本文中,你将看到几个不同语言的 WebSocket 客户端示例。
Web PubSub 使用 JSON Web 令牌 (JWT) 来验证和授权客户端。 客户端可将该令牌放在 access_token
查询参数中,或者在连接到服务时将该令牌放在 Authorization
头中。
通常,客户端先与其应用服务器通信,以获取服务和令牌的 URL。 然后,客户端使用收到的 URL 和令牌打开与服务的 WebSocket 连接。
该门户还提供了一个工具,用于以动态方式生成带令牌的客户端 URL。 此工具可用于快速测试。
为了简化示例工作流,在以下各部分,我们将使用门户中临时生成的此 URL 供客户端连接。 <Client_URL_From_Portal>
用于表示值。 生成的令牌默认会在 60 分钟后过期,因此请记得在令牌过期后重新生成令牌。
该服务支持两种类型的 WebSocket 客户端:一种是简单 WebSocket 客户端,另一种是 PubSub WebSocket 客户端。 下面介绍这两种客户端如何连接到该服务。 有关这些客户端的详细信息,请参阅适用于 Azure Web PubSub 的 WebSocket 客户端协议。
大多数新式浏览器原生就能支持 WebSocket
API。
在 HTML 页面的 script
块中:
<script>
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
let ws = new WebSocket("<Client_URL_From_Portal>");
ws.onopen = () => {
// Do things when the WebSocket connection is established
};
ws.onmessage = event => {
// Do things when messages are received.
};
</script>
const WebSocket = require('ws');
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
const client = new WebSocket("<Client_URL_From_Portal>");
client.on('open', () => {
// Do things when the WebSocket connection is established
});
client.on('message', msg => {
// Do things when messages are received.
});
import asyncio
import websockets
async def hello():
# Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
uri = '<Client_URL_From_Portal>'
async with websockets.connect(uri) as ws:
while True:
await ws.send('hello')
greeting = await ws.recv()
print(greeting)
asyncio.get_event_loop().run_until_complete(hello())
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Websocket.Client;
namespace subscriber
{
class Program
{
static async Task Main(string[] args)
{
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
using (var client = new WebsocketClient(new Uri("<Client_URL_From_Portal>")))
{
// Disable the auto disconnect and reconnect because the sample would like the client to stay online even if no data comes in
client.ReconnectTimeout = null;
client.MessageReceived.Subscribe(msg => Console.WriteLine($"Message received: {msg}"));
await client.Start();
Console.WriteLine("Connected.");
Console.Read();
}
}
}
}
package client;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.concurrent.CompletionStage;
/**
* A simple WebSocket Client.
*
*/
public final class SimpleClient {
private SimpleClient() {
}
/**
* Starts a simple WebSocket connection.
* @param args The arguments of the program.
*/
public static void main(String[] args) throws Exception {
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
WebSocket ws = HttpClient.newHttpClient().newWebSocketBuilder()
.buildAsync(URI.create("<Client_URL_From_Portal>"), new WebSocketClient()).join();
System.in.read();
}
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);
}
}
}
在 HTML 页面的 script
块中:
<script>
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
let ws = new WebSocket("<Client_URL_From_Portal>", 'json.webpubsub.azure.v1');
ws.onopen = () => {
// Do things when the WebSocket connection is established
};
ws.onmessage = event => {
// Do things when messages are received.
};
</script>
const WebSocket = require('ws');
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
const client = new WebSocket("<Client_URL_From_Portal>", "json.webpubsub.azure.v1");
client.on('open', () => {
// Do things when the WebSocket connection is established
});
client.on('message', msg => {
// Do things when messages are received.
});
import asyncio
import websockets
async def join_group():
# Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
uri = '<Client_URL_From_Portal>'
async with websockets.connect(uri, subprotocols=['json.webpubsub.azure.v1']) as ws:
await ws.send('{"type":"joinGroup","ackId":1,"group":"group1"}')
return await ws.recv()
print(asyncio.get_event_loop().run_until_complete(join_group()))
using System;
using System.IO;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;
namespace subscriber
{
class Program
{
static async Task Main(string[] args)
{
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
using (var client = new WebsocketClient(new Uri("<Client_URL_From_Portal>"), () =>
{
var inner = new ClientWebSocket();
inner.Options.AddSubProtocol("json.webpubsub.azure.v1");
return inner;
}))
{
// Disable the auto disconnect and reconnect because the sample would like the client to stay online even if no data comes in
client.ReconnectTimeout = null;
client.MessageReceived.Subscribe(msg => Console.WriteLine($"Message received: {msg}"));
await client.Start();
Console.WriteLine("Connected.");
Console.Read();
}
}
}
}
package client;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.concurrent.CompletionStage;
/**
* A PubSub WebSocket Client.
*
*/
public final class SubprotocolClient {
private SubprotocolClient() {
}
/**
* Starts a PubSub WebSocket connection.
* @param args The arguments of the program.
*/
public static void main(String[] args) throws Exception {
// Don't forget to replace this <Client_URL_From_Portal> with the value fetched from the portal
WebSocket ws = HttpClient.newHttpClient().newWebSocketBuilder().subprotocols("json.webpubsub.azure.v1")
.buildAsync(URI.create("<Client_URL_From_Portal>"), new WebSocketClient()).join();
ws.sendText("{\"type\":\"joinGroup\",\"ackId\":1,\"group\":\"group1\"}", true);
System.in.read();
}
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);
}
}
}
本文介绍了如何使用门户中生成的 URL 连接到服务。 若要了解客户端如何与应用服务器通信以获取实际应用程序中的 URL,请参阅以下教程并查看示例。