Bagikan melalui


Panduan ASP.NET SignalR Hubs API - Klien .NET (C#)

Peringatan

Dokumentasi ini bukan untuk versi terbaru SignalR. Lihat ASP.NET Core SignalR.

Dokumen ini menyediakan pengantar untuk menggunakan Hubs API untuk SignalR versi 2 di klien .NET, seperti aplikasi Windows Store (WinRT), WPF, Silverlight, dan konsol.

SIGNALR Hubs API memungkinkan Anda melakukan panggilan prosedur jarak jauh (RPC) dari server ke klien yang terhubung dan dari klien ke server. Dalam kode server, Anda menentukan metode yang dapat dipanggil oleh klien, dan Anda memanggil metode yang berjalan pada klien. Dalam kode klien, Anda menentukan metode yang dapat dipanggil dari server, dan Anda memanggil metode yang berjalan di server. SignalR mengurus semua pipa klien-ke-server untuk Anda.

SignalR juga menawarkan API tingkat bawah yang disebut Koneksi Persisten. Untuk pengenalan SignalR, Hub, dan Koneksi Persisten, atau untuk tutorial yang menunjukkan cara membangun aplikasi SignalR lengkap, lihat SignalR - Memulai.

Versi perangkat lunak yang digunakan dalam topik ini

Versi sebelumnya dari topik ini

Untuk informasi tentang versi SignalR yang lebih lama, lihat SignalR Versi Lama.

Pertanyaan dan komentar

Silakan tinggalkan umpan balik tentang bagaimana Anda menyukai tutorial ini dan apa yang dapat kami tingkatkan di komentar di bagian bawah halaman. Jika Anda memiliki pertanyaan yang tidak terkait langsung dengan tutorial, Anda dapat mempostingnya ke forum ASP.NET SignalR atau StackOverflow.com.

Gambaran Umum

Dokumen ini berisi bagian berikut:

Untuk contoh proyek klien .NET, lihat sumber daya berikut ini:

Untuk dokumentasi tentang cara memprogram server atau klien JavaScript, lihat sumber daya berikut:

Tautan ke topik Referensi API adalah ke API versi .NET 4.5. Jika Anda menggunakan .NET 4, lihat topik API versi .NET 4.

Penyiapan klien

Instal paket NuGet Microsoft.AspNet.SignalR.Client (bukan paket Microsoft.AspNet.SignalR ). Paket ini mendukung WinRT, Silverlight, WPF, aplikasi konsol, dan klien Windows Phone, untuk klien .NET 4 dan .NET 4.5.

Jika versi SignalR yang Anda miliki pada klien berbeda dari versi yang Anda miliki di server, SignalR sering dapat beradaptasi dengan perbedaan. Misalnya, server yang menjalankan SignalR versi 2 akan mendukung klien yang memiliki 1.1.x yang diinstal serta klien yang menginstal versi 2. Jika perbedaan antara versi di server dan versi pada klien terlalu bagus, atau jika klien lebih baru dari server, SignalR memberikan InvalidOperationException pengecualian ketika klien mencoba membuat koneksi. Pesan kesalahannya adalah "You are using a version of the client that isn't compatible with the server. Client version X.X, server version X.X".

Cara membuat koneksi

Sebelum dapat membuat koneksi, Anda harus membuat HubConnection objek dan membuat proksi. Untuk membuat koneksi, panggil Start metode pada HubConnection objek .

using (var hubConnection = new HubConnection("http://www.contoso.com/")) 
{
    IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
    stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
    await hubConnection.Start();
}

Catatan

Untuk klien JavaScript, Anda harus mendaftarkan setidaknya satu penanganan aktivitas sebelum memanggil Start metode untuk membuat koneksi. Ini tidak diperlukan untuk klien .NET. Untuk klien JavaScript, kode proksi yang dihasilkan secara otomatis membuat proksi untuk semua Hub yang ada di server, dan mendaftarkan handler adalah cara Anda menunjukkan Hub mana yang ingin digunakan klien Anda. Tetapi untuk klien .NET Anda membuat proksi Hub secara manual, jadi SignalR mengasumsikan bahwa Anda akan menggunakan Hub apa pun yang Anda buat proksinya.

Kode sampel menggunakan URL "/signalr" default untuk menyambungkan ke layanan SignalR Anda. Untuk informasi tentang cara menentukan URL dasar yang berbeda, lihat ASP.NET Panduan API SignalR Hubs - Server - URL /signalr.

Metode ini Start dijalankan secara asinkron. Untuk memastikan bahwa baris kode berikutnya tidak dijalankan sampai setelah koneksi dibuat, gunakan await dalam metode asinkron ASP.NET 4,5 atau .Wait() dalam metode sinkron. Jangan gunakan .Wait() di klien WinRT.

await connection.Start();
connection.Start().Wait();

Koneksi lintas domain dari klien Silverlight

Untuk informasi tentang cara mengaktifkan koneksi lintas domain dari klien Silverlight, lihat Membuat Layanan Tersedia Di Seluruh Batas Domain.

Cara mengonfigurasi koneksi

Sebelum membuat koneksi, Anda bisa menentukan salah satu opsi berikut:

  • Batas koneksi bersamaan.
  • Parameter string kueri.
  • Metode transportasi.
  • Header HTTP.
  • Sertifikat klien.

Cara mengatur jumlah maksimum koneksi bersamaan di klien WPF

Di klien WPF, Anda mungkin harus meningkatkan jumlah maksimum koneksi bersamaan dari nilai default 2. Nilai yang disarankan adalah 10.

using (var hubConnection = new HubConnection("http://www.contoso.com/"))
{
    IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
    stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
    ServicePointManager.DefaultConnectionLimit = 10;
    await hubConnection.Start();
}

Untuk informasi selengkapnya, lihat ServicePointManager.DefaultConnectionLimit.

Cara menentukan parameter string kueri

Jika Anda ingin mengirim data ke server saat klien tersambung, Anda bisa menambahkan parameter string kueri ke objek koneksi. Contoh berikut menunjukkan cara mengatur parameter string kueri dalam kode klien.

var querystringData = new Dictionary<string, string>();
querystringData.Add("contosochatversion", "1.0");
var connection = new HubConnection("http://contoso.com/", querystringData);

Contoh berikut menunjukkan cara membaca parameter string kueri dalam kode server.

public class StockTickerHub : Hub
{
    public override Task OnConnected()
    {
        var version = Context.QueryString["contosochatversion"];
        if (version != "1.0")
        {
            Clients.Caller.notifyWrongVersion();
        }
        return base.OnConnected();
    }
}

Cara menentukan metode transportasi

Sebagai bagian dari proses koneksi, klien SignalR biasanya bernegosiasi dengan server untuk menentukan transportasi terbaik yang didukung oleh server dan klien. Jika Anda sudah tahu transportasi mana yang ingin Anda gunakan, Anda dapat melewati proses negosiasi ini. Untuk menentukan metode transportasi, teruskan objek transportasi ke metode Mulai. Contoh berikut menunjukkan cara menentukan metode transportasi dalam kode klien.

using (var hubConnection = new HubConnection("http://www.contoso.com/"))
{
    IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
    stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
    await hubConnection.Start(new LongPollingTransport());
}

Namespace Microsoft.AspNet.SignalR.Client.Transports menyertakan kelas berikut yang dapat Anda gunakan untuk menentukan transportasi.

Transportasi ForeverFrame tidak termasuk dalam daftar ini karena hanya digunakan oleh browser.

Untuk informasi tentang cara memeriksa metode transportasi dalam kode server, lihat ASP.NET Panduan API SignalR Hubs - Server - Cara mendapatkan informasi tentang klien dari properti Konteks. Untuk informasi selengkapnya tentang transportasi dan fallback, lihat Pengantar SignalR - Transportasi dan Fallback.

Cara menentukan header HTTP

Untuk mengatur header HTTP, gunakan Headers properti pada objek koneksi. Contoh berikut menunjukkan cara menambahkan header HTTP.

hubConnection = new hubConnection("http://www.contoso.com/");
connection.Headers.Add("headername", "headervalue");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await connection.Start();

Cara menentukan sertifikat klien

Untuk menambahkan sertifikat klien, gunakan AddClientCertificate metode pada objek koneksi.

hubConnection = new hubConnection("http://www.contoso.com/");
hubConnection.AddClientCertificate(X509Certificate.CreateFromCertFile("MyCert.cer"));
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await connection.Start();

Cara membuat proksi Hub

Untuk menentukan metode pada klien yang dapat dipanggil Hub dari server, dan untuk memanggil metode di Hub di server, buat proksi untuk Hub dengan memanggil CreateHubProxy objek koneksi. String yang Anda berikan CreateHubProxy adalah nama kelas Hub Anda, atau nama yang ditentukan oleh HubName atribut jika string digunakan di server. Pencocokan nama tidak peka huruf besar/kecil.

Kelas hub di server

public class StockTickerHub : Hub

Membuat proksi klien untuk kelas Hub

using (var hubConnection = new HubConnection("http://www.contoso.com/"))
{
    IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
    stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
    await hubConnection.Start();
}

Jika Anda menghias kelas Hub dengan HubName atribut , gunakan nama tersebut.

Kelas hub di server

[HubName("stockTicker")]
public class StockTickerHub : Hub

Membuat proksi klien untuk kelas Hub

using (var hubConnection = new HubConnection("http://www.contoso.com/"))
{
    IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("stockTicker");
    stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
        Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
    await hubConnection.Start();
}

Jika Anda memanggil HubConnection.CreateHubProxy beberapa kali dengan yang sama hubName, Anda mendapatkan objek cache IHubProxy yang sama.

Cara menentukan metode pada klien yang dapat dipanggil server

Untuk menentukan metode yang dapat dipanggil server, gunakan metode proksi On untuk mendaftarkan penanganan aktivitas.

Pencocokan nama metode tidak peka huruf besar/kecil. Misalnya, Clients.All.UpdateStockPrice pada server akan menjalankan updateStockPrice, , updatestockpriceatau UpdateStockPrice pada klien.

Platform klien yang berbeda memiliki persyaratan yang berbeda tentang cara Anda menulis kode metode untuk memperbarui UI. Contoh yang ditampilkan adalah untuk klien WinRT (Windows Store .NET). Contoh aplikasi WPF, Silverlight, dan konsol disediakan di bagian terpisah nanti dalam topik ini.

Metode tanpa parameter

Jika metode yang Anda tangani tidak memiliki parameter, gunakan kelebihan On metode non-generik:

Kode server memanggil metode klien tanpa parameter

public class StockTickerHub : Hub
{
    public void NotifyAllClients()
    {
         Clients.All.Notify();
    }
}

Kode Klien WinRT untuk metode yang dipanggil dari server tanpa parameter (lihat contoh WPF dan Silverlight nanti dalam topik ini)

using (var hubConnection = new HubConnection("http://www.contoso.com/")) 
{
    IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
    stockTickerHub.On("notify", () =>
        // Context is a reference to SynchronizationContext.Current
        Context.Post(delegate
        {
            textBox.Text += "Notified!\n";
        }, null)
    );
    await hubConnection.Start();
}

Metode dengan parameter, menentukan jenis parameter

Jika metode yang Anda tangani memiliki parameter, tentukan jenis parameter sebagai jenis On generik metode. Ada kelebihan beban umum metode On untuk memungkinkan Anda menentukan hingga 8 parameter (4 pada Windows Phone 7). Dalam contoh berikut, satu parameter dikirim ke UpdateStockPrice metode .

Metode klien panggilan kode server dengan parameter

public void BroadcastStockPrice(Stock stock)
{
    context.Clients.Others.UpdateStockPrice(stock);
}

Kelas Stock yang digunakan untuk parameter

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

Kode Klien WinRT untuk metode yang dipanggil dari server dengan parameter (lihat contoh WPF dan Silverlight nanti dalam topik ini)

stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
    // Context is a reference to SynchronizationContext.Current
    Context.Post(delegate
    {
        textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
    }, null)
);

