クライアントから Azure Web PubSub サービスへの接続には、標準の WebSocket プロトコルが使用されます。 WebSocket クライアントに対応した言語を使用して、サービスのクライアントを作成できます。 この記事では、さまざまな言語の WebSocket クライアントのサンプルをいくつか確認します。
承認
Web PubSub では、JSON Web Token (JWT) を使用してクライアントの検証と認可を行います。 クライアントでは、サービスへの接続時に、トークンを access_token
クエリ パラメーターに配置するか、Authorization
ヘッダーに配置することができます。
一般的に、クライアントではまずアプリ サーバーと通信し、サービスの URL とトークンを取得します。 その後、クライアントでは受け取った URL とトークンを使用して、サービスへの WebSocket 接続を開きます。
また、ポータルでは、トークンを使用してクライアント URL を動的に生成するツールも提供します。 このツールは、簡単なテストを行うのに役立ちます。
Note
トークンを生成するときには、必要なロールのみを含めるようにしてください。
次のセクションでは、このサンプル ワークフローを簡略化するために、ポータルから一時的に生成された URL を使用して、クライアントが接続できるようにします。 その値を表すのに、<Client_URL_From_Portal>
を使用します。 生成されるトークンの有効期限は既定で 60 分なので、有効期限が切れた場合は、忘れずに再生成してください。
このサービスでは、シンプルな WebSocket クライアントと、PubSub WebSocket クライアントの 2 種類の WebSocket クライアントがサポートされています。 ここでは、これら 2 種類のクライアントがサービスに接続する方法について説明します。 これらのクライアントの詳細については、「Azure Web PubSub の WebSocket クライアント プロトコル」を参照してください。
依存関係
最新のブラウザーでは、WebSocket
API がネイティブでサポートされています。
シンプル WebSocket クライアント
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);
}
}
}
PubSub WebSocket クライアント
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 を取得する方法については、これらのチュートリアルを参照し、サンプルを確認してください。