ASP.NET SignalR Hubs API Kılavuzu - Sunucu (C#)

Patrick Fletcher, Tom Dykstra tarafından

Uyarı

Bu belgeler SignalR'nin en son sürümüne yönelik değildir. SignalR ASP.NET Core göz atın.

Bu belge, signalr sürüm 2 için ASP.NET SignalR Hubs API'sinin sunucu tarafını programlamaya giriş niteliğindedir ve yaygın seçenekleri gösteren kod örnekleri içerir.

SignalR Hubs API'sini kullanarak bir sunucudan bağlı istemcilere ve istemcilerden sunucuya uzaktan yordam çağrıları (RPC) yapabilirsiniz. Sunucu kodunda, istemciler tarafından çağrılabilecek yöntemleri tanımlarsınız ve istemcide çalışan yöntemleri çağırırsınız. İstemci kodunda, sunucudan çağrılabilecek yöntemleri tanımlarsınız ve sunucuda çalışan yöntemleri çağırırsınız. SignalR, istemciden sunucuya tüm tesisatı sizin için halleder.

SignalR ayrıca Kalıcı Bağlantılar adlı alt düzey bir API sunar. SignalR, Hubs ve Kalıcı Bağlantılara giriş için bkz. SignalR 2'ye giriş.

Bu konuda kullanılan yazılım sürümleri

Konu sürümleri

SignalR'nin önceki sürümleri hakkında bilgi için bkz. SignalR Eski Sürümleri.

Sorular ve yorumlar

Lütfen bu öğreticiyi nasıl beğendiğiniz ve sayfanın altındaki yorumlarda neleri geliştirebileceğimiz hakkında geri bildirim bırakın. Öğreticiyle doğrudan ilgili olmayan sorularınız varsa bunları ASP.NET SignalR forumunu veya StackOverflow.com gönderebilirsiniz.

Genel Bakış

Bu belgede aşağıdaki bölümler yer alır:

İstemcileri programlama hakkında belgeler için aşağıdaki kaynaklara bakın:

SignalR 2 için sunucu bileşenleri yalnızca .NET 4.5'te kullanılabilir. .NET 4.0 çalıştıran sunucular SignalR v1.x kullanmalıdır.

SignalR ara yazılımını kaydetme

İstemcilerin Hub'ınıza bağlanmak için kullanacağı yolu tanımlamak için, uygulama başlatıldığında yöntemini çağırın MapSignalR . MapSignalRsınıfı için OwinExtensions bir uzantı yöntemidir. Aşağıdaki örnekte, OWIN başlangıç sınıfı kullanılarak SignalR Hubs yolunun nasıl tanımlanacağı gösterilmektedir.

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }

    }
}

ASP.NET MVC uygulamasına SignalR işlevselliği ekliyorsanız SignalR yolunun diğer yollardan önce eklendiğinden emin olun. Daha fazla bilgi için bkz . Öğretici: SignalR 2 ve MVC 5'i Kullanmaya Başlama.

/signalr URL'si

Varsayılan olarak, istemcilerin Hub'ınıza bağlanmak için kullanacağı yol URL'si "/signalr" şeklindedir. (Bu URL'yi otomatik olarak oluşturulan JavaScript dosyası için "/signalr/hubs" URL'si ile karıştırmayın. Oluşturulan ara sunucu hakkında daha fazla bilgi için bkz. SignalR Hubs API Kılavuzu - JavaScript İstemcisi - Oluşturulan ara sunucu ve sizin için yaptıkları.)

Bu temel URL'yi SignalR için kullanılamaz hale getiren olağanüstü durumlar olabilir; örneğin, projenizde signalr adlı bir klasörünüz var ve adı değiştirmek istemiyorsunuz. Bu durumda, aşağıdaki örneklerde gösterildiği gibi temel URL'yi değiştirebilirsiniz (örnek koddaki "/signalr"ı istediğiniz URL ile değiştirin).

URL'yi belirten sunucu kodu

app.MapSignalR("/signalr", new HubConfiguration());

URL'yi belirten JavaScript istemci kodu (oluşturulan proxy ile)

$.connection.hub.url = "/signalr"
$.connection.hub.start().done(init);

URL'yi belirten JavaScript istemci kodu (oluşturulan ara sunucu olmadan)

var connection = $.hubConnection("/signalr", { useDefaultPath: false });

URL'yi belirten .NET istemci kodu

var hubConnection = new HubConnection("http://contoso.com/signalr", useDefaultUrl: false);

SignalR Seçeneklerini Yapılandırma

yönteminin MapSignalR aşırı yüklemeleri özel bir URL, özel bağımlılık çözümleyicisi ve aşağıdaki seçenekleri belirtmenize olanak tanır:

  • Tarayıcı istemcilerinden CORS veya JSONP kullanarak etki alanları arası çağrıları etkinleştirin.

    Genellikle tarayıcı sayfasından http://contoso.combir sayfa yüklerse SignalR bağlantısı konumundaki http://contoso.com/signalraynı etki alanındadır. sayfasındaki sayfası http://contoso.com ile http://fabrikam.com/signalrbağlantı kurarsa, bu etki alanları arası bir bağlantıdır. Güvenlik nedeniyle, etki alanları arası bağlantılar varsayılan olarak devre dışı bırakılır. Daha fazla bilgi için bkz. ASP.NET SignalR Hubs API Kılavuzu - JavaScript İstemcisi - Etki alanları arası bağlantı kurma.

  • Ayrıntılı hata iletilerini etkinleştirin.

    Hatalar oluştuğunda SignalR'nin varsayılan davranışı, istemcilere ne olduğuyla ilgili ayrıntılar olmadan bir bildirim iletisi göndermektir. Kötü amaçlı kullanıcılar bu bilgileri uygulamanıza yönelik saldırılarda kullanabileceğinden, istemcilere ayrıntılı hata bilgileri göndermek üretimde önerilmez. Sorun giderme için, daha bilgilendirici hata raporlamayı geçici olarak etkinleştirmek için bu seçeneği kullanabilirsiniz.

  • Otomatik olarak oluşturulan JavaScript proxy dosyalarını devre dışı bırakın.

    Varsayılan olarak, "/signalr/hubs" URL'sine yanıt olarak Hub sınıflarınız için proxy'leri olan bir JavaScript dosyası oluşturulur. JavaScript proxy'lerini kullanmak istemiyorsanız veya bu dosyayı el ile oluşturmak ve istemcilerinizdeki fiziksel bir dosyaya başvurmak istiyorsanız, ara sunucu oluşturmayı devre dışı bırakmak için bu seçeneği kullanabilirsiniz. Daha fazla bilgi için bkz . SignalR Hubs API Kılavuzu - JavaScript İstemcisi - SignalR tarafından oluşturulan ara sunucu için fiziksel dosya oluşturma.

