2016-09-15 10 views
7

मेरे वेब एप्लिकेशन में मैं सर्वर से सभी डेटा को पावर अप पर सर्वर से लोड करना चाहता हूं। इसके बाद मैं चाहता हूं कि सभी संचार सिग्नल के माध्यम से प्रबंधित किए जाएं - जिसका अर्थ है कि प्रत्येक अपडेट सर्वर सभी ग्राहकों को अधिसूचना भेज देगा और वे अपडेट किए गए डेटा के लिए पूछेंगे।क्लाइंट और सर्वर सिंक्रनाइज़ करने के लिए सिग्नलआर नोटिफिकेशन प्रबंधित करना (सी #)

हालांकि, मुझे नहीं पता कि सिंगलआर कनेक्शन दूषित होने पर क्या करना है और फिर वापस चला जाता है। मैं फिर से सभी डेटा लोड नहीं करना चाहता हूं। मैं क्या करना चाहता हूं कि प्रत्येक डिस्कनेक्टेड क्लाइंट के लिए सर्वर पक्ष पर कुछ प्रकार के अधिसूचना प्रबंधन को कार्यान्वित करना है और जब भी सिग्नल कनेक्शन फिर से बनाया जाता है - उस विशिष्ट क्लाइंट को उन सभी सूचनाओं को दबाएं जिन्हें उन्होंने याद किया है।

क्लाइंट साइड पर हमारे सिग्नलआर श्रोताओं को छोटे रहने वाले नियंत्रकों की बजाय सिंगलटन श्रोताओं पर बनाया जाता है, ताकि हम प्रत्येक दृश्य परिवर्तन पर अनुरोध प्राप्त कर सकें और एप्लिकेशन को तेज़ी से और अधिक उपयोगकर्ता के अनुकूल बना सकें। क्योंकि कि दृष्टिकोण की पृष्ठभूमि में नई सूचनाएं भी संभाला और प्रसंस्कृत तब भी जब यह वर्तमान दृश्य के लिए प्रासंगिक नहीं है पाने के अंत उपयोगकर्ता, पर है, इसलिए जैसे:

// This service is initialized once only 
public class Service1 { 
     static inject = ['$rootScope'] 
    array : Item[]; 

    // This is a singleton! 
    public constructor ($rootScope){ 

     // Get all items from the server 
     GetAllItemsFromServer(); 

     // Listener for signalR updates 
     var listener = $rootScope.$on("ItemsNotificationFromServer", UpdateItems); 

     $rootScope.$on('destroy', { 
      // Stop the listener 
      listener(); 
     }) 
    } 

    // Getting all the items from the server on each controller creation 
    GetAllItemsFromServer(){ 
     // Getting the items 
    } 

    // Handle the notification from the server 
    public UpdateItems(event, result) : void 
     //.. 
    } 
} 

पल क्या उदाहरण के लिए होता है पर है कि जब कोई अंतिम उपयोगकर्ता ब्राउज़र को रीफ्रेश करता है (F5) मैं नहीं जानता कि कनेक्शन क्लाइंट के दौरान इस क्लाइंट को किस सिग्नलआर नोटिफिकेशन को याद किया गया है और इसलिए मैं सर्वर से सभी डेटा फिर से लोड करता हूं (यह बेकार है)।

ताकि इसे रोकने के लिए मैं कुछ इस तरह लागू करने के बारे में सोचा -

namespace MapUsersSample 
{ 
    public class UserContext : DbContext 
    { 
     // All those are cleaned when server is powered up 
     public DbSet<Connection> Connections { get; set; } 
     public DbSet<Notification> Notifications {get; set;} 
    } 

    public class Connection 
    { 
     [Key] 
     [DatabaseGenerationOptions.None] 
     public string ConnectionID { get; set; } 
     public bool Connected { get; set; } 

     // I fill this when disconnected 
     public List<Notification> MissedNotifications {get; set;} 

     public Connection(string id) 
     { 
      this.ConnectionID = id; 
      this.Connected = true; 
      this.MissedNotifications = new List<Notification>(); 
     } 
    } 

    public abstract class Notification() 
    { 
     public int Id {get; set;} 
     public DateTime CreationTime {get; set;} 
    } 

    .. // Many notifications implement this 
} 

public class MyHub : Hub 
{ 
    private readonly DbContext _db; 
    public class MyHub(DbContext db) 
    { 
     this._db = db; 
    } 

    // Adding a new connection or updating status to true 
    public override Task OnConnected() 
    { 
     var connection = GetConnection(Context.ConnectionId); 

     if (connection == null) 
      _db.Connections.Add(new Connection(Context.ConnectionId)); 
     else 
      connection.Connected = true; 

     return base.OnConnected() 
    } 

    // Changing connection status to false 
    public override Task OnDisconnected() 
    { 
     var connection = GetConnection(Context.ConnectionId); 

     if (connection == null) 
     { 
      Log("Disconnect error: failed to find a connection with id : " + Context.ConnectionId); 
      return; 
     } 
     else { 
      connection.Connected = false; 
     } 
     return base.OnDisconnected(); 
    } 

    public override Task OnReconnected() 
    { 
     var connection = GetConnection(Context.ConnectionId); 

     if (connection == null) 
     { 
      Log("Reconnect error - failed to find a connection with id : " + Context.ConnectionId); 
      return; 
     } 
     else { 
      connection.Connected = true; 
     } 

     // On reconnect, trying to send to the client all the notifications that he has missed 
     foreach (var notification in connection.MissedNotifications){ 
      Clients.Client(connection.ConnectionID).handleNotification(notification); 
     } 

     return base.OnReconnected(); 
    } 