Metode dengan parameter, menentukan objek dinamis untuk parameter

Sebagai alternatif untuk menentukan parameter sebagai jenis On generik metode, Anda dapat menentukan parameter sebagai objek dinamis:

Metode klien panggilan kode server dengan parameter

public void BroadcastStockPrice(Stock stock)
{
    context.Clients.Others.UpdateStockPrice(stock);
}

Kelas Stock yang digunakan untuk parameter

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

Kode Klien WinRT untuk metode yang dipanggil dari server dengan parameter, menggunakan objek dinamis untuk parameter (lihat contoh WPF dan Silverlight nanti dalam topik ini)

stockTickerHubProxy.On("UpdateStockPrice", stock => 
    // Context is a reference to SynchronizationContext.Current
    Context.Post(delegate
    {
        textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
    }, null)
);

Cara menghapus handler

Untuk menghapus handler, panggil metodenya Dispose .

Kode klien untuk metode yang dipanggil dari server

var updateStockPriceHandler = stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
    Context.Post(delegate
    {
        textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
    }, null)
);

Kode klien untuk menghapus handler

updateStockPriceHandler.Dispose();

Cara memanggil metode server dari klien

Untuk memanggil metode di server, gunakan Invoke metode pada proksi Hub.

Jika metode server tidak memiliki nilai pengembalian, gunakan kelebihan Invoke metode yang tidak umum.

