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
- Visual Studio 2013
- .NET 4.5
- SignalR sürüm 2
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:
İstemcilerin çağırabileceği Hub sınıfında yöntemler tanımlama
İstemci yöntemlerini çağırma ve Hub sınıfının dışından grupları yönetme
İ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
. MapSignalR
sı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.com
bir sayfa yüklerse SignalR bağlantısı konumundakihttp://contoso.com/signalr
aynı etki alanındadır. sayfasındaki sayfasıhttp://contoso.com
ilehttp://fabrikam.com/signalr
bağ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 Hub
tü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ızStockTickerHub
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) Hub
tü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 ileClients.Caller
aynı 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 , addcontosochatmessagetopage
veya 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.Caller
vb.) 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.Add
otomatik 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 , OnDisconnected
ve 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 , OnDisconnected
OnReconnected
dizisini OnConnected
gö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.Headers
de alabilirsiniz. Aynı şeyeContext.Headers
birden çok başvurunun nedeni, önce oluşturulmuş olması, özelliğinContext.Request
daha sonra eklenmesi veContext.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.QueryString
de 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öntemindeOnConnected
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.RequestCookies
de 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.Current
HttpContext
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 , OnDisconnected
ve OnReconnected
bağlantı ömrü olay işleyici yöntemleri OnConnected
iç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 await
zaman 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şturucuHubError
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ı StockTickerHub
hub'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.Caller
Clients.OthersInGroup
gibi Clients.Others
yö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.OthersInGroup
Clients.Caller
Clients.Others
yapmak için kullanabilirsiniz.Clients.Client
Clients.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 Broadcaster
Clients.Others
yapabilir.
// 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.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin