ASP.NET SignalR Hubs API Kılavuzu - Sunucu (SignalR 1.x)
Tarafından Patrick Fletcher, Tom Dykstra
Uyarı
Bu belgeler SignalR'nin en son sürümüne yönelik değildir. ASP.NET Core SignalR'ye göz atın.
Bu belge, SignalR sürüm 1.1 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'leri, bir sunucudan bağlı istemcilere ve istemcilerden sunucuya uzaktan yordam çağrıları (RPC) yapmanıza olanak tanır. Sunucu kodunda, istemciler tarafından çağrılabilecek yöntemleri tanımlar ve istemcide çalışan yöntemleri çağırırsınız. İstemci kodunda, sunucudan çağrılabilen yöntemler 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ılar'a giriş için veya eksiksiz bir SignalR uygulamasının nasıl derlendiğini gösteren bir öğretici için bkz. SignalR - Başlarken.
Genel Bakış
Bu belgede aşağıdaki bölümler yer alır:
SignalR yolunu kaydetme ve SignalR seçeneklerini yapılandırma
Hub sınıfında istemcilerin çağırabileceği yöntemleri 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:
API Başvurusu konularının bağlantıları API'nin .NET 4.5 sürümünedir. .NET 4 kullanıyorsanız API konularının .NET 4 sürümüne bakın.
SignalR yolunu kaydetme ve SignalR seçeneklerini yapılandırma
İstemcilerin Hub'ınıza bağlanmak için kullanacağı yolu tanımlamak için uygulama başlatıldığında MapHubs yöntemini çağırın. MapHubs
sınıfı için System.Web.Routing.RouteCollection
bir uzantı yöntemidir. Aşağıdaki örnekte , Global.asax dosyasında SignalR Hubs yolunun nasıl tanımlanacağı gösterilmektedir.
using System.Web.Routing;
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
}
}
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 ve MVC 4 ile Çalışmaya Başlama.
/signalr URL'si
Varsayılan olarak, istemcilerin Hub'ınıza bağlanmak için kullanacağı yol URL'si "/signalr"dır. (Bu URL'yi otomatik olarak oluşturulan JavaScript dosyası için olan "/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
RouteTable.Routes.MapHubs("/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 MapHubs
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 etki alanları arası çağrıları etkinleştirin.
Genellikle tarayıcı sayfasından
http://contoso.com
bir sayfa yüklerse SignalR bağlantısı adresinde aynı etki alanındadırhttp://contoso.com/signalr
. sayfasındanhttp://contoso.com
ile bağlantıhttp://fabrikam.com/signalr
kurulduysa, 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ın proxy'lerini içeren 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 çağrıda bu seçeneklerin nasıl belirtilmesi gösterilmektedir MapHubs
. Özel bir URL belirtmek için örnekteki "/signalr" yerine kullanmak istediğiniz URL'yi yazın.
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableCrossDomain = true;
hubConfiguration.EnableDetailedErrors = true;
hubConfiguration.EnableJavaScriptProxies = false;
RouteTable.Routes.MapHubs("/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 bir sohbet uygulaması için basit bir Hub sınıfı gösterilmektedir.
public class ContosoChatHub : Hub
{
public void NewContosoChatMessage(string name, string message)
{
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 uygun olabilmesi 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ı olur:
Tüm istemciler hizmetinizle bir SignalR bağlantısı kurmak için aynı URL'yi kullanır ("/signalr" veya belirttiyseniz özel URL'niz) 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 bilgileri 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 dosyada 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'da bağlı istemcilerin alt kümelerine yayın yapmak için adlandırılmış gruplar tanımlayabilirsiniz. Gruplar her Hub için ayrı ayrı tutulur. Örneğin, "Yöneticiler" 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.
İstemcilerin çağırabileceği Hub sınıfında yöntemler 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 void NewContosoChatMessage(string name, string message)
{
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 parametre 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 deve kasası
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 uygun olabilmesi 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öndürerek (dönüş türü yerine T
) 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 sarmalanmamış sonucu istemciye geri gönderir, bu nedenle istemcide yöntem çağrısını kodlarken bir fark yoktur.
Hub yönteminin zaman uyumsuz hale getirilmesi, WebSocket aktarımını kullandığında bağlantının engellenmesini önler. Hub yöntemi zaman uyumlu olarak yürütürse ve aktarım WebSocket olduğunda, Hub yöntemi tamamlanana kadar hub'da aynı istemciden sonraki yöntem çağrıları engellenir.
Aşağıdaki örnekte, zaman uyumlu veya zaman uyumsuz olarak çalıştırılacak şekilde kodlanmış olan yöntemin aynısını ve ardından 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 - ASP.NET 4.5
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öntemler 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. Farklı parametre türleri belirterek aşırı yüklemeyi ayırt ederseniz Hub sınıfınız derlenir ancak istemciler aşırı yüklemelerden birini çağırmaya çalıştığında SignalR hizmeti çalışma zamanında bir özel durum oluşturur.
Hub sınıfından istemci yöntemlerini çağırma
İstemci yöntemlerini sunucudan ç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 void NewContosoChatMessage(string name, string message)
{
Clients.All.addNewMessageToPage(name, message);
}
}
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 void SendMessage(string name, string message)
{
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
İstemciler ö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 kullanımıylaClients.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);
Yöntem adları için derleme zamanı doğrulaması yok
Belirttiğiniz yöntem adı dinamik bir nesne olarak yorumlanır ve bu da bunun için IntelliSense veya derleme zamanı doğrulaması olmadığı anlamına gelir. İ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 adla 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 duyarlı olmayan 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. Sonraki kod satırlarının yöntemin tamamlanmasını beklemesi gerektiğini belirtmediğiniz sürece, bir istemciye yöntem çağrısından sonra gelen tüm kodlar SignalR'nin istemcilere veri iletmeyi bitirmesini beklemeden hemen yürütülür. Aşağıdaki kod örnekleri, biri .NET 4.5'te çalışan kodu, diğeri de .NET 4'te çalışan kodu kullanan iki istemci yönteminin sırayla nasıl yürütüleceğini gösterir.
.NET 4.5 örneği
async public Task NewContosoChatMessage(string name, string message)
{
await Clients.Others.addContosoChatMessageToPage(data);
Clients.Caller.notifyMessageSent();
}
.NET 4 örneği
public void NewContosoChatMessage(string name, string message)
{
(Clients.Others.addContosoChatMessageToPage(data) as Task).ContinueWith(antecedent =>
Clients.Caller.notifyMessageSent());
}
bir sonraki kod satırı yürütülmeden önce istemci yönteminin bitmesini beklemek için veya ContinueWith
kullanırsanızawait
, bu istemcilerin bir sonraki kod satırı yürütülmeden önce iletiyi alacağı anlamına gelmez. İstemci yöntemi çağrısının "Tamamlanması", 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 , vb.) IClientProxy
yayınlayın Clients.All
ve invoke(methodName, args...)çağırın. Clients.Caller
Clients.Others
public void NewContosoChatMessage(string name, string message)
{
string methodToCall = "addContosoChatMessageToPage";
IClientProxy proxy = Clients.All;
proxy.Invoke(methodToCall, name, message);
}
Hub sınıfından grup üyeliğini yönetme
SignalR'deki gruplar, iletileri bağlı istemcilerin belirtilen alt kümelerine yayınlamak için bir yöntem sağlar. Bir grubun herhangi bir sayıda istemcisi olabilir ve bir istemci de 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);
Açıkça grup 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 üyeliklerinin listesini tutmaz. 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. Bir gruba 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 örnekleri, bunun nasıl yapılacağını gösterir. Bunlardan biri .NET 4.5'te çalışan bir kod, diğeri de .NET 4'te çalışan kod kullanılarak yapılır
.NET 4.5 örneği
async public Task JoinGroup(string groupName)
{
await Groups.Add(Context.ConnectionId, groupName);
Clients.Group(groupname).addContosoChatMessageToPage(Context.ConnectionId + " added to group");
}
.NET 4 örneği
public void JoinGroup(string groupName)
{
(Groups.Add(Context.ConnectionId, groupName) as Task).ContinueWith(antecedent =>
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 istemcinin 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ı kaybedildikten sonra veya bağlantı zaman aşımına uğradıktan sonra bağlantı otomatik olarak geri yüklenemediyse veya istemcinin 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 bölümüne 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.
Kullanıcı adını grup adı olarak 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ı ile 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ıyı kestiğinde depolanan verileri güncelleştirebilirsiniz. Kullanıcıya ileti göndermek için bağlantı kimliklerini belirtirsiniz. Bu yöntemin bir 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()
{
// 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();
}
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 OnConnected
ardından 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
yöntemi, istemcinin bağlantısı kesildiğinde çağrılır ve bir tarayıcı yeni bir sayfaya gittiği zaman gibi SignalR otomatik olarak yeniden bağlanamaz. Bu nedenle, belirli bir istemci için olası bir olay dizisi , OnReconnected
, OnDisconnected
; veya OnConnected
, OnDisconnected
olurOnConnected
. 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 çalıştırabilir OnReconnected
.
Daha fazla bilgi için bkz. SignalR'de Bağlantı Ömrü Olaylarını Anlama ve İşleme.
Arayan durumu doldurulamadı
Bağlantı ömrü olay işleyicisi 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
doldurulmayacak. Nesnesi ve Caller
özelliği hakkında state
daha fazla bilgi için, bu konunun devamında İstemciler ile Hub sınıfı arasında durum geçirme bölümüne bakın.
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ı şeye birden çok başvurunun nedeni, önce oluşturulmuş olmasıContext.Headers
, ö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 bkz. JavaScript ve .NET istemcileri için API kılavuzları.
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şleyicisi yöntemindeOnConnected
bu değeri denetlerseniz, bazı senaryolarda başlangıçta bağlantı için belirlenen son aktarım yöntemi olmayan bir aktarım değeri alabilirsiniz. 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 doldurulmuyor.
nesnesinde ve Clients.Caller
özelliğinde state
veri oluşturma veya güncelleştirme 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 void NewContosoChatMessage(string data)
{
string userName = Clients.Caller.userName;
string computerName = Clients.Caller.computerName;
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.
Hub sınıfında hataları işleme
Hub sınıf yöntemlerinizde oluşan hataları işlemek için aşağıdaki yöntemlerden birini veya her ikisini 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 nedenleriyle üretimdeki 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 örnek hataları günlüğe kaydeden bir işlem hattı modülünü ve ardından Modülü Hubs işlem hattına yerleştiren Global.asax kodunu gösterir.
public class ErrorHandlingPipelineModule : HubPipelineModule { protected override void OnIncomingError(Exception ex, IHubIncomingInvokerContext context) { Debug.WriteLine("=> Exception " + ex.Message); if (ex.InnerException != null) { Debug.WriteLine("=> Inner Exception " + ex.InnerException.Message); } base.OnIncomingError(ex, context); } }
protected void Application_Start(object sender, EventArgs e) { GlobalHost.HubPipeline.AddModule(new ErrorHandlingPipelineModule()); RouteTable.Routes.MapHubs(); }
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 istemcide yöntemleri çağırmak veya grupları yönetmek için bunu 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 tekli sınıf örneğindeki bağlamı kullanır.
// For the complete example, go to
// http://www.asp.net/signalr/overview/signalr-1x/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ırayla 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
Hangi istemcilerin RPC alacağını belirtebilirsiniz, ancak Hub sınıfından arama yaptığı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 , veya veya Clients.Caller
Clients.OthersInGroup
gibi Clients.Others
geçerli bağlantı kimliği hakkında bilgi gerektiren yöntemler kullanılamaz. 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);
Belirtilen istemciler dışında, bağlantı kimliğiyle tanımlanan belirtilen bir 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ızı çağırıyorsanız, geçerli bağlantı kimliğini geçirebilir ve bunu Clients.Client
, Clients.AllExcept
veya , veya Clients.Group
simülasyonu Clients.OthersInGroup
Clients.Caller
Clients.Others
yapmak için kullanabilirsiniz. Aşağıdaki örnekte, MoveShapeHub
sınıfı bağlantı kimliğini sınıfına Broadcaster
geçirir, böylece sınıfın Broadcaster
simülasyonunu Clients.Others
yapabilir.
// For the complete example, see
// http://www.asp.net/signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr
// 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ıyla 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 örnek, 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ünü gösterir:
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);
}
}
Global.asax dosyasındaki aşağıdaki kod, hub işlem hattında çalıştırılacak modülü kaydeder:
protected void Application_Start(object sender, EventArgs e)
{
GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule());
RouteTable.Routes.MapHubs();
}
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