    // This method is called from clients that receive a notification 
    public clientNotified(int connectionId, int notificationId) 
    { 
     // Getting the connection 
     var connection = GetConnection(connectionId); 

     if (connection == null){ 
      Log("clientNotified error - failed to find a connection with id : " + Context.ConnectionId); 
      return; 
     } 

     // Getting the notification that the client was notified about 
     var notificationToRemove = _dbConnection.Notifications.FirstOrDefault(n => n.Id == notificationId); 

     if (notificationToRemove == null) 
     { 
      Log("clientNotified error - failed to find notification with id : " + notificationId); 
      return; 
     } 

     // Removing from the missed notifications 
     connection.MissedNotifications.Remove(notificationToRemove); 
    } 

    private Connection GetConnection(int connectionId) 
    { 
     return _db.Connections.find(connectionId); 
    } 


} 

// Notifications outside of the hub 
public class Broadcaster 
{ 
    DbContext _db; 
    public Broadcaster(DbContext db) 
    { 
     _hubContext = GlobalHost.ConnectionManager.GetHubContext<MoveShapeHub>(); 
     _dbConnection = db; 
    } 

    public void NotifyClients(Notification notification) 
    { 
     var openConnections = _db.Connections.Where(x => x.Connected); 
     var closedConnections = _db.Connections.Where(x => !x.Connected); 

     // Adding all notifications to be sent when those connections are back 
     foreach (var connection in closedConnections){ 
      connection.MissedNotifications.add(notification); 
     } 

     // Notifying all open connections 
     foreach (var connection in openConnections){ 
      _hubContext.Clients.Client(connection.ConnectionID).handleNotification(notification); 
     } 
    } 
} 


client side java script: 

handleNotification(notification){ 
    hubProxy.Server.clientNotified(hub.connection.id, notification.Id) 

    // Keep handling the notification here.. 
} 

मैं अभी तक यह परीक्षण करने के लिए नहीं मिला है, लेकिन इससे पहले कि मैं अपनी टीम को यह विचार प्रस्तुत, इस दृष्टिकोण लोकप्रिय है? लोगों ने इस दृष्टिकोण को नहीं देखा है और मुझे आश्चर्य हुआ कि क्यों? क्या यहां कोई जोखिम है?

+0

मेरी राय में, यदि अंतिम उपयोगकर्ता पृष्ठ को रीफ्रेश करता है, तो जेएस द्वारा निर्मित संपूर्ण महल, कॉल क्लाइंट साइड संग्रह सहित, सिग्नल कनेक्शन ऑब्जेक्ट्स खो जाते हैं। और उस स्थिति में, यदि आप चाहते हैं तो आपको सभी डेटा लाने की आवश्यकता है, अन्यथा आपके पास जो होगा वह केवल बढ़ती डेटा है। –

+0

क्या आपने RabbitMQ जैसे कतारों को माना है? एक बार सॉकेट कनेक्शन खो जाने के बाद –

+0

, यह जानने का कोई तरीका नहीं है कि जब तक आप कुछ राज्य बनाए रखते हैं, वही ग्राहक फिर से कनेक्ट हो जाता है, तो आपको भी सावधान रहना होगा और सही डेटा को सही उपयोगकर्ता को धक्का देना होगा। मैं नए अनुरोधों के मुताबिक नए अनुरोधों के इलाज के लिए सिफारिश करता हूं। –

उत्तर

2

पल क्या उदाहरण के लिए होता है पर कि एक अंत उपयोगकर्ता ब्राउज़र ताज़ा करता है जब (F5) मैं नहीं जानता कि क्या कर सकते हैं SignalR सूचनाएं इस ग्राहक कनेक्शन समस्याओं के दौरान याद किया गया है और इसलिए मैं सर्वर से सभी डेटा लोड सब फिर से (यह बेकार है)।

ब्राउज़र रीफ्रेश करने के लिए F5 दबाकर एक हार्ड रीसेट है, सभी मौजूदा सिग्नल कनेक्शन खो जाएंगे। डेटा प्राप्त करने के लिए नए कनेक्शन बनाए जाएंगे। कनेक्शन समस्याएं परिदृश्यों में होती हैं जब सिग्नलआर http कनेक्शन के साथ समस्याओं को नोटिस करता है उदा। अस्थायी नेटवर्क मुद्दों के कारण। ब्राउज़र रीफ्रेश एक कनेक्शन समस्या नहीं है, यह एक उपयोगकर्ता का एक कार्य है जो जानबूझकर एक नया कनेक्शन पुनर्निर्माण कर रहा है।

तो, मिस्ड नोटिफिकेशन प्रबंधित करने का आपका कोड केवल सिग्नल कनेक्शन कनेक्शन के लिए काम करेगा। मुझे नहीं लगता कि यह ब्राउज़र रीफ्रेश के लिए काम करेगा, लेकिन फिर यह एक नया कनेक्शन है, इसलिए आपने कुछ भी याद नहीं किया है।

2

आपको यह जांचना चाहिए कि डेटा वास्तविक है या नहीं। यह अंतिम परिवर्तन का हैश या डेटाटाइम हो सकता है।

जब ग्राहक पुन: कनेक्ट होता है तो आपको क्लाइंट को अंतिम परिवर्तन के वास्तविक डेटा हैश या डेटाटाइम भेजना चाहिए।

उदाहरण

{ 
clients: '2016-05-05T09:05:05', 
orders: '2016-09-20T10:11:11' 
} 

और क्लाइंट अनुप्रयोग क्या डेटा इसे अद्यतन करने की जरूरत है तय करेगा के लिए

क्लाइंट पर आप स्थानीय स्टोरेज या सत्र स्टोरेज में डेटा सहेज सकते हैं।

संबंधित मुद्दे