Forum
Üzerinde çalıştığım proje bir Asp.Net MVC projesi. Genelde soru sorulurken birçok kavram üzerinden gidildiğinden önce doğru bildiklerimi söylemeyi daha uygun buluyorum. Kavramları kategorize edeceğim, yanlış bir bilgi var ise, kavram numaraları üzerinden gidebiliriz böylece.
Kavram 1 - Kullanıcıları tanımak (ayırt etmek) için birden fazla seçenek var,
I) Browser Özellikleri
II) IP Numarası
III) Sunucunun oluşturduğu Session State (Session State değerleri opsiyonel olarak geçici bellekte (RAM) tutulabilir ya da kalıcı bir birimde (SQL Server) depolanabilir. Client'larda ise browser da tutulur ama cookie gibi depolanmaz)
IV) Web programcısının client tarafında saklanması için request sonrasında response ile dönen cookie'ler.
Kavram 2 - Client browser'ı, IV. maddede bahsedildiği üzere cookie'lere izin vermiyorsa bile, III. madde unsurları her daim çalışacaktır. Bu çalışma, browser kapatılana, eylemsizlik sonrası zaman aşımı gerçekleşene ya da sunucu taraflı değer silinene kadar geçerli olur.
Evet şuan tartışmak istediğim konuya değiniyorum; Dün web siteme yayın öncesi SignalR 2 özelliğini eklemeye karar verdim.
Kavram 3 - SignalR 2 arkaplanda socket mantığını kullanıyor. Tabii, Socket teknolojisi desteklendiği müddetçe, desteklenmiyorsa farklı teknolojileri kullanıyor. Şimdi hatırlayamadığım ama izin verilen, desteklenen durumlara göre SignalR 2; yine kendisinin otomatik seçebileceği 3 ya da 4 farklı yöntem üzerinden çalışabiliyor.
Lâkin kullanıcıları tanıma konusunda nasıl bir yöntem izliyor, sanırım bu da yine gizemli olan HTTP ile alâkalı bir durum. IV. maddede bahsi geçen cookie'yi kullanmıyor bildiğim kadarıyla, III. maddede bahsi geçen Session ID'den mi yararlanıyor, sanki mantıklı gibi ama bilemedim. IP numarasını da dikkate alıyor denemez bence, çünkü arada bir proxy hizmeti olma ihtimali de olabilir.
Velâkin,
1) Aynı IP, aynı bilgisayar ve hatta aynı browser'da ama İKİ FARKLI SEKMEDE oturum açmış iki farklı kullanıcının request ya da response'lar aracılığı ile taşınan özel bir değer ile nasıl ayırt edilebileceğini bilmiyorum. (Javascript ile her sekmede açılan ya da kullanılan oturumlar için özel bir tanımlama yapılabilir, Asp.Net tarafında gelen / giden taleplerde buna ek bir veri ya da işaret var mı onu bilmiyorum) Örneğin, SessionID şu, SekmeID şu gibi...
2) Hali hazırda aynı browser'da çalışan iki farklı sekmedeki iki farklı oturum için, her ikisinin de olası sohbet ekranı açık ise, SignalR 2, bu durumda hangi sekmedeki sohbet ekranına (daha doğrusu hangi sekmedeki javascript mesaj alımı fonksiyonuna) başvuracağını, veriyi ileteceğini nereden ayırt edecek ?
Ve evet, ayırt edemiyorsa, bu iki sekmedeki iki ayrı oturum için özel bir socket uygulaması yazıldığında, çözüm için nasıl bir yöntem izlenmelidir ?
Aynı browser'dan aynı siteye bağlanan iki farklı sekmenin ayırt edilebilmesi için (oturum olsun olmasın) nasıl bir yöntem izlenebilir ?
Teşekkürler.
SignalR yapısında ilgilli Hub'a bağlanan her bir instance yeni bir client olarak tanınır ve yeni bir ConnectionId ile adreslenir. Eğer aynı tarayıcıda farklı sekmelerden ortak Hub'a bağlanırsanız her iki sekmede ayrı birer client olarak çalışacaktır.
Signalr'da bu tarz durumları yönetmek için hazır bir yapı bulunmuyor. Fakat bağlanan clientleri kendiniz yönetebilir ve IP vs. bilgilerden ayrıştırma yapabilirsiniz. Örnek kod;
[HubName("DeviceConfig")]
public class DeviceConfigHub : Hub
{
static List<ConnectedThings> CurrentConnections = new List<ConnectedThings>();
public override Task OnConnected()
{
Debugger.Break();
var id = Context.ConnectionId;
var serverVars = Context.Request.GetHttpContext().Request.ServerVariables;
var Ip = serverVars["REMOTE_ADDR"];
CurrentConnections.Add(new ConnectedThings(id,"", Ip));
GlobalHost.ConnectionManager.GetHubContext<DeviceConfigHub>().Clients.All.connectedThingsChanged(CurrentConnections);
return base.OnConnected();
}
public override Task OnReconnected()
{
return base.OnReconnected();
}
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
var connection = CurrentConnections.FirstOrDefault(x => x.ID == Context.ConnectionId);
if (connection != null)
{
CurrentConnections.Remove(connection);
}
GlobalHost.ConnectionManager.GetHubContext<DeviceConfigHub>().Clients.All.connectedThingsChanged(CurrentConnections);
return base.OnDisconnected(stopCalled);
}
public void Register(string deviceId)
{
string connectionId = Context.ConnectionId;
var firstOrDefault = CurrentConnections.Where(x => x.ID == connectionId).FirstOrDefault();
if (firstOrDefault != null)
firstOrDefault.Name = deviceId;
else
{
CurrentConnections.Add(new ConnectedThings(connectionId, deviceId));
}
GlobalHost.ConnectionManager.GetHubContext<DeviceConfigHub>().Clients.All.connectedThingsChanged(CurrentConnections);
}
public List<ConnectedThings> GetAllActiveConnections()
{
return CurrentConnections.ToList();
}
}