2015-04-23 2 views
1

Я пытаюсь показать друзьям в Интернете пользователей. Для этого я создал столбец OnlineStatus в таблице UserInfo. Я создал концентратор, который при запуске вызывает функцию, и эта функция отправляет запрос Ajax на сервер, чтобы получить список друзей в Интернете. Если друг этого пользователя входит в систему, то в OnlineStatus будет установлено значение 1 в противном случае 0. Для того чтобы пользователь мог видеть своих онлайн-друзей в режиме реального времени, я использую SqlDependency, если столбец OnlineStatus обновлен, а SiganlR - функцию хаба, которая в превращает вызовы в функцию клиента, и эта функция, в свою очередь, отправляет запрос Ajax серверу, запрашивая обновленный список пользователей онлайн. Hub, при запуске, работает нормально, но если пользователь выходит из системы, а SqlDependency не вызывается. Пожалуйста, помогите мне исправить это. А вот действие:SqlDependency не работает, если таблица обновляется

Public JsonResult FindOnlineFriends(long UserId) 
     { 
      List<UserDetails> onlinefriends = new List<UserDetails>(); 
      using(SqlConnection con=new SqlConnection(connectionString)) 
      { 
       using(SqlCommand cmd=new SqlCommand()) 
       { 
        StringBuilder builder = new StringBuilder(); 
        builder.Append("select [UserId],[DisplayPhoto],[Name] from [dbo].[UserInfo] as userself,("); 
        builder.Append("(select [PersonId2] from [dbo].[FriendsRelation] where [PersonId1] like @UserId) union"); 
        builder.Append("(select [PersonId1] from [FriendsRelation] where [PersonId2] like @UserId)) as friends "); 
        builder.Append("where [userself].[UserId]=[PersonId2] and [OnlineStatus]=1"); 
        cmd.CommandText = builder.ToString(); 
        cmd.Connection = con; 
        cmd.Parameters.AddWithValue("@UserId",UserId); 
        cmd.Notification = null; 
        SqlDependency.Stop(connectionString); 
        SqlDependency.Start(connectionString); 
        SqlDependency dependency = new SqlDependency(cmd); 
        dependency.OnChange += new OnChangeEventHandler(onlineFriends_OnChange); 
        con.Open(); 
        using(SqlDataReader rdr=cmd.ExecuteReader()) 
        { 
         if(rdr.HasRows) 
         { 
          while(rdr.Read()) 
          { 
           onlinefriends.Add(new UserDetails { UserId = Convert.ToInt64(rdr["UserId"]), Name = rdr["Name"].ToString(), DisplayPhoto = rdr["DisplayPhoto"].ToString() }); 
          } 
         } 
        } 
       } 
      } 
      return Json(onlinefriends,JsonRequestBehavior.AllowGet); 
     } 
     private void onlineFriends_OnChange(object sender, SqlNotificationEventArgs e) 
     { 
      if (e.Type == SqlNotificationType.Change) 
      { 
       SocialNetworkHub.SocialNetworkHub.ShowOnlineFriends(); 
      } 
     } 

ответ

0

Ваше решение будет работать только для одного пользователя. Когда вы вызываете SqlDependency.Start() или SqlDependency.Stop(), он отбрасывает все подписки. Однако для вашей задачи лучше использовать реализацию с открытым исходным кодом SqlDependency - SqlDependencyEx, потому что с помощью этого компонента вы можете независимо наблюдать за UPDATE изменениями таблицы UserInfo. Пример кода:

int changesReceived = 0; 
using (SqlDependencyEx sqlDependency = new SqlDependencyEx(
      TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME)) 
{ 
    sqlDependency.TableChanged += (o, e) => changesReceived++; 
    sqlDependency.Start(); 

    // Make table changes. 
    MakeTableInsertDeleteChanges(changesCount); 

    // Wait a little bit to receive all changes. 
    Thread.Sleep(1000); 
} 

Assert.AreEqual(changesCount, changesReceived); 

Надеюсь, что это поможет.

Смежные вопросы