Öğretici: Azure Web PubSub hizmetiyle sohbet uygulaması oluşturma
İleti yayımlama ve abone olma öğreticisinde, Azure Web PubSub ile iletileri yayımlama ve abone olma ile ilgili temel bilgileri öğrenirsiniz. Bu öğreticide Azure Web PubSub'un olay sistemini öğrenecek ve gerçek zamanlı iletişim işlevselliğine sahip eksiksiz bir web uygulaması oluşturmak için kullanacaksınız.
Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:
- Web PubSub hizmet örneği oluşturma
- Azure Web PubSub için olay işleyici ayarlarını yapılandırma
- Uygulama sunucusundaki olayları işleme ve gerçek zamanlı sohbet uygulaması oluşturma
Azure aboneliğiniz yoksa başlamadan önce birücretsiz Azure hesabı oluşturun.
Önkoşullar
Azure Cloud Shell'de Bash ortamını kullanın. Daha fazla bilgi için bkz . Azure Cloud Shell'de Bash için hızlı başlangıç.
CLI başvuru komutlarını yerel olarak çalıştırmayı tercih ediyorsanız Azure CLI'yı yükleyin . Windows veya macOS üzerinde çalışıyorsanız Azure CLI’yi bir Docker kapsayıcısında çalıştırmayı değerlendirin. Daha fazla bilgi için bkz . Docker kapsayıcısında Azure CLI'yi çalıştırma.
Yerel yükleme kullanıyorsanız az login komutunu kullanarak Azure CLI ile oturum açın. Kimlik doğrulama işlemini tamamlamak için terminalinizde görüntülenen adımları izleyin. Diğer oturum açma seçenekleri için bkz . Azure CLI ile oturum açma.
İstendiğinde, ilk kullanımda Azure CLI uzantısını yükleyin. Uzantılar hakkında daha fazla bilgi için bkz. Azure CLI ile uzantıları kullanma.
Yüklü sürümü ve bağımlı kitaplıkları bulmak için az version komutunu çalıştırın. En son sürüme yükseltmek için az upgrade komutunu çalıştırın.
- Bu kurulum, Azure CLI'nın 2.22.0 veya üzeri bir sürümünü gerektirir. Azure Cloud Shell kullanılıyorsa en son sürüm zaten yüklüdür.
Azure Web PubSub örneği oluşturma
Kaynak grubu oluşturma
Kaynak grubu, Azure kaynaklarının dağıtıldığı ve yönetildiği bir mantıksal kapsayıcıdır.
konumunda adlı myResourceGroup
eastus
bir kaynak grubu oluşturmak için az group create komutunu kullanın.
az group create --name myResourceGroup --location EastUS
Web PubSub örneği oluşturma
Webpubsub uzantısını yüklemek veya geçerli sürüme yükseltmek için az extension add komutunu çalıştırın.
az extension add --upgrade --name webpubsub
Oluşturduğunuz kaynak grubunda bir Web PubSub oluşturmak için Azure CLI az webpubsub create komutunu kullanın. Aşağıdaki komut, EastUS'ta myResourceGroup kaynak grubu altında bir Ücretsiz Web PubSub kaynağı oluşturur:
Önemli
Her Web PubSub kaynağının benzersiz bir adı olmalıdır. Aşağıdaki örneklerde unique-resource-name> değerini Web PubSub'ınızın adıyla değiştirin<.
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
Bu komutun çıktısı yeni oluşturulan kaynağın özelliklerini gösterir. Aşağıda listelenen iki özelliği not edin:
-
Kaynak Adı: Yukarıdaki parametreye
--name
sağladığınız ad. -
hostName: Örnekte ana bilgisayar adı şeklindedir
<your-unique-resource-name>.webpubsub.azure.com/
.
Bu noktada, azure hesabınız bu yeni kaynak üzerinde herhangi bir işlem gerçekleştirme yetkisi olan tek hesaptır.
Gelecekte kullanmak üzere ConnectionString'i edinin
Önemli
Ham bağlantı dizesi yalnızca tanıtım amacıyla bu makalede görünür.
bağlantı dizesi, uygulamanızın Azure Web PubSub hizmetine erişmesi için gereken yetkilendirme bilgilerini içerir. bağlantı dizesi içindeki erişim anahtarı, hizmetinizin kök parolasına benzer. Üretim ortamlarında erişim anahtarlarınızı her zaman koruyun. Anahtarlarınızı güvenli bir şekilde yönetmek ve döndürmek ve bağlantınızın WebPubSubServiceClient
güvenliğini sağlamak için Azure Key Vault kullanın.
Erişim anahtarlarını diğer kullanıcılara dağıtmaktan, sabit kodlamaktan veya başkalarının erişebileceği herhangi bir yerde düz metin olarak kaydetmekten kaçının. Ele geçirilmiş olabileceklerini düşünüyorsanız anahtarlarınızı döndürün.
Hizmetin ConnectionString'ini almak için Azure CLI az webpubsub key komutunu kullanın. Yer tutucuyu <your-unique-resource-name>
Azure Web PubSub örneğinizin adıyla değiştirin.
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
Daha sonra kullanmak üzere bağlantı dizesi kopyalayın.
Getirilen ConnectionString'i kopyalayın ve daha sonra öğreticinin okuyduğu ortam değişkenine WebPubSubConnectionString
ayarlayın. aşağıdaki değerini, getirdiğiniz ConnectionString ile değiştirin<connection-string>
.
export WebPubSubConnectionString="<connection-string>"
SET WebPubSubConnectionString=<connection-string>
Projeyi ayarlama
Önkoşullar
Uygulamayı oluşturma
Azure Web PubSub'da sunucu ve istemci olarak iki rol vardır. Bu kavram, bir web uygulamasındaki sunucu ve istemci rollerine benzer. Sunucu, istemcileri yönetmek, dinlemek ve istemci iletilerini yanıtlamakla sorumludur. İstemci, kullanıcının iletilerini sunucudan gönderip almaktan ve son kullanıcı için görselleştirmekten sorumludur.
Bu öğreticide, gerçek zamanlı bir sohbet web uygulaması oluşturacağız. Gerçek bir web uygulamasında, sunucunun sorumluluğu istemcilerin kimliğini doğrulamayı ve uygulama kullanıcı arabirimi için statik web sayfaları sunmayı da içerir.
Web sayfalarını barındırmak ve gelen istekleri işlemek için ASP.NET Core 8 kullanıyoruz.
İlk olarak bir klasörde ASP.NET Core web uygulaması chatapp
oluşturalım.
Yeni bir web uygulaması oluşturun.
mkdir chatapp cd chatapp dotnet new web
Statik web sayfalarını barındırmayı desteklemek için Program.cs ekleyin
app.UseStaticFiles()
.var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseStaticFiles(); app.Run();
Bir HTML dosyası oluşturun ve olarak
wwwroot/index.html
kaydedin. Bunu daha sonra sohbet uygulamasının kullanıcı arabirimi için kullanacağız.<html> <body> <h1>Azure Web PubSub Chat</h1> </body> </html>
Tarayıcıda çalıştırarak dotnet run --urls http://localhost:8080
ve bu sunucuya erişerek http://localhost:8080/index.html
sunucuyu test edebilirsiniz.
Anlaşma uç noktası ekleme
Yayımlama ve abone olma iletisi öğreticisinde, abone bağlantı dizesi doğrudan tüketir. Bağlantı dizesi hizmete herhangi bir işlem yapmak için yüksek ayrıcalığı olduğundan, gerçek bir dünya uygulamasında bağlantı dizesi herhangi bir istemciyle paylaşmak güvenli değildir. Şimdi sunucunuzun bağlantı dizesi kullanmasını ve istemcinin erişim belirteci ile tam URL'yi alması için bir negotiate
uç noktayı kullanıma sunun. Bu şekilde, sunucu yetkisiz erişimi önlemek için uç noktanın negotiate
önüne kimlik doğrulama ara yazılımı ekleyebilir.
İlk olarak bağımlılıkları yükleyin.
dotnet add package Microsoft.Azure.WebPubSub.AspNetCore
Şimdi belirteci oluşturmak üzere istemcisinin çağıracağı bir /negotiate
uç nokta ekleyelim.
using Azure.Core;
using Microsoft.Azure.WebPubSub.AspNetCore;
using Microsoft.Azure.WebPubSub.Common;
using Microsoft.Extensions.Primitives;
// Read connection string from environment
var connectionString = Environment.GetEnvironmentVariable("WebPubSubConnectionString");
if (connectionString == null)
{
throw new ArgumentNullException(nameof(connectionString));
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWebPubSub(o => o.ServiceEndpoint = new WebPubSubServiceEndpoint(connectionString))
.AddWebPubSubServiceClient<Sample_ChatApp>();
var app = builder.Build();
app.UseStaticFiles();
// return the Client Access URL with negotiate endpoint
app.MapGet("/negotiate", (WebPubSubServiceClient<Sample_ChatApp> service, HttpContext context) =>
{
var id = context.Request.Query["id"];
if (StringValues.IsNullOrEmpty(id))
{
context.Response.StatusCode = 400;
return null;
}
return new
{
url = service.GetClientAccessUri(userId: id).AbsoluteUri
};
});
app.Run();
sealed class Sample_ChatApp : WebPubSubHub
{
}
AddWebPubSubServiceClient<THub>()
, istemci bağlantı belirteci oluşturmak için anlaşma adımında ve hub olayları tetiklendiğinde hizmet REST API'lerini çağırmak için hub yöntemlerinde kullanabileceğimiz hizmet istemcisini WebPubSubServiceClient<THub>
eklemek için kullanılır. Bu belirteç oluşturma kodu, yayımlama ve abone olma iletisi öğreticisinde kullandığımız koda benzer, ancak belirteci oluştururken bir bağımsız değişken daha (userId
) geçiririz. kullanıcı kimliği istemci kimliğini tanımlamak için kullanılabilir, böylece bir ileti aldığınızda iletinin nereden geldiğini bilirsiniz.
Kod, önceki adımda ayarladığımız ortam değişkenindeki WebPubSubConnectionString
bağlantı dizesi okur.
kullanarak dotnet run --urls http://localhost:8080
sunucuyu yeniden çalıştırın.
Bu API'ye erişerek http://localhost:8080/negotiate?id=user1
test edebilirsiniz ve size erişim belirteci ile Azure Web PubSub'un tam URL'sini verir.
Olayları işleme
Azure Web PubSub'da, istemci tarafında belirli etkinlikler gerçekleştiğinde (örneğin bir istemci bağlanıyor, bağlı, bağlantısı kesiliyor veya bir istemci ileti gönderiyorsa), hizmet bu olaylara tepki verebilmesi için sunucuya bildirimler gönderir.
Olaylar web kancası biçiminde sunucuya teslim edilir. Web kancası uygulama sunucusu tarafından sunulur ve kullanıma sunulur ve Azure Web PubSub hizmeti tarafında kaydedilir. Bir olay gerçekleştiğinde hizmet web kancalarını çağırır.
Azure Web PubSub, olay verilerini açıklamak için CloudEvents'i izler.
Aşağıda, bir istemci bağlandığında sistem olaylarını ve bir istemci sohbet uygulamasını derlemek için ileti gönderirken kullanıcı olaylarını ele message
alıyoruzconnected
.
Önceki adımda yüklediğimiz AspNetCore Microsoft.Azure.WebPubSub.AspNetCore
için Web PubSub SDK'sı, CloudEvents isteklerini ayrıştırma ve işlemeye de yardımcı olabilir.
İlk olarak, önüne app.Run()
olay işleyicileri ekleyin. Olaylar için uç nokta yolunu (diyelim ki /eventhandler
) belirtin.
app.MapWebPubSubHub<Sample_ChatApp>("/eventhandler/{*path}");
app.Run();
Şimdi, önceki adımda oluşturduğumuz sınıfın Sample_ChatApp
içinde, Web PubSub hizmetini çağırmak için kullandığımız bir WebPubSubServiceClient<Sample_ChatApp>
oluşturucu ekleyin. Ve OnConnectedAsync()
olay tetiklendiğinde connected
yanıt vermek, OnMessageReceivedAsync()
istemciden gelen iletileri işlemek için.
sealed class Sample_ChatApp : WebPubSubHub
{
private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;
public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
{
_serviceClient = serviceClient;
}
public override async Task OnConnectedAsync(ConnectedEventRequest request)
{
Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
}
public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
{
await _serviceClient.SendToAllAsync(RequestContent.Create(
new
{
from = request.ConnectionContext.UserId,
message = request.Data.ToString()
}),
ContentType.ApplicationJson);
return new UserEventResponse();
}
}
Yukarıdaki kodda, JSON biçiminde bir bildirim iletisi yayınlamak için hizmet istemcisini kullanırız ve bu iletinin tümü ile birleştirilir SendToAllAsync
.
Web sayfasını güncelleştirme
Şimdi bağlanacak, ileti gönderecek ve alınan iletileri sayfada görüntüleyecek mantığı ekleyecek şekilde güncelleştirelim index.html
.
<html>
<body>
<h1>Azure Web PubSub Chat</h1>
<input id="message" placeholder="Type to chat...">
<div id="messages"></div>
<script>
(async function () {
let id = prompt('Please input your user name');
let res = await fetch(`/negotiate?id=${id}`);
let data = await res.json();
let ws = new WebSocket(data.url);
ws.onopen = () => console.log('connected');
let messages = document.querySelector('#messages');
ws.onmessage = event => {
let m = document.createElement('p');
let data = JSON.parse(event.data);
m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
messages.appendChild(m);
};
let message = document.querySelector('#message');
message.addEventListener('keypress', e => {
if (e.charCode !== 13) return;
ws.send(message.value);
message.value = '';
});
})();
</script>
</body>
</html>
Yukarıdaki kodda bağlandığımız kodun tarayıcıda yerel WebSocket API'sini, ileti göndermek ve WebSocket.onmessage
alınan iletileri dinlemek için kullandığını WebSocket.send()
görebilirsiniz.
Ayrıca hizmete bağlanmak için İstemci SDK'larını da kullanabilirsiniz. Bu da sizi otomatik yeniden bağlama, hata işleme ve daha fazlası ile güçlendirebilir.
Artık sohbetin çalışması için bir adım kaldı. Hangi olayları önemsediğimizi ve Web PubSub hizmetinde olayları nereye gönderebileceğimizi yapılandıralım.
Olay işleyicisini ayarlama
Web PubSub hizmetinde olay işleyicisini, hizmete olayların nereye gönderileceğine söyleyecek şekilde ayarladık.
Web sunucusu yerel olarak çalıştırıldığında, web PubSub hizmeti internetten erişilebilen uç noktası yoksa localhost'ı nasıl çağırır? Genellikle iki yol vardır. Bunlardan biri, bir genel tünel aracı kullanarak localhost'un genel kullanıma sunma, diğeri ise web PubSub hizmetinden gelen trafiği yerel sunucunuza tünel oluşturmak için awps-tunnel kullanmaktır.
Bu bölümde, olay işleyicilerini ayarlamak için Azure CLI'yi ve trafiği localhost'a yönlendirmek için awps-tunnel kullanacağız.
Hub ayarlarını yapılandırma
Web PubSub'un iletileri 'nin tünel bağlantısı üzerinden awps-tunnel
yönlendirmesi için URL şablonunu düzen kullanacak tunnel
şekilde ayarladık. Olay işleyicileri, bu makalede açıklandığı gibi portaldan veya CLI'dan ayarlanabilir. Burada CLI aracılığıyla ayarlayacağız. Önceki adım ayarlandığı gibi yoldaki /eventhandler
olayları dinlediğimiz için URL şablonunu olarak tunnel:///eventhandler
ayarlarız.
Hub için olay işleyici ayarlarını oluşturmak için Sample_ChatApp
Azure CLI az webpubsub hub create komutunu kullanın.
Önemli
benzersiz-kaynak-adınızı> önceki adımlardan oluşturulan Web PubSub kaynağınızın adıyla değiştirin<.
az webpubsub hub create -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected"
awps-tunnel'ı yerel olarak çalıştırma
awps-tunnel indirme ve yükleme
Araç, Node.js sürüm 16 veya üzeri üzerinde çalışır.
npm install -g @azure/web-pubsub-tunnel-tool
Hizmet bağlantı dizesi kullanma ve çalıştırma
export WebPubSubConnectionString="<your connection string>"
awps-tunnel run --hub Sample_ChatApp --upstream http://localhost:8080
Web sunucusunu çalıştırma
Artık her şey ayarlandı. Şimdi web sunucusunu çalıştıralım ve sohbet uygulamasını çalışır durumda oynatalım.
Şimdi kullanarak sunucuyu dotnet run --urls http://localhost:8080
çalıştırın.
Bu öğreticinin tam kod örneğini burada bulabilirsiniz.
http://localhost:8080/index.html
'ı açın. Kullanıcı adınızı girip sohbet etmeye başlayabilirsiniz.
Olay işleyicisi ile Gecikmeli connect
Kimlik Doğrulaması
Önceki bölümlerde, istemcilerin Web PubSub hizmetine bağlanması için Web PubSub hizmet URL'sini ve JWT erişim belirtecini döndürmek için anlaşma uç noktasının nasıl kullanılacağını gösteriyoruz. Bazı durumlarda, örneğin, kaynakları sınırlı olan uç cihazlar, istemciler Web PubSub kaynaklarına doğrudan bağlanmayı tercih edebilir. Bu gibi durumlarda, istemcilere yavaş kimlik doğrulaması yapmak, istemcilere kullanıcı kimliği atamak, istemcilerin bağlandıktan sonra katıldığı grupları belirtmek, istemcilerin sahip olduğu izinleri ve WebSocket altprotocol'u istemciye WebSocket yanıtı olarak yapılandırmak için olay işleyicisini yapılandırabilirsinizconnect
. Ayrıntılar lütfen olay işleyicisi belirtimini bağlama konusuna bakın.
Şimdi olay işleyicisini kullanarak connect
anlaşma bölümünün yaptığı gibi benzer bir sonuç elde edelim.
Hub ayarlarını güncelleştirme
İlk olarak hub ayarlarını olay işleyicisini de içerecek connect
şekilde güncelleştirelim. JWT erişim belirteci olmayan istemcilerin hizmete bağlanabilmesi için anonim bağlantıya da izin vermemiz gerekiyor.
Hub için olay işleyici ayarlarını oluşturmak için Sample_ChatApp
Azure CLI az webpubsub hub update komutunu kullanın.
Önemli
benzersiz-kaynak-adınızı> önceki adımlardan oluşturulan Web PubSub kaynağınızın adıyla değiştirin<.
az webpubsub hub update -n "<your-unique-resource-name>" -g "myResourceGroup" --hub-name "Sample_ChatApp" --allow-anonymous true --event-handler url-template="tunnel:///eventhandler" user-event-pattern="*" system-event="connected" system-event="connect"
Bağlantı olayını işlemek için yukarı akış mantığını güncelleştirme
Şimdi bağlantı olayını işlemek için yukarı akış mantığını güncelleştirelim. Şimdi anlaşma uç noktasını da kaldırabiliriz.
Tanıtım amaçlı olarak anlaşma uç noktasında yaptıklarımıza benzer şekilde sorgu parametrelerinden kimlik de okuruz. Connect olayında, özgün istemci sorgusu bağlanma olayı istek gövdesinde korunur.
sınıfının Sample_ChatApp
içinde, olayı işlemek connect
için öğesini geçersiz kılınOnConnectAsync()
:
sealed class Sample_ChatApp : WebPubSubHub
{
private readonly WebPubSubServiceClient<Sample_ChatApp> _serviceClient;
public Sample_ChatApp(WebPubSubServiceClient<Sample_ChatApp> serviceClient)
{
_serviceClient = serviceClient;
}
public override ValueTask<ConnectEventResponse> OnConnectAsync(ConnectEventRequest request, CancellationToken cancellationToken)
{
if (request.Query.TryGetValue("id", out var id))
{
return new ValueTask<ConnectEventResponse>(request.CreateResponse(userId: id.FirstOrDefault(), null, null, null));
}
// The SDK catches this exception and returns 401 to the caller
throw new UnauthorizedAccessException("Request missing id");
}
public override async Task OnConnectedAsync(ConnectedEventRequest request)
{
Console.WriteLine($"[SYSTEM] {request.ConnectionContext.UserId} joined.");
}
public override async ValueTask<UserEventResponse> OnMessageReceivedAsync(UserEventRequest request, CancellationToken cancellationToken)
{
await _serviceClient.SendToAllAsync(RequestContent.Create(
new
{
from = request.ConnectionContext.UserId,
message = request.Data.ToString()
}),
ContentType.ApplicationJson);
return new UserEventResponse();
}
}
Index.html doğrudan bağlanacak şekilde güncelleştirme
Şimdi Web PubSub hizmetine doğrudan bağlanmak için web sayfasını güncelleştirelim. Bahsetmeniz gereken bir nokta, tanıtım amacıyla Web PubSub hizmet uç noktasının istemci koduna sabit kodlanmış olmasıdır. Lütfen aşağıdaki html'deki hizmet ana bilgisayar adını <the host name of your service>
kendi hizmetinizdeki değerle güncelleştirin. Web PubSub hizmet uç noktası değerini sunucunuzdan getirmek hala yararlı olabilir; istemcinin bağlandığı yere daha fazla esneklik ve denetlenebilirlik sağlar.
<html>
<body>
<h1>Azure Web PubSub Chat</h1>
<input id="message" placeholder="Type to chat...">
<div id="messages"></div>
<script>
(async function () {
// sample host: mock.webpubsub.azure.com
let hostname = "<the host name of your service>";
let id = prompt('Please input your user name');
let ws = new WebSocket(`wss://${hostname}/client/hubs/Sample_ChatApp?id=${id}`);
ws.onopen = () => console.log('connected');
let messages = document.querySelector('#messages');
ws.onmessage = event => {
let m = document.createElement('p');
let data = JSON.parse(event.data);
m.innerText = `[${data.type || ''}${data.from || ''}] ${data.message}`;
messages.appendChild(m);
};
let message = document.querySelector('#message');
message.addEventListener('keypress', e => {
if (e.charCode !== 13) return;
ws.send(message.value);
message.value = '';
});
})();
</script>
</body>
</html>
Sunucuyu yeniden çalıştırma
Şimdi sunucuyu yeniden çalıştırın ve önceki yönergeleri izleyerek web sayfasını ziyaret edin. 'yi durdurduysanız awps-tunnel
lütfen tünel aracını da yeniden çalıştırın.
Sonraki adımlar
Bu öğretici, Azure Web PubSub hizmetinde olay sisteminin nasıl çalıştığı hakkında temel bir fikir sağlar.
Hizmetin nasıl kullanılacağı hakkında daha fazla bilgi edinmek için diğer öğreticileri gözden geçirin.