Aşağıdaki örnekte SignalR bağlantı URL'sinin ve yöntemine yapılan bir çağrıda bu seçeneklerin nasıl belirtileceğini gösterilmektedir MapSignalR . Özel bir URL belirtmek için örnekteki "/signalr" yerine kullanmak istediğiniz URL'yi yazın.

var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
hubConfiguration.EnableJavaScriptProxies = false;
app.MapSignalR("/signalr", hubConfiguration);

Hub sınıflarını oluşturma ve kullanma

Hub oluşturmak için Microsoft.Aspnet.Signalr.Hub'dan türetilen bir sınıf oluşturun. Aşağıdaki örnekte, sohbet uygulaması için basit bir Hub sınıfı gösterilmektedir.

public class ContosoChatHub : Hub
{
    public async Task NewContosoChatMessage(string name, string message)
    {
        await Clients.All.addNewMessageToPage(name, message);
    }
}

Bu örnekte, bağlı bir istemci yöntemini çağırabilir NewContosoChatMessage ve çağırdığında, alınan veriler tüm bağlı istemcilere yayınlanır.

Hub nesne ömrü

Hub sınıfının örneğini oluşturmaz veya sunucudaki kendi kodunuzdan yöntemlerini çağırmazsınız; SignalR Hubs işlem hattı tarafından sizin için yapılan tüm işlemleri gerçekleştirin. SignalR, bir istemcinin bağlanması, bağlantısının kesilmesi veya sunucuya yöntem çağrısı yapması gibi bir Hub işlemini işlemesi gerektiğinde Hub sınıfınızın yeni bir örneğini oluşturur.

Hub sınıfının örnekleri geçici olduğundan, bir yöntem çağrısından diğerine durumu korumak için bunları kullanamazsınız. Sunucu bir istemciden her yöntem çağrısı aldığında, Hub sınıfınızın yeni bir örneği iletiyi işler. Birden çok bağlantı ve yöntem çağrısı aracılığıyla durumu korumak için veritabanı veya Hub sınıfındaki statik değişken gibi başka bir yöntemi ya da öğesinden Hubtüretilmeyen farklı bir sınıfı kullanın. Hub sınıfında statik değişken gibi bir yöntem kullanarak verileri bellekte kalıcı hale alırsanız, uygulama etki alanı geri dönüşüme geçtiğinde veriler kaybolur.

hub sınıfı dışında çalışan kendi kodunuzdan istemcilere ileti göndermek istiyorsanız, hub sınıfı örneğini oluşturarak bunu yapamazsınız, ancak Hub sınıfınızın SignalR bağlam nesnesine başvuru alarak bunu yapabilirsiniz. Daha fazla bilgi için, bu konunun devamında İstemci yöntemlerini çağırma ve Hub sınıfı dışından grupları yönetme konusuna bakın.

JavaScript istemcilerinde Hub adlarının camel-casing

Varsayılan olarak, JavaScript istemcileri sınıf adının camel cased sürümünü kullanarak Hubs'a başvurur. SignalR, JavaScript kodunun JavaScript kurallarına uyması için bu değişikliği otomatik olarak yapar. Önceki örnek JavaScript kodunda olarak contosoChatHub adlandırılır.

Sunucu

public class ContosoChatHub : Hub

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

var contosoChatHubProxy = $.connection.contosoChatHub;

İstemcilerin kullanması için farklı bir ad belirtmek istiyorsanız özniteliğini HubName ekleyin. Bir HubName öznitelik kullandığınızda, JavaScript istemcilerinde deve durumunda ad değişikliği olmaz.

Sunucu

[HubName("PascalCaseContosoChatHub")]
public class ContosoChatHub : Hub

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

var contosoChatHubProxy = $.connection.PascalCaseContosoChatHub;

Birden Çok Hub

