2013-04-08 20 views
10

Sto utilizzando SignalR 1 con l'applicazione web MVC4 C# con l'autenticazione del modulo. Ho un codice nel mio layout di pagina in JavaScript:disconnetti il ​​client dal lato server signalr

$(documnet).ready(function(){ 
     connect to hub code ... 
}) 

voglio disconnettere un utente forma il mozzo e iniziare a collegare di nuovo dopo che lui fa un login e confermare OK. voglio farlo dal lato server all'interno del mio account di controller e il metodo:

public ActionResult LogOn(LoginModel model, string returnUrl) 
{ 
    if (ModelState.IsValid) 
    { 
     if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password)) 
     { 
      FormsAuthentication.SetAuthCookie(model.UserName, false); 
      ....here , disconnect from hub 
      ....to make the user reconnect  
} 

Il motivo che voglio fare è perché SignalR genera un errore se l'utente autenticato cambiato dopo il login e la connessione resta. L'errore è:

L'ID di connessione è nel formato errato.

risposta

20

Non è possibile interrompere e avviare le connessioni SignalR dal server. Avrete bisogno di chiamare

$.connection.hub.stop(); //on the client before the user attempts to log on and then call 
$.connection.hub.start(); //after the log on attempt has completed. 
+0

io chiamo "$ .connectino.hub. inizio();" su ogni stato di documento pronto ... è OK chiamare "$ .connection.hub.stop();" prima ? –

+0

È necessario scaricarlo dal client quando l'utente si connette all'hub e archiviarlo per poterlo confrontare con qualsiasi nuova connessione, in tal modo si evitano anche attacchi di rappresentazione. –

12

Un modo che si possa fare ciò che si chiede è quello di scrivere un evento di disconnessione sul proprio client che il server può chiamare attraverso SignalR. Forse qualcosa di un po 'come questo:

myHub.client.serverOrderedDisconnect = function (value) { 
    $.connection.hub.stop(); 
}; 

Poi, sul server, qualcosa di simile:

Clients.Client(Context.ConnectionId).serverOrderedDisconnect(); 
+0

ma come posso ottenere Context.ConnectionId dal codice lato server all'interno dell'azione "LogOn"? –

1

Prova questa:

public ActionResult LogOn(LoginModel model, string returnUrl) { 
    if (ModelState.IsValid) { 
     if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password)) { 
      FormsAuthentication.SetAuthCookie(model.UserName, false); 
      connection.Stop(); 
     } 
} 

Assumendo che il handle di connessione è connection. La sfida è accedere a un handle per l'oggetto connection nel metodo di azione.

+0

ma come posso ottenere l'oggetto "connessione" dal codice lato server all'interno dell'azione "LogOn"? –

+1

buona domanda. non l'ho pensato bene Probabilmente non sarebbe prontamente disponibile a meno che non lo avessi aggiunto alla sessione, il che sembra sbagliato ... –

4

Prova a controllare tutto da javascript. Il seguente è un esempio di disconnessione, il login sarebbe simile.

Da http://www.asp.net/signalr/overview/security/introduction-to-security:

Se cambia lo stato di autenticazione di un utente, mentre una connessione attiva esiste, l'utente riceverà un errore che afferma: "L'identità dell'utente non può cambiare durante una connessione SignalR attiva." In tal caso, l'applicazione dovrebbe riconnettersi al server per assicurarsi che l'ID di connessione e il nome utente siano coordinati. Ad esempio, se l'applicazione consente all'utente di disconnettersi mentre esiste una connessione attiva , il nome utente per la connessione non corrisponderà più al nome passato per la richiesta successiva. Si vorrà interrompere la connessione prima che l'utente si disconnetta e quindi riavviarlo.

Tuttavia, è importante notare che la maggior parte delle applicazioni non necessita di per arrestare manualmente e avviare la connessione. Se l'applicazione reindirizza gli utenti a una pagina separata dopo la disconnessione, come il comportamento predefinito in un'applicazione Web Form o MVC o aggiorna la pagina corrente dopo aver effettuato il logout, la connessione attiva è automaticamente disconnessa e non richiede qualsiasi azione aggiuntiva.

L'esempio seguente mostra come interrompere e avviare una connessione quando lo stato dell'utente è cambiato.

<script type="text/javascript"> 
$(function() { 
    var chat = $.connection.sampleHub; 
    $.connection.hub.start().done(function() { 
     $('#logoutbutton').click(function() { 
      chat.connection.stop(); 
      $.ajax({ 
       url: "Services/SampleWebService.svc/LogOut", 
       type: "POST" 
      }).done(function() { 
       chat.connection.start(); 
      }); 
     }); 
    }); 
}); 

-3

Copia e incolla il seguente funzione nel vostro hub

Use HttpContext.Current.Response.End(); 

per forzare il client di staccare nel vostro hub

+0

Problemi grammaticali e di presentazione a parte, ci sono problemi tecnici con questa soluzione che causerebbe i downvotes? –

Problemi correlati