Kode server untuk metode yang tidak memiliki nilai pengembalian

public class StockTickerHub : Hub
{
    public void JoinGroup(string groupName)
    {
        Groups.Add(Context.ConnectionId, groupName); 
    }
}

Kode klien memanggil metode yang tidak memiliki nilai pengembalian

stockTickerHubProxy.Invoke("JoinGroup", "SignalRChatRoom");

Jika metode server memiliki nilai pengembalian, tentukan jenis pengembalian sebagai jenis Invoke generik metode.

Kode server untuk metode yang memiliki nilai pengembalian dan mengambil parameter jenis kompleks

public IEnumerable<Stock> AddStock(Stock stock)
{
    _stockTicker.AddStock(stock);
    return _stockTicker.GetAllStocks();
}

Kelas Stock yang digunakan untuk parameter dan nilai pengembalian

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

Kode klien memanggil metode yang memiliki nilai pengembalian dan mengambil parameter jenis kompleks, dalam metode asinkron ASP.NET 4,5

var stocks = await stockTickerHub.Invoke<IEnumerable<Stock>>("AddStock", new Stock() { Symbol = "MSFT" });
foreach (Stock stock in stocks)
{
    textBox.Text += string.Format("Symbol: {0} price: {1}\n", stock.Symbol, stock.Price);
}

