2010-05-24 15 views
9

Saludos, alguien me puede dar algunos consejos o enlaces que me ayudarán a implementar el siguiente escenario. La página se escribirá en asp.net mvc. La autorización se implementará mediante membresías. El escenario es el siguiente:.asp.net mvc que está en línea

Usuario1 acaba de iniciar sesión Después de un rato , Usuario2 intenta iniciar sesión con éxito. Entonces se debe notificar a user1 que User2 acaba de iniciar sesión. Además, User2 debe ser notificado que User1 es en línea.

¿Cómo puedo lograr algo así? También debería ser posible que estos usuarios se escriban mensajes entre ellos. (chat como)

Respuesta

6

hay métodos para hacer esto en los proveedores de membresía asp.net, específicamente, IsUserOnline() y algo así como CountUsersOnline(). El único problema con estos métodos es que son realmente cojos. Dependen del LastActivityDate() del proveedor de membresía y de una ventana que puede establecer en web.config. En otras palabras, el usuario se considera en línea si su último encuentro con el proveedor de membresía más la ventana de tiempo en web.config no ha expirado.

Tomamos este scenairo y logramos que funcionase para nosotros configurando un servidor Comet y haciendo ping al servidor web cada diez minutos. Cuando se hace ping al servidor web, actualiza el LastActivityDate del proveedor de membresía.

Configuramos la ventana de actividad en 12 minutos, así como el temporizador de sesión. Esto nos permite determinar quién está en línea con una precisión de aproximadamente diez minutos.


Aquí está la línea en Web.config:

<membership userIsOnlineTimeWindow="12"> 

Aquí es servidor de jQuery Comet:

function getData() { 
    $.getJSON("/Account/Timer", gotData); 
    } 

    // Whenever a query stops, start a new one.  
    $(document).ajaxStop(getData, 600000); 

    // Start the first query. 
    getData(); 

Aquí es nuestro código de servidor:

public JsonResult Timer() 
    { 
      MembershipUser user = Membership.GetUser(User.Name); 
      user.LastActivityDate = DateTime.Now; 

      Membership.UpdateUser(user); 

      // You can return anything to reset the timer. 
      return Json(new { Timer = "reset" }, JsonRequestBehavior.AllowGet); 
    } 
+0

¿Dónde agrego este código de servidor? – DoIt

3

Me parece que necesita que se realice una encuesta jQuery.

Puede hacer fácilmente una publicación de jQuery en un ActionResult que verificaría a los usuarios en línea y devolvería un PartialView a la función jQuery llamante.

El PartialView que regresa puede tener todos los usuarios conectados que luego pueden aparecer en algún tipo de panel de animación.

Use javascript para ejecutar una encuesta cronometrada de vuelta al controlador.

+0

sí, yo estaba pensando en la solución similar pero cómo ¿Debería verificar quién está en línea? Cómo crear una funcionalidad (desde el lado del servidor) –

+0

Piensa cuando un usuario inicia sesión necesitarás escribir una entrada de db y al final de la sesión de ese usuario, elimina la entrada quizás. Podría, supongo, mantener todos los usuarios conectados en una memoria caché y eliminarlos al finalizar la sesión. de cualquier forma, creo que debes registrarlos en algún lugar y utilizar la sesión final o algo así como – griegs

+0

, y cualquier sugerencia sobre cómo puedo hacer esto: "Supongo que podrías mantener a todos los usuarios conectados en una memoria caché y eliminarlos al final de la sesión "en asp.net mvc? –

2

No puede obtener en línea en vivo en la web. debe actualizar la página o actualizar el contenido con ajax -o bien-. Así que va a resolver, creo.

ps. chat y problemas en línea, tiene dos opciones; se puede almacenar en la base de datos - su lo que sugieren - o almacenar en la memoria, es posible que desee ver this

Tablas:

Users 
-Id/int - identity 
-LoginTime/datetime 
-IsOnline/bit 

Friends 
-Id/int - identity 
-FirstUserId/int 
-SecondUserId/int 

public class UserInformation 
{ 
    public IList<User> OnlineFriends { get; set;} 
    public IList<User> JustLoggedFriends { get; set; } /* For notifications */ 
} 

public class UserRepository 
{ 
    public UserInformation GetInformation(int id, DateTime lastCheck) 
    { 
     return Session.Linq<User>() 
       .Where(u => u.Id == id) 
       .Select(u => new { 
           User = u, 
           Friends = u.Friends.Where(f => f.FirstUser.Id == u.Id || f.SecondUser.Id == u.Id) 
       }) 
       .Select(a => new UserInformation { 
           JustLoggedFriends = u.Friends.Where(f => f.IsOnline && f.OnlineTime >= lastCheck).ToList(), 
           OnlineFriends = u.Friends.Where(f => f.IsOnline).ToList() 
       }) 
       .ToList(); 
    } 
} 

public class UserService 
{ 
    public UserInformation GetInformation(int id, DateTime lastCheck) 
    { 
     return repository.GetInformation(id, lastCheck); 
    } 
} 

de interfaz de usuario:

public class UserController 
{ 
    public ActionResult Index() 
    { 
     var userId = (int)Session["UserId"]; 
     var lastCheck = (DateTime)Session["LastCheck"]; 
     UserInformation info = userService.GetInformation(userId, lastCheck); 
     Session["LastCheck"] = DateTime.Now; 

     //show up notifications and online users. 
    } 
    public ActionResult Login() 
    { 
     User user = null; // TODO: get user by username and password 
     Session["UserId"] = user.Id; 
     Session["LastCheck"] = DateTime.Now; 
    } 
} 
+0

y cómo implementarlo para que pueda verificar (mediante el uso de GetUserOnlineFriends) periódicamente, digamos cada dos minutos, ¿amigos del usuario? Además, ¿cómo implementar la posibilidad de chatear entre estos dos amigos? –

+0

no limitado. usted puede verificar el evento session_start y session_end y luego actualizar user online -column- cuando session_start se activa y cuando los usuarios de la actualización disparada al final registran como desconectados, la columna _data tipo de bit_ va a resolver esto. y luego si los usuarios en línea los muestran. pero este algoritmo no es para ti, la sesión va a resolver eso. Lo entendí ahora. editando ahora. – cem