Pengembangan dan konfigurasi Azure Functions dengan Azure SignalR Service
Aplikasi Azure Functions dapat menggunakan pengikatan Azure SignalR Service untuk menambahkan kemampuan real time. Aplikasi klien menggunakan SDK klien yang tersedia dalam beberapa bahasa untuk tersambung ke Azure SignalR Service dan menerima pesan real-time.
Artikel ini menjelaskan konsep untuk mengembangkan dan mengonfigurasi aplikasi Azure Function yang terintegrasi dengan SignalR Service.
Konfigurasi SignalR Service
Azure SignalR Service dapat dikonfigurasi dalam mode yang berbeda. Saat digunakan dengan Azure Functions, layanan harus dikonfigurasi dalam mode Tanpa Server.
Di portal Microsoft Azure, temukan halaman Pengaturan sumber daya SignalR Service Anda. Atur mode Layanan ke Tanpa server.
Pengembangan Azure Functions
Aplikasi real-time tanpa server yang dibangun dengan Azure Functions dan Azure SignalR Service memerlukan setidaknya dua Azure Functions:
- Fungsi
negotiate
yang dipanggil klien untuk mendapatkan token akses SignalR Service yang valid dan URL titik akhir. - Satu atau beberapa fungsi yang menangani pesan yang dikirim dari SignalR Service ke klien.
Fungsi negosiasi
Aplikasi klien memerlukan token akses yang valid untuk tersambung ke Azure SignalR Service. Token akses dapat berupa anonim atau diautentikasi ke ID pengguna. Aplikasi SignalR Service tanpa server memerlukan titik akhir HTTP bernama negotiate
untuk mendapatkan token dan informasi koneksi lainnya, seperti URL titik akhir SignalR Service.
Gunakan Fungsi Azure yang dipicu HTTP dan SignalRConnectionInfo
pengikatan input untuk menghasilkan objek informasi koneksi. Fungsi harus memiliki rute HTTP yang berakhiran /negotiate
.
Dengan model berbasis kelas di C#, Anda tidak memerlukan SignalRConnectionInfo
pengikatan input dan dapat menambahkan klaim kustom dengan lebih mudah. Untuk informasi selengkapnya, lihat Pengalaman negosiasi dalam model berbasis kelas.
Untuk informasi selengkapnya tentang fungsi ini negotiate
, lihat Pengembangan Azure Functions.
Untuk mempelajari cara membuat token terautentikasi, lihat Menggunakan Autentikasi App Service.
Menangani pesan yang dikirim dari SignalR Service
Gunakan pengikatan SignalRTrigger
untuk menangani pesan yang dikirim dari SignalR Service. Anda bisa mendapatkan pemberitahuan ketika klien mengirim pesan atau klien tersambung atau terputus.
Untuk informasi selengkapnya, lihat referensi pengikatan pemicu SignalR Service.
Anda juga perlu mengonfigurasi titik akhir fungsi Anda sebagai titik akhir upstream sehingga layanan memicu fungsi ketika ada pesan dari klien. Untuk informasi selengkapnya tentang cara mengonfigurasi titik akhir upstram, lihat Titik akhir upstram.
Catatan
SignalR Service tidak mendukung StreamInvocation
pesan dari klien dalam Mode Tanpa Server.
Mengirim pesan dan mengelola keanggotaan grup
Gunakan pengikatan SignalR
output untuk mengirim pesan ke klien yang terhubung ke Azure SignalR Service. Anda dapat menyiarkan pesan ke semua klien, atau Anda dapat mengirimnya ke subset klien. Misalnya, hanya mengirim pesan ke klien yang diautentikasi dengan ID pengguna tertentu, atau hanya ke grup tertentu.
Pengguna dapat ditambahkan ke satu atau beberapa grup. Anda juga dapat menggunakan pengikatan SignalR
output untuk menambahkan atau menghapus pengguna ke/dari grup.
Untuk informasi selengkapnya, lihat SignalR
referensi pengikatan output.
Hub SignalR
SignalR memiliki konsep hub. Setiap sambungan klien dan setiap pesan yang dikirim dari Azure Functions dicakup ke hub tertentu. Anda dapat menggunakan hub sebagai cara untuk memisahkan sambungan dan pesan Anda ke dalam namespace layanan logis.
Model berbasis kelas
Model berbasis kelas didedikasikan untuk C#.
Model berbasis kelas memberikan pengalaman pemrograman yang lebih baik, yang dapat menggantikan pengikatan input dan output SignalR, dengan fitur-fitur berikut:
- Negosiasi yang lebih fleksibel, mengirim pesan, dan mengelola pengalaman grup.
- Fungsi pengelolaan lainnya didukung, termasuk menutup koneksi, memeriksa apakah koneksi, pengguna, atau grup ada.
- Hub yang sangat ditik
- Nama hub terpadu dan pengaturan string koneksi di satu tempat.
Kode berikut menunjukkan cara menulis pengikatan SignalR dalam model berbasis kelas:
Pertama, tentukan hub Anda yang berasal dari kelas ServerlessHub
:
[SignalRConnection("AzureSignalRConnectionString")]
public class Functions : ServerlessHub
{
private const string HubName = nameof(Functions); // Used by SignalR trigger only
public Functions(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
[Function("negotiate")]
public async Task<HttpResponseData> Negotiate([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
var negotiateResponse = await NegotiateAsync(new() { UserId = req.Headers.GetValues("userId").FirstOrDefault() });
var response = req.CreateResponse();
response.WriteBytes(negotiateResponse.ToArray());
return response;
}
[Function("Broadcast")]
public Task Broadcast(
[SignalRTrigger(HubName, "messages", "broadcast", "message")] SignalRInvocationContext invocationContext, string message)
{
return Clients.All.SendAsync("newMessage", new NewMessage(invocationContext, message));
}
[Function("JoinGroup")]
public Task JoinGroup([SignalRTrigger(HubName, "messages", "JoinGroup", "connectionId", "groupName")] SignalRInvocationContext invocationContext, string connectionId, string groupName)
{
return Groups.AddToGroupAsync(connectionId, groupName);
}
}
Dalam file Program.cs, daftarkan hub tanpa server Anda:
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(b => b.Services
.AddServerlessHub<Functions>())
.Build();
Pengalaman negosiasi dalam model berbasis kelas
Alih-alih menggunakan pengikatan [SignalRConnectionInfoInput]
input SignalR, negosiasi dalam model berbasis kelas bisa lebih fleksibel. ServerlessHub
Kelas dasar memiliki metode NegotiateAsync
, yang memungkinkan pengguna untuk menyesuaikan opsi negosiasi seperti userId
, , claims
dll.
Task<BinaryData> NegotiateAsync(NegotiationOptions? options = null)
Mengirim pesan dan mengelola pengalaman dalam model berbasis kelas
Anda dapat mengirim pesan, mengelola grup, atau mengelola klien dengan mengakses anggota yang disediakan oleh kelas ServerlessHub
dasar .
ServerlessHub.Clients
untuk mengirim pesan ke klien.ServerlessHub.Groups
untuk mengelola koneksi dengan grup, seperti menambahkan koneksi ke grup, menghapus koneksi dari grup.ServerlessHub.UserGroups
untuk mengelola pengguna dengan grup, seperti menambahkan pengguna ke grup, menghapus pengguna dari grup.ServerlessHub.ClientManager
untuk memeriksa keberadaan koneksi, menutup koneksi, dll.
Hub yang sangat ditik
Hub yang sangat ditik memungkinkan Anda menggunakan metode yang sangat ditik ketika Anda mengirim pesan ke klien. Untuk menggunakan hub yang sangat ditik dalam model berbasis kelas, ekstrak metode klien ke dalam antarmuka T
, dan buat kelas hub Anda berasal dari ServerlessHub<T>
.
Kode berikut adalah sampel antarmuka untuk metode klien.
public interface IChatClient
{
Task newMessage(NewMessage message);
}
Kemudian Anda dapat menggunakan metode yang ditik dengan kuat sebagai berikut:
[SignalRConnection("AzureSignalRConnectionString")]
public class Functions : ServerlessHub<IChatClient>
{
private const string HubName = nameof(Functions); // Used by SignalR trigger only
public Functions(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
[Function("Broadcast")]
public Task Broadcast(
[SignalRTrigger(HubName, "messages", "broadcast", "message")] SignalRInvocationContext invocationContext, string message)
{
return Clients.All.newMessage(new NewMessage(invocationContext, message));
}
}
Catatan
Anda bisa mendapatkan sampel proyek lengkap dari GitHub.
Nama hub terpadu dan pengaturan string koneksi di satu tempat
- Nama kelas hub tanpa server secara otomatis digunakan sebagai
HubName
. - Anda mungkin telah memperhatikan atribut yang
SignalRConnection
digunakan pada kelas hub tanpa server sebagai berikut:
Ini memungkinkan Anda untuk menyesuaikan di mana string koneksi untuk hub tanpa server berada. Jika tidak ada, nilai[SignalRConnection("AzureSignalRConnectionString")] public class Functions : ServerlessHub<IChatClient>
AzureSignalRConnectionString
default digunakan.
Penting
Pemicu SignalR dan hub tanpa server bersifat independen. Oleh karena itu, nama kelas hub tanpa server dan SignalRConnection
atribut tidak mengubah pengaturan pemicu SignalR, meskipun Anda menggunakan pemicu SignalR di dalam hub tanpa server.
Pengembangan klien
Aplikasi klien SignalR dapat menggunakan SDK klien SignalR dalam salah satu dari beberapa bahasa untuk terhubung dengan mudah dan menerima pesan dari Azure SignalR Service.
Mengonfigurasi sambungan klien
Untuk tersambung ke SignalR Service, klien harus menyelesaikan negosiasi sambungan berhasil yang terdiri dari langkah-langkah berikut:
- Buat permintaan ke titik akhir HTTP yang
negotiate
dibahas di atas untuk mendapatkan informasi koneksi yang valid - Koneksi ke SignalR Service menggunakan URL titik akhir layanan dan token akses yang diperoleh dari
negotiate
titik akhir
SDK klien SignalR sudah memuat logika yang diperlukan untuk melakukan handshake negosiasi. Teruskan URL titik akhir negosiasi, dikurangi negotiate
segmen, ke SDK HubConnectionBuilder
. Berikut adalah contoh di JavaScript:
const connection = new signalR.HubConnectionBuilder()
.withUrl("https://my-signalr-function-app.azurewebsites.net/api")
.build();
Berdasarkan konvensi, SDK secara otomatis menambahkan /negotiate
ke URL dan menggunakannya untuk memulai negosiasi.
Catatan
Jika Anda menggunakan JavaScript/TypeScript SDK di browser, Anda harus mengaktifkan cross-origin resource sharing (CORS) di Function App Anda.
Untuk informasi selengkapnya tentang cara menggunakan SDK klien SignalR, lihat dokumentasi untuk bahasa Anda:
Mengirim pesan dari klien ke layanan
Jika Anda telah mengonfigurasi hulu untuk sumber daya SignalR, Anda dapat mengirim pesan dari klien ke Azure Functions menggunakan klien SignalR apa pun. Berikut adalah contoh di JavaScript:
connection.send("method1", "arg1", "arg2");
Konfigurasi Azure Functions
Aplikasi Azure Function yang terintegrasi dengan Azure SignalR Service dapat digunakan seperti aplikasi Azure Function pada umumnya, menggunakan teknik seperti penyebaran terus menerus, penyebaran zip, dan dijalankan dari paket.
Namun, ada beberapa pertimbangan khusus untuk aplikasi yang menggunakan pengikatan SignalR Service. Jika klien berjalan di browser, CORS harus diaktifkan. Dan jika aplikasi memerlukan autentikasi, Anda dapat mengintegrasikan titik akhir negosiasi dengan Autentikasi App Service.
Mengaktifkan CORS
Klien JavaScript/TypeScript membuat permintaan HTTP ke fungsi negosiasi untuk memulai negosiasi koneksi. Ketika aplikasi klien dihosting di domain yang berbeda dari aplikasi Azure Function, berbagi sumber daya lintas asal (CORS) harus diaktifkan pada aplikasi fungsi, atau browser akan memblokir permintaan.
Localhost
Saat menjalankan aplikasi Function di komputer lokal, Anda dapat menambahkan bagian Host
ke local.settings.js untuk mengaktifkan CORS. Di bagian Host
tersebut, tambahkan dua properti:
CORS
- masukkan URL dasar yang merupakan asal aplikasi klienCORSCredentials
- atur ketrue
untuk mengizinkan permintaan "withCredentials"
Contoh:
{
"IsEncrypted": false,
"Values": {
// values
},
"Host": {
"CORS": "http://localhost:8080",
"CORSCredentials": true
}
}
Cloud - Azure Functions CORS
Untuk mengaktifkan CORS pada aplikasi Azure Function, buka layar konfigurasi CORS pada tab Fitur platform aplikasi Function Anda di portal Microsoft Azure.
Catatan
Konfigurasi CORS belum tersedia dalam paket Azure Functions Linux Consumption. Gunakan Azure API Management untuk mengaktifkan CORS.
CORS dengan Access-Control-Allow-Credentials harus diaktifkan agar klien SignalR memanggil fungsi negosiasi. Untuk mengaktifkannya, pilih kotak centang.
Di bagian Asal yang diizinkan, tambahkan entri dengan URL dasar asal aplikasi web Anda.
Cloud - Azure API Management
Azure API Management menyediakan gateway API yang menambahkan kemampuan ke layanan ujung belakang yang ada. Anda dapat menggunakannya untuk menambahkan CORS ke aplikasi fungsi Anda. Ini menawarkan tingkat konsumsi dengan harga bayar per tindakan dan pemberian gratis bulanan.
Lihat dokumentasi API Management untuk informasi tentang cara mengimpor aplikasi Azure Function. Setelah diimpor, Anda bisa menambahkan kebijakan masuk untuk mengaktifkan CORS dengan dukungan Access-Control-Allow-Credentials.
<cors allow-credentials="true">
<allowed-origins>
<origin>https://azure-samples.github.io</origin>
</allowed-origins>
<allowed-methods>
<method>GET</method>
<method>POST</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
<expose-headers>
<header>*</header>
</expose-headers>
</cors>
Konfigurasikan klien SignalR Anda untuk menggunakan URL API Management.
Menggunakan Autentikasi App Service
Azure Functions memiliki autentikasi bawaan, mendukung penyedia populer seperti Facebook, Twitter, Akun Microsoft, Google, dan ID Microsoft Entra. Fitur ini dapat diintegrasikan dengan SignalRConnectionInfo
pengikatan untuk membuat koneksi ke Azure SignalR Service yang diautentikasi ke ID pengguna. Aplikasi Anda dapat mengirim pesan menggunakan pengikatan output yang ditargetkan ke ID pengguna tersebut SignalR
.
Di portal Microsoft Azure, di tab Fitur platform aplikasi Fungsi buka jendela pengaturan Autentikasi/otorisasi. Ikuti dokumentasi Autentikasi App Service untuk mengonfigurasi autentikasi menggunakan penyedia identitas pilihan Anda.
Setelah dikonfigurasi, permintaan HTTP yang diautentikasi mencakup x-ms-client-principal-name
dan x-ms-client-principal-id
header yang masing-masing berisi nama pengguna dan ID pengguna identitas yang diautentikasi.
Anda dapat menggunakan header ini dalam konfigurasi pengikatan Anda SignalRConnectionInfo
untuk membuat koneksi terautentikasi. Berikut adalah contoh fungsi negosiasi C# yang menggunakan x-ms-client-principal-id
header .
[FunctionName("negotiate")]
public static SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req,
[SignalRConnectionInfo
(HubName = "chat", UserId = "{headers.x-ms-client-principal-id}")]
SignalRConnectionInfo connectionInfo)
{
// connectionInfo contains an access key token with a name identifier claim set to the authenticated user
return connectionInfo;
}
Anda lalu dapat mengirim pesan ke pengguna tersebut dengan mengatur properti UserId
pesan SignalR.
[FunctionName("SendMessage")]
public static Task SendMessage(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
[SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will only be sent to these user IDs
UserId = "userId1",
Target = "newMessage",
Arguments = new [] { message }
});
}
Untuk informasi mengenai bahasa lain, lihat pengikatan Azure SignalR Service untuk referensi Azure Functions.
Langkah berikutnya
Dalam artikel ini, Anda mempelajari cara mengembangkan dan mengonfigurasi aplikasi SignalR Service tanpa server menggunakan Azure Functions. Cobalah membuat aplikasi sendiri menggunakan salah satu mulai cepat atau tutorial di halaman ringkasan SignalR Service.