Kode klien memanggil metode yang memiliki nilai pengembalian dan mengambil parameter jenis kompleks, dalam metode sinkron

var stocks = stockTickerHub.Invoke<IEnumerable<Stock>>("AddStock", new Stock() { Symbol = "MSFT" }).Result;
foreach (Stock stock in stocks)
{
    textBox.Text += string.Format("Symbol: {0} price: {1}\n", stock.Symbol, stock.Price);
}

Metode ini Invoke dijalankan secara asinkron dan mengembalikan Task objek. Jika Anda tidak menentukan await atau .Wait(), baris kode berikutnya akan dijalankan sebelum metode yang Anda panggil selesai dieksekusi.

Cara menangani peristiwa seumur hidup koneksi

SignalR menyediakan peristiwa seumur hidup koneksi berikut yang dapat Anda tangani:

  • Received: Dimunculkan ketika ada data yang diterima pada koneksi. Menyediakan data yang diterima.
  • ConnectionSlow: Dimunculkan saat klien mendeteksi koneksi yang lambat atau sering terputus.
  • Reconnecting: Dinaikkan ketika transportasi yang mendasar mulai terhubung kembali.
  • Reconnected: Dinaikkan ketika transportasi yang mendasar telah tersambung kembali.
  • StateChanged: Dimunculkan saat status koneksi berubah. Menyediakan status lama dan status baru. Untuk informasi tentang nilai status koneksi, lihat Enumerasi ConnectionState.
  • Closed: Dinaikkan ketika koneksi terputus.

Misalnya, jika Anda ingin menampilkan pesan peringatan untuk kesalahan yang tidak fatal tetapi menyebabkan masalah koneksi terputus-terputus, seperti lambat atau sering menghilangkan koneksi, tangani ConnectionSlow peristiwa.

hubConnection.ConnectionSlow += () => Console.WriteLine("Connection problems.");

Untuk informasi selengkapnya, lihat Memahami dan Menangani Peristiwa Seumur Hidup Koneksi di SignalR.

Cara menangani kesalahan

Jika Anda tidak secara eksplisit mengaktifkan pesan kesalahan terperinci di server, objek pengecualian yang dikembalikan SignalR setelah kesalahan berisi informasi minimal tentang kesalahan tersebut. Misalnya, jika panggilan ke newContosoChatMessage gagal, pesan kesalahan dalam objek kesalahan berisi "There was an error invoking Hub method 'contosoChatHub.newContosoChatMessage'." Mengirim pesan kesalahan terperinci ke klien dalam produksi tidak disarankan karena alasan keamanan, tetapi jika Anda ingin mengaktifkan pesan kesalahan terperinci untuk tujuan pemecahan masalah, gunakan kode berikut di server.

