2012-11-06 6 views
4

현재 사용자를 OnlineUsers라는 테이블에 보관합니다. 사람이 연결하거나 연결을 끊을 때 테이블에 userid와 그의 connectionid를 추가하지만 어떤 이유로 (여러 브라우저 창이 열렸을 때 나는 믿는다) Disconnect 기능은 때때로 사용자를 테이블에두고 "온라인 "그들이 정말로 그렇지 않을 때. 누구든지이 문제를 전에 경험해 봤고이 문제를 해결하는 좋은 방법은 무엇입니까? 다음은가끔 신호가 끊어지지 않습니다. R

public bool ConnectUser(Guid UserId, String ConnectionId) 
      { 
       if (!Ent.OnlineUsers.Any(x => x.UserId == UserId && x.ConnectionId == ConnectionId)) 
       { 
        Ent.OnlineUsers.AddObject(new OnlineUser { UserId = UserId, ConnectionId = ConnectionId }); 
        Ent.SaveChanges(); 
        return true; 
       } 
       else 
        return false; 
      } 
      public void DisconnectUser(Guid UserId, String ConnectionId) 
      { 
       if (Ent.OnlineUsers.Any(x => x.UserId == UserId && x.ConnectionId == ConnectionId)) 
       { 
        Ent.OnlineUsers.DeleteObject(Ent.OnlineUsers.First(x => x.UserId == UserId && x.ConnectionId == ConnectionId)); 
        Ent.SaveChanges(); 
       } 
      } 

:

UPDATE는 ** 여기

추가 및 테이블에서 제거 할 내 DB 기능입니다 (코드를 참을 수 없어 미안, 나는 처음에 그것을 했어야) 내 허브 클래스는 연결 및 분리 작업 :

public Task Disconnect() 
     { 

      disconnectUser();     
      return null; 
     } 
     public Task Reconnect(IEnumerable<string> connections) 
     { 
      connectUser();     
      return null; 
     } 
     public Task Connect() 
     { 
      connectUser();    
      return null; 
     } 
private void connectUser() 
     { 
      if (onlineUserRepository.ConnectUser(MainProfile.UserId, Context.ConnectionId)) 
      { 
       Groups.Add(Context.ConnectionId, Convert.ToString(MainProfile.ChatId)); 
      } 
     } 
     private void disconnectUser() 
     { 
      onlineUserRepository.DisconnectUser(MainProfile.UserId, Context.ConnectionId); 
      Groups.Remove(Context.ConnectionId, Convert.ToString(MainProfile.ChatId)); 
     } 

내가 signalR (0.5.3)의 최신 버전임을 확인하고이 나는 열려있는 여러 개의 브라우저 창을 때 발생하는 것 같습니다 그리고 그들을 모두 한 번에 닫으면 사용자가 데이터베이스에 갇히게됩니다.

public class MyConnectionFactory : IConnectionIdGenerator 
    { 
     public string GenerateConnectionId(IRequest request) 
     {    
      if (request.Cookies["srconnectionid"] != null) 
      { 
       return request.Cookies["srconnectionid"].ToString(); 
      } 

      return Guid.NewGuid().ToString(); 
     } 
    } 
+2

: 여기

내 연결 팩토리입니까? 나는 0.5.3 이전의 버전에 간헐적으로 문제가 있었다. 그 이후로 나의 연결/연결 해제는 견고했습니다. 또한 소스 코드를 게시하는 것은 SignalR 문제를 진단 할 수있는 필수 요건입니다 (또는 정말로 SO에 게시 한 모든 문제). 마지막으로, 다른 브라우저에서 다른 방식으로 동작하는지 테스트 할 수 있었습니까? – Heather

+0

나는 signalR 버전 0.5.3을 확인했는데, 어떤 이유로 그 일이 계속 일어나고 여러 브라우저 창이 열리고 한 번에 모두 닫히면 문제가 발생합니다. – anthonypliu

+0

@Heather 연결 ID 생성자를 추가했습니다. 문제의 원인이 될 수도 있습니다. – anthonypliu

답변

7

내가 당신의 연결 팩토리가 실제로 문제라고 생각합니다 :

이가 필요한 경우

이 내 접속 아이디 생성기 클래스입니다. 쿠키를 찾지 못하는 경우 새 GUID를 생성하지만 그 시간은 이미 너무 늦었습니다.

제 생각에는 연결 ID는 초기화 중에 클라이언트 (클라이언트 측 허브)에 의해 설정되고 서버에서 변경할 수 없습니다. 그것은 오직 읽을 수 있습니다. 쿠키를 찾지 못했을 때 새로운 GUID를 반환 할 때 사실상 클라이언트 ID가 변경됩니다.

내 연결 팩토리에서 쿠키를 찾을 수없는 경우 throw합니다. signalr을 사용하는 페이지를 여는 컨트롤러 동작에서 쿠키가 심어 졌는지 확인합니다. 사용중인 SignalR의 버전

public class ConnectionFactory : IConnectionIdGenerator 
{ 
    public string GenerateConnectionId(IRequest request) 
    { 
     if (request.Cookies["UserGuid"] != null) 
      return request.Cookies["UserGuid"].Value; 

     throw new ApplicationException("No User Id cookie was found on this browser; you must have cookies enabled to enter."); 
    } 
} 
+0

연결 ID를 만드는 페이지에서 여러 개의 브라우저 창이 열리면 어떻게합니까? 제 경우에는 여러 브라우저 창을 어떻게 처리합니까? 도와 주셔서 다시 한 번 감사드립니다! – anthonypliu

+0

여러 브라우저 인스턴스는 모두 동일한 쿠키에 액세스 할 수 있으므로 발행 할 때마다 쿠키 값을 변경하지 않는 한 모두 동일한 ID를 통해 연결됩니다. 어쨌든 쿠키의 가치는 열려있는 브라우저 창의 수에 관계없이 결국 ID가 될 것이며, 일부 ID가 같고 다른 ID가 다른 경우에는 문제가되지 않습니다. – Heather

관련 문제