Lorsque la connexion est fermée avec SignalR de navigateur
Je suis en train de faire une petite application de chat avec SignalR 2.0 (comme tout le monde).
J'ai un win8.1 domaine d'application et lorsque l'application est fermée, le hub reçoit l'évènement OnDisconnected et supprime l'utilisateur à partir de la liste sur le moyeu.
Le hub envoie à chaque client que l'utilisateur a quitté le chat, donc on peut visualiser que l'utilisateur a quitté.
Mais quand je suis SignalR et Javascript dans une page web et la page est fermée, le concentrateur n'a pas averti que l'onglet/le navigateur est fermé...
Quiconque aucune idée de comment le branchement peut être fermé?
Ce que j'ai codé:
De Démarrage Hub
[assembly: OwinStartup(typeof(ChatServer.Startup))]
namespace ChatServer
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
//Map all hubs to "/signalr"
app.MapSignalR();
}
}
}
Hub
[HubName("ChatHub")]
public class ChatHub : Hub
{
private static List<User> Users = new List<User>();
public void Send(string name, string message)
{
//Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(name, message, DateTime.Now);
}
public void UserConnected(string name)
{
Clients.Caller.connected(JsonConvert.SerializeObject(Users));
User user = new User() { Name = name, ConnectionID = Context.ConnectionId };
Clients.Others.userConnected(JsonConvert.SerializeObject(user));
Users.Add(user);
}
public void UserLeft()
{
if(Users.Any(x=>x.ConnectionID == Context.ConnectionId))
{
User user = Users.First(x => x.ConnectionID == Context.ConnectionId);
Users.Remove(user);
Clients.Others.userLeft(JsonConvert.SerializeObject(user), Context.ConnectionId);
}
}
public override System.Threading.Tasks.Task OnDisconnected()
{
//Only called when win8.1 app closes
//Not called when browsers closes page
UserLeft();
return base.OnDisconnected();
}
}
HTML - Javascript:
Javascript:
chat = new function () {
var ChatHub;
//Connecting to the hub
this.attachEvents = function () {
if ($.connection != null) {
ChatHub = $.connection.ChatHub;
$.connection.hub.start({ transport: 'auto' }, function () {
//Register client on hub
ChatHub.server.userConnected("web name");
});
}
this.send = function (name,message) {
if ($.connection != null) {
//Send chat message
ChatHub.server.send(name, message).fail(function (e) {
alert(e);
});
}
}
}
};
window.onbeforeunload = function (e) {
//This is called when we close the page
$.connection.hub.stop();
return "You killed me! :'(";
};
Win8.1 client
internal async void ConnectToHub(string userName)
{
try
{
HubConnection hubConnection = new HubConnection(SERVER_PROXY);
chat = hubConnection.CreateHubProxy("ChatHub");
Context = SynchronizationContext.Current;
MakeHubFunctionsAvailableOnClient();
await hubConnection.Start();
//Register client on hub
await chat.Invoke("UserConnected", userName);
}
catch (Exception)
{
throw;
}
}
private void MakeHubFunctionsAvailableOnClient()
{
//Receive chat messages
chat.On<string, string, DateTime>("broadcastMessage",
(name, message, date) => Context.Post(
delegate {
Messages.Add(new UserMessage() { Message = message, User = name, Date = date });
}, null
)
);
//Receive all online users
chat.On<string>("connected",
(users) => Context.Post(
delegate
{
List<User> userList = JsonConvert.DeserializeObject<List<User>>(users);
foreach (User user in userList)
{
Users.Add(user);
}
Messages.Add(new UserMessage() { Message = "CONNECTED", User = "System", Date = DateTime.Now });
}, null
)
);
//New user connected
chat.On<string>("userConnected",
(user) => Context.Post(
delegate
{
User newUser = JsonConvert.DeserializeObject<User>(user);
Users.Add(newUser);
Messages.Add(new UserMessage() { Message = newUser.Name + " CONNECTED", User = "System", Date = DateTime.Now });
}, null
)
);
//User left, remove user from list on client
chat.On<string>("userLeft",
(user) => Context.Post(
delegate
{
User newUser = JsonConvert.DeserializeObject<User>(user);
User y = Users.First(x=>x.ConnectionID == newUser.ConnectionID);
bool ux = Users.Remove(y);
Messages.Add(new UserMessage() { Message = newUser.Name + " left the conversation", User = "System", Date = DateTime.Now });
}, null
)
);
}
Mon hub ne déclenche pas OnDisconnected, quand je ferme l'onglet /navigateur /de la navigation sur d'autres sites
Le site est une simple page web (pour le moment)
Quel navigateur suis-je utiliser?
Chrome: Version 32.0.1700.68 bêta-m
Internet Explorer 11
OriginalL'auteur brouckaertd | 2014-01-09
Vous devez vous connecter pour publier un commentaire.
Je suppose que votre question est de savoir comment détecter si un utilisateur spécifique de gauche ou de fermer le navigateur. Quand un utilisateur arrive dans la ou les feuilles, envoyer une notification à d'autres utilisateurs.
Je pense que le problème est que vous n'avez pas à traiter
OnConnected
etOnDisconnected
correctement.Pour le faire fonctionner, vous devez d'abord connaître chaque client qui se connecte à un hub de passe un unique id de connexion. Vous pouvez récupérer cette valeur dans le Contexte.ConnectionId propriété du moyeu contexte. Lors de chaque client arrive, ils vont à travers
OnConnected
, quand ils partent, ils vont à traversOnDisconnected
. Ci-dessous est un exemple de travail:Classe Hub
Vue
Salut @Lin, si j'exécute ton code, j'obtiens ces erreurs: "Uncaught TypeError: Object #<Object> n'a pas de méthode "connecté"". Quand je me connecte le client de l'objet -> console.log($.connexion.ChatHub.client); les résultats dans: Object {}. Si j'utilise ChatHub avec un c minuscule, chathub est pas défini
salut @brouckaertd, je suppose que le problème est que vous n'avez pas le OnConnected fonction de votre classe hub. J'ai créé une semblable fonction de chat pour vous, jetez un coup d'oeil.
Un peu en retard à répondre, mais le onConnected événement est remplaçable. Donc, à partir de ce que je sais, cela signifie qu'elle est toujours appelée. Si je mettre en œuvre le onConnected événement avec un code personnalisé. Je pense que ça ne pourra pas résoudre mon problème. Mais je vais essayer ton code, et espère qu'il fonctionne.
J'ai utilisé mon moyeu avec votre client. Et ça marche!!! Merci!!!! Maintenant seulement de déterminer quelle est la différence entre notre code
OriginalL'auteur Lin
Vous pourriez être en cours d'exécution dans le problème décrit ici: https://github.com/SignalR/SignalR/issues/2719
tl;dr: Il y a un bug introduit dans Chrome 31 qui est déjà fixé dans google Chrome Canary, qui empêche SignalR immédiatement déclencher OnDisconnected.
Si vous êtes, vous pouvez utiliser la solution de contournement je l'ai suggéré dans la question, qui est d'ajouter les éléments suivants à votre code JS.
Même avec ce bug et sans la solution de contournement je m'attends à ce SignalR pour élever OnDisconnected environ 35 fois le navigateur quitte la page hébergeant SignalR.
Peut vous fournir plus de détails à propos des navigateurs vous rencontrez ce problème avec et dans quelles situations? (par exemple, la fermeture de l'onglet, la fermeture de la fenêtre, fraîcheur, de naviguer vers une autre page du même site, la navigation vers un autre site, etc.)
OriginalL'auteur halter73