2017-07-23 6 views
0

Je dois implémenter le chat sur mon projet web. Comment l'implémenter sur une page - il y a beaucoup d'articles à ce sujet. Mais je dois avoir la capacité: 1. Aviser les autres utilisateurs, que quelqu'un connecté sur le site (sur une page, non seulement à la page de discussion) 2. informer les autres utilisateurs, que quelqu'un dconnecter SignalR - implémentation correcte du chat

Donc, je donne les résultats suivants Code du moyeu:

public void Connect() 
    { 
     try 
     { 
      var id = Context.ConnectionId; 
      string username = Context.User.Identity.Name; 

      var currentUser = connectedUsers.Where(p => p.Username == username).FirstOrDefault(); 
      if (currentUser == null) 
      { 
       AddNewUserToCollection(); 
      } 
      else 
      { 
       // update ConnectionId for sure (connection id is changed sometimes (probably if user is logged out and login again)) 
       if (currentUser.ConnectionId != id) 
       { 
        var companyId = _chatRepository.GetCompanyIdOfUser(username); // throws exception if companyId is null 
        Groups.Remove(currentUser.ConnectionId, companyId.ToString()); 
        Groups.Add(id, companyId.ToString()); 
        currentUser.ConnectionId = id; 
        //Clients.Group(companyId.ToString()).onNewUserConnected(username); 
       } 
      } 
     } 
     catch(InvalidCompanyException c_ex) 
     { 
      Clients.Client(Context.ConnectionId).onErrorMessage($"User '{c_ex.Username}' does not exist"); 
     } 
    } 


    public void Disconnect() 
    { 
     string username = Context.User.Identity.Name; 
     var item = connectedUsers.Where(p => p.Username == username).FirstOrDefault(); 
     if (item != null) 
     { 
      connectedUsers.Remove(item); 
      Groups.Remove(item.ConnectionId, item.CompanyID.ToString()); 
      Clients.Group(item.CompanyID.ToString()).onUserDisconnected(item.Username); 
     } 
    } 

    public override Task OnDisconnected(bool stopCalled) 
    { 
     var item = connectedUsers.Where(p => p.ConnectionId == Context.ConnectionId).FirstOrDefault(); 
     if (item != null) 
     { 
      connectedUsers.Remove(item); 
      Groups.Remove(item.ConnectionId, item.CompanyID.ToString()); 
      Clients.Group(item.CompanyID.ToString()).onUserDisconnected(item.Username); 
     } 
     return base.OnDisconnected(stopCalled); 
    } 

et j'ajouté le code suivant à _layout.cshtml:

<script> 
     $(document).ready(function() { 
      var chat = $.connection.chatHub; 

      $.connection.hub.start().done(function() { 
       chat.server.connect(); 
      }); 
     }); 
    </script> 

à autres usagers, que l'utilisateur actuel est connecté. Mais le débogueur dit que cette paire OnDisconnected/Connect est appelée à chaque fois, lorsque l'utilisateur recharge la page (passe par les pages) avec un ID de connexion différent. Lorsque je supprime ce code client, cette paire n'est pas appelée. Comment l'implémenter correctement, informer les autres utilisateurs, que quelqu'un est en ligne, mais sans se reconnecter à chaque fois?

+0

Vous êtes presque là pour la version la plus basique. Tout ce que je suggère est d'attendre quelques secondes après que quelqu'un se déconnecte avant de dire à tous les autres qu'ils se sont déconnectés (et seulement si l'utilisateur n'avait pas trouvé un nouvel identifiant de connexion). Votre prochain problème est de traiter avec un utilisateur avec plusieurs onglets ouverts (vous aurez besoin de suivre le nombre de connexions que chaque utilisateur a). IFYI serait idéalement dans un pipeline hub, mais vous devriez probablement commencer à travailler ici d'abord. – thab

Répondre

1

Comme vous avez l'appel connect() dans une page de rasoir (_layout.cshtml), vous serez effectivement déconnecté/connecté à chaque publication (chargement de la page).

Le scénario que vous essayez d'utiliser est le meilleur dans un scénario SPA (ou AJAX) où la navigation est gérée de manière asynchrone par JavaScript côté client. Votre configuration actuelle actualise l'écran, recharge le JavaScript, relance la fonction document ready() avec chaque navigation rendue par le serveur.

Une autre alternative consiste à utiliser l'ID utilisateur réel du client et de le transmettre à la méthode server.connect (id). Utilisez ensuite cet ID utilisateur pour suivre l'activité de l'utilisateur à la place du hub ConnectionId.