var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
App.MapSignalR(hubConfiguration);

Untuk menangani kesalahan yang dimunculkan SignalR, Anda dapat menambahkan handler untuk Error peristiwa pada objek koneksi.

hubConnection.Error += ex => Console.WriteLine("SignalR error: {0}", ex.Message);

Untuk menangani kesalahan dari pemanggilan metode, bungkus kode dalam blok try-catch.

try
{
    IEnumerable<Stock> stocks = await stockTickerHub.Invoke<IEnumerable<Stock>>("GetAllStocks");
    foreach (Stock stock in stocks)
    {
        Console.WriteLine("Symbol: {0} price: {1}", stock.Symbol, stock.Price);
    }
}
catch (Exception ex)
{
    Console.WriteLine("Error invoking GetAllStocks: {0}", ex.Message);
}

Cara mengaktifkan pengelogan sisi klien

Untuk mengaktifkan pengelogan sisi klien, atur TraceLevel properti dan TraceWriter pada objek koneksi.

using (var hubConnection = new HubConnection("http://www.contoso.com/"))
{
    hubConnection.TraceLevel = TraceLevels.All;
    hubConnection.TraceWriter = Console.Out;
    IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
    stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
    await hubConnection.Start();
}

Sampel kode aplikasi WPF, Silverlight, dan konsol untuk metode klien yang dapat dipanggil server

Sampel kode yang ditampilkan sebelumnya untuk menentukan metode klien yang dapat dipanggil server berlaku untuk klien WinRT. Sampel berikut menunjukkan kode yang setara untuk klien aplikasi WPF, Silverlight, dan konsol.

Metode tanpa parameter

Kode klien WPF untuk metode yang dipanggil dari server tanpa parameter

stockTickerHub.On<Stock>("notify", () =>
    Dispatcher.InvokeAsync(() =>
        {
            SignalRTextBlock.Text += string.Format("Notified!");
        })
);

Kode klien Silverlight untuk metode yang dipanggil dari server tanpa parameter

stockTickerHub.On<Stock>("notify", () =>
    // Context is a reference to SynchronizationContext.Current
    Context.Post(delegate
    {
        textBox.Text += "Notified!";
    }, null)
);

Kode klien aplikasi konsol untuk metode yang dipanggil dari server tanpa parameter

stockTickerHubProxyProxy.On("Notify", () => Console.WriteLine("Notified!"));

Metode dengan parameter, menentukan jenis parameter

Kode klien WPF untuk metode yang dipanggil dari server dengan parameter

stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
    Dispatcher.InvokeAsync(() =>
        {
            textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
        })
);

Kode klien Silverlight untuk metode yang dipanggil dari server dengan parameter

stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
    // Context is a reference to SynchronizationContext.Current
    Context.Post(delegate
    {
        textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
    }, null)
);

Kode klien aplikasi konsol untuk metode yang dipanggil dari server dengan parameter

stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => 
    Console.WriteLine("Symbol {0} Price {1}", stock.Symbol, stock.Price));

Metode dengan parameter, menentukan objek dinamis untuk parameter

Kode klien WPF untuk metode yang dipanggil dari server dengan parameter, menggunakan objek dinamis untuk parameter

stockTickerHubProxy.On("UpdateStockPrice", stock => 
    Dispatcher.InvokeAsync(() =>
        {
            textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
        })
);

Kode klien Silverlight untuk metode yang dipanggil dari server dengan parameter, menggunakan objek dinamis untuk parameter

stockTickerHubProxy.On("UpdateStockPrice", stock => 
    // Context is a reference to SynchronizationContext.Current
    Context.Post(delegate
    {
        textBox.Text += string.Format("Stock update for {0} new price {1}\n", stock.Symbol, stock.Price);
    }, null)
);

Kode klien aplikasi konsol untuk metode yang dipanggil dari server dengan parameter, menggunakan objek dinamis untuk parameter

stockTickerHubProxy.On("UpdateStockPrice", stock => 
    Console.WriteLine("Symbol {0} Price {1}", stock.Symbol, stock.Price));