Bir uygulamada birden çok Hub sınıfı tanımlayabilirsiniz. Bunu yaptığınızda, bağlantı paylaşılır ancak gruplar ayrıdır:

  • Tüm istemciler hizmetinizle bir SignalR bağlantısı ("/signalr" veya belirttiyseniz özel URL'niz) için aynı URL'yi kullanır ve bu bağlantı hizmet tarafından tanımlanan tüm Hub'lar için kullanılır.

    Tek bir sınıftaki tüm Hub işlevlerini tanımlamaya kıyasla birden çok Hub için performans farkı yoktur.

  • Tüm Hub'lar aynı HTTP isteği bilgilerini alır.

    Tüm Hub'lar aynı bağlantıyı paylaştığından, sunucunun aldığı tek HTTP isteği bilgisi SignalR bağlantısını oluşturan özgün HTTP isteğinde gelen bilgilerdir. Bir sorgu dizesi belirterek istemciden sunucuya bilgi geçirmek için bağlantı isteğini kullanırsanız, farklı Hub'lara farklı sorgu dizeleri sağlayamazsınız. Tüm Hub'lar aynı bilgileri alır.

  • Oluşturulan JavaScript proxy'leri dosyası, tek bir dosyadaki tüm Hub'lar için proxy'ler içerir.

    JavaScript proxy'leri hakkında bilgi için bkz . SignalR Hubs API Kılavuzu - JavaScript İstemcisi - Oluşturulan ara sunucu ve sizin için yaptıkları.

  • Gruplar Hub'lar içinde tanımlanır.

    SignalR'de, bağlı istemcilerin alt kümelerine yayın yapmak için adlandırılmış gruplar tanımlayabilirsiniz. Gruplar her Merkez için ayrı ayrı tutulur. Örneğin, "Administrators" adlı bir grup sınıfınız ContosoChatHub için bir istemci kümesi içerir ve aynı grup adı sınıfınız StockTickerHub için farklı bir istemci kümesine başvurur.

Strongly-Typed Hub'ları

İstemcinizin başvurabileceği (ve hub yöntemlerinizde IntelliSense'i etkinleştirebilen) hub yöntemleriniz için bir arabirim tanımlamak için, hub'ınızı yerine öğesinden Hub<T> (SignalR 2.1'de kullanıma sunulmuştur) Hubtüretin:

public class StrongHub : Hub<IClient>
{
    public async Task Send(string message)
    {
        await Clients.All.NewMessage(message);
    }
}

public interface IClient
{
    Task NewMessage(string message);
}

Hub sınıfında istemcilerin çağırabileceği yöntemleri tanımlama

Hub'da istemciden çağrılmasını istediğiniz bir yöntemi kullanıma açmak için, aşağıdaki örneklerde gösterildiği gibi genel bir yöntem bildirin.

public class ContosoChatHub : Hub
{
    public async Task NewContosoChatMessage(string name, string message)
    {
        await Clients.All.addNewMessageToPage(name, message);
    }
}
public class StockTickerHub : Hub
{
    public IEnumerable<Stock> GetAllStocks()
    {
        return _stockTicker.GetAllStocks();
    }
}

Herhangi bir C# yönteminde olduğu gibi karmaşık türler ve diziler de dahil olmak üzere bir dönüş türü ve parametreleri belirtebilirsiniz. Parametrelerde aldığınız veya çağırana geri döndürdüğünüz tüm veriler, istemci ile sunucu arasında JSON kullanılarak iletilir ve SignalR karmaşık nesnelerin ve nesne dizilerinin bağlamasını otomatik olarak işler.

JavaScript istemcilerinde yöntem adlarının camel-casing

Varsayılan olarak JavaScript istemcileri, yöntem adının camel cased sürümünü kullanarak Hub yöntemlerine başvurur. SignalR, JavaScript kodunun JavaScript kurallarına uyması için bu değişikliği otomatik olarak yapar.

Sunucu

public void NewContosoChatMessage(string userName, string message)

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

contosoChatHubProxy.server.newContosoChatMessage(userName, message);

İstemcilerin kullanması için farklı bir ad belirtmek istiyorsanız özniteliğini HubMethodName ekleyin.

Sunucu

[HubMethodName("PascalCaseNewContosoChatMessage")]
public void NewContosoChatMessage(string userName, string message)

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

contosoChatHubProxy.server.PascalCaseNewContosoChatMessage(userName, message);

Zaman uyumsuz olarak ne zaman yürütülür?

Yöntem uzun süre çalışacaksa veya veritabanı araması veya web hizmeti çağrısı gibi beklemeyi kapsayan bir iş yapması gerekiyorsa, Bir Görev (dönüş yerine void ) veya Görev<T> nesnesi (dönüş türü yerine T ) döndürerek Hub yöntemini zaman uyumsuz hale getirin. yönteminden bir Task nesne döndürdiğinizde SignalR, öğesinin Task tamamlanmasını bekler ve ardından açılmamış sonucu istemciye geri gönderir, bu nedenle istemcide yöntem çağrısını kodlarken hiçbir fark yoktur.

Hub yönteminin zaman uyumsuz hale getirilmesi, WebSocket aktarımını kullandığında bağlantıyı engellemeyi önler. Hub yöntemi zaman uyumlu olarak yürütür ve aktarım WebSocket olduğunda, Hub yöntemi tamamlanana kadar hub'daki yöntemlerin aynı istemciden sonraki çağrıları engellenir.

Aşağıdaki örnek, zaman uyumlu veya zaman uyumsuz olarak çalıştırmak için kodlanmış yöntemin aynısını ve ardından her iki sürümü çağırmak için çalışan JavaScript istemci kodunu gösterir.

Zaman Uyumlu

public IEnumerable<Stock> GetAllStocks()
{
    // Returns data from memory.
    return _stockTicker.GetAllStocks();
}

Zaman uyumsuz

public async Task<IEnumerable<Stock>> GetAllStocks()
{
    // Returns data from a web service.
    var uri = Util.getServiceUri("Stocks");
    using (HttpClient httpClient = new HttpClient())
    {
        var response = await httpClient.GetAsync(uri);
        return (await response.Content.ReadAsAsync<IEnumerable<Stock>>());
    }
}

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

stockTickerHubProxy.server.getAllStocks().done(function (stocks) {
    $.each(stocks, function () {
        alert(this.Symbol + ' ' + this.Price);
    });
});

ASP.NET 4.5'te zaman uyumsuz yöntemleri kullanma hakkında daha fazla bilgi için bkz. ASP.NET MVC 4'te Zaman Uyumsuz Yöntemleri Kullanma.

Aşırı Yüklemeleri Tanımlama

Bir yöntem için aşırı yüklemeler tanımlamak istiyorsanız, her aşırı yüklemedeki parametre sayısı farklı olmalıdır. Bir aşırı yüklemeyi yalnızca farklı parametre türleri belirterek ayırt ederseniz, Hub sınıfınız derlenir, ancak SignalR hizmeti istemciler aşırı yüklemelerden birini çağırmaya çalıştığında çalışma zamanında bir özel durum oluşturur.

Hub yöntemi çağrılarından ilerleme durumunu raporlama

SignalR 2.1, .NET 4.5'te sunulan ilerleme durumu raporlama düzeni için destek ekler. İlerleme raporlaması uygulamak için, istemcinizin erişebileceği hub yönteminiz için bir IProgress<T> parametre tanımlayın:

public class ProgressHub : Hub
{
    public async Task<string> DoLongRunningThing(IProgress<int> progress)
    {
        for (int i = 0; i <= 100; i+=5)
        {
            await Task.Delay(200);
            progress.Report(i);
        }
        return "Job complete!";
    }
}

Uzun süre çalışan bir sunucu yöntemi yazarken, hub iş parçacığını engellemek yerine Async/ Await gibi zaman uyumsuz bir programlama deseni kullanmak önemlidir.

Hub sınıfından istemci yöntemlerini çağırma

Sunucudan istemci yöntemlerini çağırmak için Hub sınıfınızdaki bir yöntemde özelliğini kullanın Clients . Aşağıdaki örnekte, tüm bağlı istemcileri çağıran addNewMessageToPage sunucu kodu ve JavaScript istemcisinde yöntemini tanımlayan istemci kodu gösterilmektedir.

Sunucu

public class ContosoChatHub : Hub
{
    public async Task NewContosoChatMessage(string name, string message)
    {
        await Clients.All.addNewMessageToPage(name, message);
    }
}

İstemci yöntemini çağırmak zaman uyumsuz bir işlemdir ve döndürür Task. await kullanın:

  • İletinin hatasız gönderilmesini sağlamak için.
  • Bir try-catch bloğundaki hataları yakalamayı ve işlemeyi etkinleştirmek için.

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

contosoChatHubProxy.client.addNewMessageToPage = function (name, message) {
    // Add the message to the page. 
    $('#discussion').append('<li><strong>' + htmlEncode(name)
        + '</strong>: ' + htmlEncode(message) + '<li>');
};

İstemci yönteminden dönüş değeri alamazsınız; gibi int x = Clients.All.add(1,1) söz dizimi çalışmıyor.

Parametreler için karmaşık türler ve diziler belirtebilirsiniz. Aşağıdaki örnek, bir yöntem parametresinde istemciye karmaşık bir tür geçirir.

Karmaşık bir nesne kullanarak istemci yöntemini çağıran sunucu kodu

public async Task SendMessage(string name, string message)
{
    await Clients.All.addContosoChatMessageToPage(new ContosoChatMessage() { UserName = name, Message = message });
}

Karmaşık nesneyi tanımlayan sunucu kodu

public class ContosoChatMessage
{
    public string UserName { get; set; }
    public string Message { get; set; }
}

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addMessageToPage = function (message) {
    console.log(message.UserName + ' ' + message.Message);
});

RPC'yi alacak istemcileri seçme

clients özelliği, RPC'yi alacak istemcileri belirtmek için çeşitli seçenekler sağlayan bir HubConnectionContext nesnesi döndürür:

  • Tüm bağlı istemciler.

    Clients.All.addContosoChatMessageToPage(name, message);
    
  • Yalnızca çağıran istemci.

    Clients.Caller.addContosoChatMessageToPage(name, message);
    
  • Çağıran istemci dışındaki tüm istemciler.

    Clients.Others.addContosoChatMessageToPage(name, message);
    
  • Bağlantı kimliğiyle tanımlanan belirli bir istemci.

    Clients.Client(Context.ConnectionId).addContosoChatMessageToPage(name, message);
    

    Bu örnek, çağıran istemciyi çağırır addContosoChatMessageToPage ve ile Clients.Calleraynı etkiye sahiptir.

  • Bağlantı kimliğiyle tanımlanan belirtilen istemciler dışındaki tüm bağlı istemciler.

    Clients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    
  • Belirtilen gruptaki tüm bağlı istemciler.

    Clients.Group(groupName).addContosoChatMessageToPage(name, message);
    
  • Bağlantı kimliğiyle tanımlanan belirtilen istemciler dışında, belirtilen gruptaki tüm bağlı istemciler.

    Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    
  • Belirtilen gruptaki çağıran istemci dışındaki tüm bağlı istemciler.

    Clients.OthersInGroup(groupName).addContosoChatMessageToPage(name, message);
    
  • UserId ile tanımlanan belirli bir kullanıcı.

    Clients.User(userid).addContosoChatMessageToPage(name, message);
    

    Varsayılan olarak, bu şeklindedir IPrincipal.Identity.Name, ancak bu, IUserIdProvider uygulamasını genel ana bilgisayara kaydederek değiştirilebilir.

  • Bağlantı kimlikleri listesindeki tüm istemciler ve gruplar.

    Clients.Clients(ConnectionIds).broadcastMessage(name, message);
    
  • Grupların listesi.

    Clients.Groups(GroupIds).broadcastMessage(name, message);
    
  • Ada göre bir kullanıcı.

    Clients.Client(username).broadcastMessage(name, message);
    
  • Kullanıcı adlarının listesi (SignalR 2.1'de tanıtıldı).

    Clients.Users(new string[] { "myUser", "myUser2" }).broadcastMessage(name, message);
    

Yöntem adları için derleme zamanı doğrulaması yok

Belirttiğiniz yöntem adı dinamik bir nesne olarak yorumlanır; başka bir deyişle bu nesne için IntelliSense veya derleme zamanı doğrulaması yoktur. İfade çalışma zamanında değerlendirilir. Yöntem çağrısı yürütürken SignalR yöntem adını ve parametre değerlerini istemciye gönderir ve istemcinin adıyla eşleşen bir yöntemi varsa, bu yöntem çağrılır ve parametre değerleri bu yönteme geçirilir. İstemcide eşleşen bir yöntem bulunamazsa hata oluşmaz. Bir istemci yöntemini çağırdığınızda SignalR'nin arka planda istemciye ilettiği verilerin biçimi hakkında bilgi için bkz . SignalR'ye Giriş.

Büyük/küçük harfe duyarsız yöntem adı eşleştirme

Yöntem adı eşleştirme büyük/küçük harfe duyarlı değildir. Örneğin, Clients.All.addContosoChatMessageToPage sunucuda , addcontosochatmessagetopageveya addContosoChatMessageToPage istemcisinde yürütülürAddContosoChatMessageToPage.

Zaman uyumsuz yürütme

Çağırdığınız yöntem zaman uyumsuz olarak yürütülür. Bir istemciye yöntem çağrısından sonra gelen tüm kodlar, sonraki kod satırlarının yöntemin tamamlanmasını beklemesi gerektiğini belirtmediğiniz sürece SignalR'nin istemcilere veri iletmeyi bitirmesini beklemeden hemen yürütülür. Aşağıdaki kod örneği, iki istemci yönteminin sırayla nasıl yürütüleceklerini gösterir.

Await Kullanma (.NET 4.5)

public async Task NewContosoChatMessage(string name, string message)
{
    await Clients.Others.addContosoChatMessageToPage(data);
    await Clients.Caller.notifyMessageSent();
}

Bir sonraki kod satırı yürütülmeden önce bir istemci yönteminin bitmesini beklemek için kullanırsanız await , bu istemcilerin bir sonraki kod satırı yürütülmeden önce iletiyi alacağı anlamına gelmez. bir istemci yöntemi çağrısının "tamamlanması" yalnızca SignalR'nin iletiyi göndermek için gereken her şeyi yaptığı anlamına gelir. İstemcilerin iletiyi aldığını doğrulamanız gerekiyorsa, bu mekanizmayı kendiniz programlamanız gerekir. Örneğin, Hub'da bir MessageReceived yöntem kodlayabilir ve istemcideki yönteminde addContosoChatMessageToPage , istemcide yapmanız gereken her işi yaptıktan sonra çağırabilirsiniz MessageReceived . Hub'da MessageReceived gerçek istemci alımına ve özgün yöntem çağrısının işlenmesine bağlı olan her işi yapabilirsiniz.

Yöntem adı olarak dize değişkeni kullanma

Yöntem adı olarak bir dize değişkeni kullanarak bir istemci yöntemini çağırmak istiyorsanız, öğesine (veya Clients.Others, Clients.Callervb.) IClientProxy ve Clients.All ardından Invoke(methodName, args...) öğesini çağırın.

public async Task NewContosoChatMessage(string name, string message)
{
    string methodToCall = "addContosoChatMessageToPage";
    IClientProxy proxy = Clients.All;
    await proxy.Invoke(methodToCall, name, message);
}

Hub sınıfından grup üyeliğini yönetme

SignalR'deki gruplar, bağlı istemcilerin belirtilen alt kümelerine ileti yayınlamak için bir yöntem sağlar. Bir grubun herhangi bir sayıda istemcisi olabilir ve bir istemci herhangi bir sayıda grubun üyesi olabilir.

Grup üyeliğini yönetmek için Hub sınıfının özelliği tarafından Groups sağlanan Add ve Remove yöntemlerini kullanın. Aşağıdaki örnek, istemci kodu tarafından çağrılan Hub yöntemlerinde kullanılan ve Groups.Remove yöntemlerini ve ardından bunları çağıran JavaScript istemci kodunu gösterirGroups.Add.

Sunucu

public class ContosoChatHub : Hub
{
    public Task JoinGroup(string groupName)
    {
        return Groups.Add(Context.ConnectionId, groupName);
    }

    public Task LeaveGroup(string groupName)
    {
        return Groups.Remove(Context.ConnectionId, groupName);
    }
}

Oluşturulan ara sunucuyu kullanan JavaScript istemcisi

contosoChatHubProxy.server.joinGroup(groupName);
contosoChatHubProxy.server.leaveGroup(groupName);

Grupları açıkça oluşturmanız gerekmez. Aslında bir grup, çağrısında adını ilk kez belirttiğinizde Groups.Addotomatik olarak oluşturulur ve içindeki üyelikten son bağlantıyı kaldırdığınızda silinir.

Grup üyeliği listesi veya grup listesi almak için API yoktur. SignalR, istemcilere ve gruplara pub/sub modelini temel alan iletiler gönderir ve sunucu grup veya grup üyeliği listelerini korumaz. Bu, web grubuna her düğüm eklediğinizde SignalR'nin koruduğu herhangi bir durumun yeni düğüme yayılması gerektiğinden ölçeklenebilirliği en üst düzeye çıkarmaya yardımcı olur.

Add ve Remove yöntemlerinin zaman uyumsuz yürütülmesi

Groups.Add ve Groups.Remove yöntemleri zaman uyumsuz olarak yürütülür. Gruba bir istemci eklemek ve grubu kullanarak istemciye hemen bir ileti göndermek istiyorsanız, önce yöntemin tamamlandığından Groups.Add emin olmanız gerekir. Aşağıdaki kod örneği bunun nasıl yapılacağını gösterir.

Gruba istemci ekleme ve ardından bu istemciye ileti gönderme

public async Task JoinGroup(string groupName)
{
    await Groups.Add(Context.ConnectionId, groupName);
    await Clients.Group(groupname).addContosoChatMessageToPage(Context.ConnectionId + " added to group");
}

Grup üyeliği kalıcılığı

SignalR, kullanıcıları değil bağlantıları izler. Bu nedenle, bir kullanıcının her bağlantı kurduğunda aynı grupta olmasını istiyorsanız, kullanıcı her yeni bağlantı kurduğunda aramanız Groups.Add gerekir.

Geçici bir bağlantı kaybından sonra SignalR bazen bağlantıyı otomatik olarak geri yükleyebilir. Bu durumda SignalR aynı bağlantıyı geri yükler, yeni bir bağlantı kurmaz ve bu nedenle istemcinin grup üyeliği otomatik olarak geri yüklenir. Grup üyelikleri de dahil olmak üzere her istemci için bağlantı durumu istemciye yuvarlandığından, geçici kesme sunucu yeniden başlatma veya hata sonucu olduğunda bile bu mümkündür. Bir sunucu kapanırsa ve bağlantı zaman aşımına uğramadan önce yeni bir sunucuyla değiştirilirse, istemci yeni sunucuya otomatik olarak yeniden bağlanabilir ve üyesi olduğu gruplara yeniden kaydolabilir.

Bağlantı kesildikten sonra bağlantı otomatik olarak geri yüklenemediyse veya bağlantı zaman aşımına uğradıysa ya da istemci bağlantısı kesildiğinde (örneğin, bir tarayıcı yeni bir sayfaya gittiğinde), grup üyelikleri kaybolur. Kullanıcının bir sonraki bağlantısı yeni bir bağlantı olacaktır. Aynı kullanıcı yeni bir bağlantı kurduğunda grup üyeliklerini korumak için uygulamanızın kullanıcılar ve gruplar arasındaki ilişkileri izlemesi ve bir kullanıcı her yeni bağlantı kurduğunda grup üyeliklerini geri yüklemesi gerekir.

Bağlantılar ve yeniden bağlantılar hakkında daha fazla bilgi için, bu konunun devamında Hub sınıfında bağlantı ömrü olaylarını işleme konusuna bakın.

Tek kullanıcılı gruplar

SignalR kullanan uygulamaların genellikle hangi kullanıcının ileti gönderdiğini ve hangi kullanıcıların ileti alması gerektiğini bilmek için kullanıcılar ve bağlantılar arasındaki ilişkileri izlemesi gerekir. Gruplar, bunu yapmak için yaygın olarak kullanılan iki desenden birinde kullanılır.

  • Tek kullanıcılı gruplar.

    Grup adı olarak kullanıcı adını belirtebilir ve kullanıcı her bağlandığında veya yeniden bağlandığında geçerli bağlantı kimliğini gruba ekleyebilirsiniz. Gruba gönderdiğiniz kullanıcıya ileti göndermek için. Bu yöntemin bir dezavantajı, grubun size kullanıcının çevrimiçi mi yoksa çevrimdışı mı olduğunu öğrenmeniz için bir yol sağlamamasıdır.

  • Kullanıcı adları ve bağlantı kimlikleri arasındaki ilişkilendirmeleri izleyin.

    Her kullanıcı adı ve bir veya daha fazla bağlantı kimliği arasındaki ilişkiyi bir sözlükte veya veritabanında depolayabilir ve kullanıcı her bağlandığında veya bağlantısını kestiğinde depolanan verileri güncelleştirebilirsiniz. Kullanıcıya ileti göndermek için bağlantı kimliklerini belirtirsiniz. Bu yöntemin dezavantajı daha fazla bellek almasıdır.

Hub sınıfında bağlantı ömrü olaylarını işleme

Bağlantı ömrü olaylarını işlemenin tipik nedenleri, kullanıcının bağlı olup olmadığını izlemek ve kullanıcı adları ile bağlantı kimlikleri arasındaki ilişkiyi izlemektir. İstemciler bağlandığında veya bağlantıyı kestiğinde kendi kodunuzu çalıştırmak için, aşağıdaki örnekte gösterildiği gibi Hub sınıfının , OnDisconnectedve OnReconnected sanal yöntemlerini geçersiz kılınOnConnected.

public class ContosoChatHub : Hub
{
    public override Task OnConnected()
    {
        // Add your own code here.
        // For example: in a chat application, record the association between
        // the current connection ID and user name, and mark the user as online.
        // After the code in this method completes, the client is informed that
        // the connection is established; for example, in a JavaScript client,
        // the start().done callback is executed.
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        // Add your own code here.
        // For example: in a chat application, mark the user as offline, 
        // delete the association between the current connection id and user name.
        return base.OnDisconnected(stopCalled);
    }

    public override Task OnReconnected()
    {
        // Add your own code here.
        // For example: in a chat application, you might have marked the
        // user as offline after a period of inactivity; in that case 
        // mark the user as online again.
        return base.OnReconnected();
    }
}

OnConnected, OnDisconnected ve OnReconnected çağrıldığında

Bir tarayıcı yeni bir sayfaya her gidildiğinde yeni bir bağlantı kurulması gerekir; bu da SignalR'nin yöntemi ve ardından OnConnected yöntemini yürüteceği OnDisconnected anlamına gelir. SignalR, yeni bir bağlantı kurulduğunda her zaman yeni bir bağlantı kimliği oluşturur.

Bağlantı OnReconnected zaman aşımına uğramadan önce bir kablonun geçici olarak bağlantısının kesilmesi ve yeniden bağlanması gibi SignalR'nin otomatik olarak kurtarabileceği geçici bir bağlantı kesintisi olduğunda yöntemi çağrılır. OnDisconnected İstemcinin bağlantısı kesildiğinde ve tarayıcı yeni bir sayfaya gittiği zaman gibi SignalR otomatik olarak yeniden bağlanamayınca yöntemi çağrılır. Bu nedenle, belirli bir istemci için olası bir olay dizisi , OnReconnected, OnDisconnected; veya OnConnected, OnDisconnectedşeklindedirOnConnected. Belirli bir bağlantı için , OnDisconnectedOnReconnected dizisini OnConnectedgörmezsiniz.

Bir sunucunun OnDisconnected kapanması veya Uygulama Etki Alanının geri dönüştürülmesi gibi bazı senaryolarda yöntemi çağrılmıyor. Başka bir sunucu hatta geldiğinde veya Uygulama Etki Alanı geri dönüşümünü tamamladığında, bazı istemciler olayı yeniden bağlayıp tetikleyebiliyor OnReconnected olabilir.

Daha fazla bilgi için bkz. SignalR'de Bağlantı Ömrü Olaylarını Anlama ve İşleme.

Arayan durumu doldurulmadı

Bağlantı ömrü olay işleyici yöntemleri sunucudan çağrılır; başka bir deyişle istemcideki nesneye state yerleştirdiğiniz herhangi bir durum sunucudaki özelliğinde Caller doldurulmayacaktır. Nesnesi ve özelliği hakkında state bilgi için, bu konunun devamında İstemciler ile Hub sınıfı arasında durum geçirme konusuna bakın.Caller

Context özelliğinden istemci hakkında bilgi alma

İstemci hakkında bilgi almak için Hub sınıfının özelliğini kullanın Context . özelliği, Context aşağıdaki bilgilere erişim sağlayan bir HubCallerContext nesnesi döndürür:

  • Çağıran istemcinin bağlantı kimliği.

    string connectionID = Context.ConnectionId;
    

    Bağlantı kimliği SignalR tarafından atanan bir GUID'dir (değeri kendi kodunuzda belirtemezsiniz). Her bağlantı için bir bağlantı kimliği vardır ve uygulamanızda birden çok Hub varsa tüm Hub'lar tarafından aynı bağlantı kimliği kullanılır.

  • HTTP üst bilgi verileri.

    System.Collections.Specialized.NameValueCollection headers = Context.Request.Headers;
    

    HTTP üst bilgilerini adresinden Context.Headersde alabilirsiniz. Aynı şeye Context.Headers birden çok başvurunun nedeni, önce oluşturulmuş olması, özelliğin Context.Request daha sonra eklenmesi ve Context.Headers geriye dönük uyumluluk için korunmasıdır.

  • Sorgu dizesi verileri.

    System.Collections.Specialized.NameValueCollection queryString = Context.Request.QueryString;
    string parameterValue = queryString["parametername"]
    

    Sorgu dizesi verilerini 'den Context.QueryStringde alabilirsiniz.

    Bu özellikte elde ettiğiniz sorgu dizesi, SignalR bağlantısını oluşturan HTTP isteğiyle kullanılan dizedir. bağlantıyı yapılandırarak istemciye sorgu dizesi parametreleri ekleyebilirsiniz. Bu, istemci hakkındaki verileri istemciden sunucuya geçirmenin kullanışlı bir yoludur. Aşağıdaki örnekte, oluşturulan ara sunucuyu kullandığınızda JavaScript istemcisine sorgu dizesi eklemenin bir yolu gösterilmektedir.

    $.connection.hub.qs = { "version" : "1.0" };
    

    Sorgu dizesi parametrelerini ayarlama hakkında daha fazla bilgi için JavaScript ve .NET istemcileri için API kılavuzlarına bakın.

    Bağlantı için kullanılan aktarım yöntemini sorgu dizesi verilerinde ve SignalR tarafından dahili olarak kullanılan bazı diğer değerlerde bulabilirsiniz:

    string transportMethod = queryString["transport"];
    

    değeri transportMethod "webSockets", "serverSentEvents", "foreverFrame" veya "longPolling" olur. Olay işleyici yönteminde OnConnected bu değeri denetlerseniz, bazı senaryolarda başlangıçta bağlantı için son anlaşmalı aktarım yöntemi olmayan bir aktarım değeri alabileceğinizi unutmayın. Bu durumda yöntem bir özel durum oluşturur ve son aktarım yöntemi oluşturulduğunda daha sonra yeniden çağrılır.

  • Kurabiye.

    System.Collections.Generic.IDictionary<string, Cookie> cookies = Context.Request.Cookies;
    

    Tanımlama bilgilerini adresinden Context.RequestCookiesde alabilirsiniz.

  • Kullanıcı bilgileri.

    System.Security.Principal.IPrincipal user = Context.User;
    
  • İsteğin HttpContext nesnesi:

    System.Web.HttpContextBase httpContext = Context.Request.GetHttpContext();
    

    SignalR bağlantısı için nesnesini almak HttpContext.CurrentHttpContext yerine bu yöntemi kullanın.

İstemciler ile Hub sınıfı arasında durum geçirme

İstemci proxy'si, her yöntem çağrısıyla sunucuya iletilmesini istediğiniz verileri depolayabileceğiniz bir state nesne sağlar. Sunucuda, istemciler tarafından çağrılan Hub yöntemlerindeki özelliğinde bu verilere Clients.Caller erişebilirsiniz. Clients.Caller özelliği , OnDisconnectedve OnReconnectedbağlantı ömrü olay işleyici yöntemleri OnConnectediçin doldurulmadı.

nesnesinde state veri oluşturma veya güncelleştirme ve Clients.Caller özelliği her iki yönde de çalışır. Sunucudaki değerleri güncelleştirebilirsiniz ve bunlar istemciye geri geçirilir.

Aşağıdaki örnekte, her yöntem çağrısıyla sunucuya iletim durumunu depolayan JavaScript istemci kodu gösterilmektedir.

contosoChatHubProxy.state.userName = "Fadi Fakhouri";
contosoChatHubProxy.state.computerName = "fadivm1";

Aşağıdaki örnekte bir .NET istemcisindeki eşdeğer kod gösterilmektedir.

contosoChatHubProxy["userName"] = "Fadi Fakhouri";
chatHubProxy["computerName"] = "fadivm1";

Hub sınıfınızda bu verilere özelliğinden Clients.Caller erişebilirsiniz. Aşağıdaki örnekte, önceki örnekte başvuruda bulunılan durumu alan kod gösterilmektedir.

public async Task NewContosoChatMessage(string data)
{
    string userName = Clients.Caller.userName;
    string computerName = Clients.Caller.computerName;
    await Clients.Others.addContosoChatMessageToPage(message, userName, computerName);
}

Not

Veya Clients.Caller özelliğine yerleştirdiğiniz state her şey her yöntem çağrısıyla yuvarlandığından, durumu kalıcı hale getiren bu mekanizma büyük miktarda veri için tasarlanmamıştır. Kullanıcı adları veya sayaçlar gibi daha küçük öğeler için kullanışlıdır.

VB.NET veya kesin olarak belirlenmiş bir hub'da çağıran durum nesnesine üzerinden erişilemiyor Clients.Caller; bunun yerine kullanın Clients.CallerState (SignalR 2.1'de tanıtıldı):

C'de CallerState Kullanma#

public async Task NewContosoChatMessage(string data)
{
    string userName = Clients.CallerState.userName;
    string computerName = Clients.CallerState.computerName;
    await Clients.Others.addContosoChatMessageToPage(data, userName, computerName);
}

Visual Basic'te CallerState Kullanma

Public Async Function NewContosoChatMessage(message As String) As Task
    Dim userName As String = Clients.CallerState.userName
    Dim computerName As String = Clients.CallerState.computerName
    Await Clients.Others.addContosoChatMessageToPage(message, userName, computerName)
End Sub

Hub sınıfında hataları işleme

Hub sınıf yöntemlerinizde oluşan hataları işlemek için öncelikle kullanarak awaitzaman uyumsuz işlemlerden (istemci yöntemlerini çağırma gibi) gelen özel durumları "gözlemlediğinizden" emin olun. Ardından aşağıdaki yöntemlerden birini veya daha fazlasını kullanın:

  • Yöntem kodunuzu try-catch bloklarında sarmalayın ve özel durum nesnesini günlüğe yazın. Hata ayıklama amacıyla özel durumu istemciye gönderebilirsiniz, ancak güvenlik nedeniyle üretim ortamındaki istemcilere ayrıntılı bilgi gönderilmesi önerilmez.

  • OnIncomingError yöntemini işleyen bir Hubs işlem hattı modülü oluşturun. Aşağıdaki örnekte hataları günlüğe kaydeden bir işlem hattı modülü ve ardından Startup.cs dosyasındaki kodun modülü Hubs işlem hattına eklemesi gösterilmektedir.

    public class ErrorHandlingPipelineModule : HubPipelineModule
    {
        protected override void OnIncomingError(ExceptionContext exceptionContext, IHubIncomingInvokerContext invokerContext)
        {
            Debug.WriteLine("=> Exception " + exceptionContext.Error.Message);
            if (exceptionContext.Error.InnerException != null)
            {
                Debug.WriteLine("=> Inner Exception " + exceptionContext.Error.InnerException.Message);
            }
            base.OnIncomingError(exceptionContext, invokerContext);
    
        }
    }
    
    public void Configuration(IAppBuilder app)
    {
        // Any connection or hub wire up and configuration should go here
        GlobalHost.HubPipeline.AddModule(new ErrorHandlingPipelineModule()); 
        app.MapSignalR();
    }
    
  • sınıfını HubException kullanın (SignalR 2'de tanıtıldı). Bu hata herhangi bir hub çağrısından oluşturulabilir. Oluşturucu HubError bir dize iletisi ve ek hata verilerini depolamak için bir nesne alır. SignalR, özel durumu otomatik olarak seri hale getirerek istemciye gönderir; burada hub yöntemi çağrısını reddetmek veya başarısız olmak için kullanılır.

    Aşağıdaki kod örnekleri, Hub çağrısı sırasında bir HubException oluşturma işleminin nasıl yapılacağını ve JavaScript ve .NET istemcilerinde özel durumun nasıl işlendiğini gösterir.

    HubException sınıfını gösteren sunucu kodu

    public class MyHub : Hub
    {
        public async Task Send(string message)
        {
            if(message.Contains("<script>"))
            {
                throw new HubException("This message will flow to the client", new { user = Context.User.Identity.Name, message = message });
            }
    
            await Clients.All.send(message);
        }
    }
    

    Hub'da HubException oluşturma yanıtlarını gösteren JavaScript istemci kodu

    myHub.server.send("<script>")
                .fail(function (e) {
                    if (e.source === 'HubException') {
                        console.log(e.message + ' : ' + e.data.user);
                    }
                });
    

    Hub'da HubException oluşturma yanıtlarını gösteren .NET istemci kodu

    try
    {
        await myHub.Invoke("Send", "<script>");
    }
    catch(HubException ex)
    {
        Console.WriteLine(ex.Message);
    }
    

Hub işlem hattı modülleri hakkında daha fazla bilgi için bu konunun devamında Yer alan Hubs işlem hattını özelleştirme bölümüne bakın.

İzlemeyi etkinleştirme

Sunucu tarafı izlemeyi etkinleştirmek için, bu örnekte gösterildiği gibi Web.config dosyanıza bir system.diagnostics öğesi ekleyin:

<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="SignalRSamples" connectionString="Data Source=(local);Initial Catalog=SignalRSamples;Integrated Security=SSPI;Asynchronous Processing=True;" />
    <add name="SignalRSamplesWithMARS" connectionString="Data Source=(local);Initial Catalog=SignalRSamples;Integrated Security=SSPI;Asynchronous Processing=True;MultipleActiveResultSets=true;" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
  <system.diagnostics>
    <sources>
      <source name="SignalR.SqlMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
     <source name="SignalR.ServiceBusMessageBus">
        <listeners>
            <add name="SignalR-Bus" />
        </listeners>
     </source>
     <source name="SignalR.ScaleoutMessageBus">
        <listeners>
            <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.Transports.WebSocketTransport">
        <listeners>
          <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.Transports.ServerSentEventsTransport">
          <listeners>
              <add name="SignalR-Transports" />
          </listeners>
      </source>
      <source name="SignalR.Transports.ForeverFrameTransport">
          <listeners>
              <add name="SignalR-Transports" />
          </listeners>
      </source>
      <source name="SignalR.Transports.LongPollingTransport">
        <listeners>
            <add name="SignalR-Transports" />
        </listeners>
      </source>
      <source name="SignalR.Transports.TransportHeartBeat">
        <listeners>
            <add name="SignalR-Transports" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="SignalRSwitch" value="Verbose" />
    </switches>
    <sharedListeners>
      <add name="SignalR-Transports" 
           type="System.Diagnostics.TextWriterTraceListener" 
           initializeData="transports.log.txt" />
        <add name="SignalR-Bus"
           type="System.Diagnostics.TextWriterTraceListener"
           initializeData="bus.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

Uygulamayı Visual Studio'da çalıştırdığınızda, çıkış penceresinde günlükleri görüntüleyebilirsiniz.

İstemci yöntemlerini çağırma ve Hub sınıfının dışından grupları yönetme

Hub sınıfınızdan farklı bir sınıftan istemci yöntemlerini çağırmak için, Hub için SignalR bağlam nesnesine bir başvuru alın ve bunu istemcideki yöntemleri çağırmak veya grupları yönetmek için kullanın.

Aşağıdaki örnek StockTicker sınıf bağlam nesnesini alır, sınıfın bir örneğinde depolar, sınıf örneğini statik bir özellikte depolar ve adlı StockTickerHubhub'a bağlı istemcilerde yöntemini çağırmak updateStockPrice için tekil sınıf örneğindeki bağlamı kullanır.

// For the complete example, go to 
// http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-aspnet-signalr
// This sample only shows code related to getting and using the SignalR context.
public class StockTicker
{
    // Singleton instance
    private readonly static Lazy<StockTicker> _instance = new Lazy<StockTicker>(
        () => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>()));

    private IHubContext _context;

    private StockTicker(IHubContext context)
    {
        _context = context;
    }

    // This method is invoked by a Timer object.
    private void UpdateStockPrices(object state)
    {
        foreach (var stock in _stocks.Values)
        {
            if (TryUpdateStockPrice(stock))
            {
                _context.Clients.All.updateStockPrice(stock);
            }
        }
    }

Bağlamı uzun ömürlü bir nesnede birden çok kez kullanmanız gerekiyorsa, başvuruyu bir kez alın ve her seferinde yeniden almak yerine kaydedin. Bağlamı bir kez almak, SignalR'nin istemcilere hub yöntemlerinizin istemci yöntemi çağrıları yaptığı sırada ileti göndermesini sağlar. Hub için SignalR bağlamını kullanmayı gösteren bir öğretici için bkz. ASP.NET SignalR ile Sunucu Yayını.

İstemci yöntemlerini çağırma

RPC'yi hangi istemcilerin alacağını belirtebilirsiniz, ancak Hub sınıfından çağırdığınızdan daha az seçeneğiniz vardır. Bunun nedeni, bağlamın bir istemciden gelen belirli bir çağrıyla ilişkilendirilmemesidir, bu nedenle geçerli bağlantı kimliği hakkında bilgi gerektiren , veya veya Clients.CallerClients.OthersInGroupgibi Clients.Othersyöntemlerin kullanılamamasıdır. Aşağıdaki seçenekler kullanılabilir:

  • Tüm bağlı istemciler.

    context.Clients.All.addContosoChatMessageToPage(name, message);
    
  • Bağlantı kimliğiyle tanımlanan belirli bir istemci.

    context.Clients.Client(connectionID).addContosoChatMessageToPage(name, message);
    
  • Bağlantı kimliğiyle tanımlanan belirtilen istemciler dışındaki tüm bağlı istemciler.

    context.Clients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    
  • Belirtilen gruptaki tüm bağlı istemciler.

    context.Clients.Group(groupName).addContosoChatMessageToPage(name, message);
    
  • Bağlantı kimliğiyle tanımlanan belirtilen istemciler dışında belirtilen gruptaki tüm bağlı istemciler.

    Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message);
    

Hub sınıfınızdaki yöntemlerden Hub olmayan sınıfınıza çağrıda bulunursanız, geçerli bağlantı kimliğini geçirebilir ve bunu , , veya Clients.Group simülasyonu Clients.OthersInGroupClients.CallerClients.Othersyapmak için kullanabilirsiniz.Clients.ClientClients.AllExcept Aşağıdaki örnekte sınıfı, MoveShapeHub bağlantı kimliğini sınıfına Broadcaster geçirerek sınıfının benzetimini BroadcasterClients.Othersyapabilir.

// For the complete example, see
// http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20
// This sample only shows code that passes connection ID to the non-Hub class,
// in order to simulate Clients.Others.
public class MoveShapeHub : Hub
{
    // Code not shown puts a singleton instance of Broadcaster in this variable.
    private Broadcaster _broadcaster;

    public void UpdateModel(ShapeModel clientModel)
    {
        clientModel.LastUpdatedBy = Context.ConnectionId;
        // Update the shape model within our broadcaster
        _broadcaster.UpdateShape(clientModel);
    }
}

public class Broadcaster
{
    public Broadcaster()
    {
        _hubContext = GlobalHost.ConnectionManager.GetHubContext<MoveShapeHub>();
    }

    public void UpdateShape(ShapeModel clientModel)
    {
        _model = clientModel;
        _modelUpdated = true;
    }

    // Called by a Timer object.
    public void BroadcastShape(object state)
    {
        if (_modelUpdated)
        {
            _hubContext.Clients.AllExcept(_model.LastUpdatedBy).updateShape(_model);
            _modelUpdated = false;
        }
    }
}

Grup üyeliğini yönetme

Grupları yönetmek için, Hub sınıfındaki seçeneklerle aynı seçeneklere sahipsiniz.

  • Gruba istemci ekleme

    context.Groups.Add(connectionID, groupName);
    
  • Gruptan istemci kaldırma

    context.Groups.Remove(connectionID, groupName);
    

Hubs işlem hattını özelleştirme

SignalR, Hub işlem hattına kendi kodunuzu eklemenizi sağlar. Aşağıdaki örnekte, istemciden alınan her gelen yöntem çağrısını ve istemcide çağrılan giden yöntem çağrısını günlüğe kaydeden özel bir Hub işlem hattı modülü gösterilmektedir:

public class LoggingPipelineModule : HubPipelineModule 
{ 
    protected override bool OnBeforeIncoming(IHubIncomingInvokerContext context) 
    { 
        Debug.WriteLine("=> Invoking " + context.MethodDescriptor.Name + " on hub " + context.MethodDescriptor.Hub.Name); 
        return base.OnBeforeIncoming(context); 
    }   
    protected override bool OnBeforeOutgoing(IHubOutgoingInvokerContext context) 
    { 
        Debug.WriteLine("<= Invoking " + context.Invocation.Method + " on client hub " + context.Invocation.Hub); 
        return base.OnBeforeOutgoing(context); 
    } 
}

Startup.cs dosyasındaki aşağıdaki kod, hub işlem hattında çalıştırılacak modülü kaydeder:

public void Configuration(IAppBuilder app) 
{ 
    GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule()); 
    app.MapSignalR();
}

Geçersiz kılabileceğiniz birçok farklı yöntem vardır. Tam liste için bkz . HubPipelineModule Yöntemleri.