클라이언트는 표준 WebSocket 프로토콜을 사용하여 Azure Web PubSub 서비스에 연결합니다. WebSocket 클라이언트가 지원되는 언어를 사용하여 서비스 클라이언트를 작성할 수 있습니다. 이 문서에서는 다양한 언어의 WebSocket 클라이언트 샘플을 여럿 볼 수 있습니다.
Authorization
Web PubSub은 JWT(JSON 웹 토큰)를 사용하여 클라이언트의 유효성을 검사하고 권한을 부여합니다. 클라이언트는 토큰을 access_token 쿼리 매개 변수에 넣거나, 서비스에 연결할 때 Authorization 헤더에 넣을 수 있습니다.
일반적인으로 클라이언트는 먼저 앱 서버와 통신하여 서비스 및 토큰의 URL을 가져옵니다. 그런 다음 클라이언트에서 수신한 URL과 토큰을 사용하여 서비스에 대한 WebSocket 연결을 엽니다.
또한 포털은 토큰을 사용하여 클라이언트 URL을 동적으로 생성하는 도구를 제공합니다. 이 도구는 빠른 테스트를 수행하는 데 유용할 수 있습니다.
참고 항목
토큰을 생성할 때 필요한 역할만 포함해야 합니다.
다음 섹션에서는 샘플 워크플로를 간소화하기 위해 클라이언트가 연결할 포털에서 일시적으로 생성된 URL을 사용합니다. <Client_URL_From_Portal>을 사용하여 값을 나타냅니다. 생성된 토큰은 기본적으로 60분 후에 만료되므로, 토큰이 만료되면 다시 생성하는 것을 잊지 마세요.
이 서비스는 두 가지 유형의 WebSocket 클라이언트를 지원합니다. 하나는 단순 WebSocket 클라이언트이고 다른 하나는 PubSub WebSocket 클라이언트입니다. 여기에서는 이 두 종류의 클라이언트가 서비스에 연결하는 방법을 보여 줍니다. 이러한 클라이언트에 대한 자세한 내용은 Azure Web PubSub용 WebSocket 클라이언트 프로토콜을 참조하세요.
<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);
}
}
}
<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을 가져오는 방법을 살펴보려면 다음 자습서를 읽고 샘플을 확인하세요.