Signal R 의 풍부 하고 다채로운 메시지 전송 방식 의 실현 코드

지난 SignalR 글 에 서 는 SignalR 을 통 해 간단 한 대화방 기능 을 구현 하 는 방법 을 시연 했다.간결 함 이 바로 미의 원칙 에 따라 이 편 은 SignalR 에서 의 사용자 와 그룹의 개념 에 대해 이야기 하고 이러한 기초 지식 을 이해 하 는 것 이 SignalR 기반 의 응용 을 더욱 잘 개발 하 는 데 도움 이 된다.사용자 와 그룹 에 대한 이 해 를 통 해 사용자 와 그룹 에 대한 관리,그리고 메시지 전송 의 여러 가지 방식 을 확대 하여 SignalR 에 전면적으로 접속 할 준 비 를 한다.
1.사용자
SignalR 에서 사용 자 는 연결 을 표시 합 니 다.한 사용 자 는 하나의 연결 을 대표 합 니 다.하나의'시스템 사용자'는 여러 개의 연결 신분 을 만 들 수 있 고 함수 클 러 스 터 를 통 해 한 사용자 의 모든 연결 에 메 시 지 를 보 낼 수 있 습 니 다.예 를 들 어 하나의'시스템 사용자'는 여러 개의 연결 을 가진다.이런 연결 은 웹 연결,Android 핸드폰 클 라 이언 트 연결,IOS 핸드폰 클 라 이언 트 연결,또는 다른 클 라 이언 트 연결 이다.'시스템 사용자'는 각각 이런 클 라 이언 트 에 로그 인하 고 여러 개의 연결 을 만 들 었 다.기본 적 인 상황 에서 이 연결 들 은 모두 ClaimTypes.NameIdentifier 를 통 해 Claims Principal 에서 사용자 표지 와 연 결 됩 니 다.
**주의:사용자 식별 자 는 대소 문 자 를 구분 합 니 다.한 고객 의 여러 연결 을 실현 하기 위해 본 사례 는 Claims Identity 로그 인 인 인 인 터 페 이 스 를 간단하게 실현 하여 의외 의 놀 라 움 이 라 고 할 수 있 습 니 다.
1.1 사용자 연결 관리
사용자 가 다 중 연결 을 가 질 수 있다 는 것 을 직관 적 으로 관찰 하기 위해 서 는 로 컬 정적 대상 을 만들어 사용자 연결 을 저장 해 야 합 니 다.

public class WeChatHub : Hub
 {
  public Dictionary<string, List<string>> UserList { get; set; } = new Dictionary<string, List<string>>();

  public void Send(ChatMessage body)
  {
   Clients.All.SendAsync("Recv", body);
  }

  public override Task OnConnectedAsync()
  {
   var userName = this.Context.User.Identity.Name;
   var connectionId = this.Context.ConnectionId;
   if (!UserList.ContainsKey(userName))
   {
    UserList[userName] = new List<string>();
    UserList[userName].Add(connectionId);
   }
   else if (!UserList[userName].Contains(connectionId))
   {
    UserList[userName].Add(connectionId);
   }
   Console.WriteLine(" ,     :{0},{1},{2}", this.Context.UserIdentifier, this.Context.User.Identity.Name, this.Context.ConnectionId);
   return base.OnConnectedAsync();
  }

  public override Task OnDisconnectedAsync(Exception exception)
  {
   var userName = this.Context.User.Identity.Name;
   var connectionId = this.Context.ConnectionId;
   if (UserList.ContainsKey(userName))
   {
    if (UserList[userName].Contains(connectionId))
    {
     UserList[userName].Remove(connectionId);
    }
   }

   Console.WriteLine(" ,     :{0}", this.Context.ConnectionId);
   return base.OnDisconnectedAsync(exception);
  }
 }
위의 코드 는 사용자 의 모든 연결 을 저장 하 는 내부 구성원 UserList 를 포함 하고 있 으 며,사용자 가 SignalR 연결 을 할 때 현재 연결 을 UserList 에 저장 하고,연결 이 끊 겼 을 때 현재 연결 을 UserList 에서 삭제 합 니 다.이렇게 해서 간단 한 사용자 연결 관 리 를 실현 했다.
위의 코드 에서 현재 사용자 닉네임 은 var userName=this.context.User.Identity.Name 에 따 른 것 입 니 다.이 줄 코드 는 이 사용자 의 닉네임 을 얻 기 위해 간단 한 UserIdentity 로그 인 을 한 다음 쿠키 에 사용자 정 보 를 기록 합 니 다.마지막 으로 var userName=this.context.User.Identity.Name;현재 로그 인 사용자 의 닉네임 을 얻 었 습 니 다.(ID 로그 인 절차 에 익숙 한 친구 들 은 낯 설 지 않 을 것 입 니 다.실제로 저도 ID 인증 을 거의 사용 하지 않 습 니 다)
1.2 단일 사용자 에 게 메시지 보 내기

  [Authorize(Roles = "User")]
  [HttpPost("SendToUser")]
  public async Task<IActionResult> SendToUser([FromBody] UserInfoViewModel model)
  {
   ChatMessage message = new ChatMessage()
   {
    Type = 1,
    Content = model.Content,
    UserName = model.UserName
   };

   if (this.chatHub.UserList.ContainsKey(model.UserName))
   {
    var connections = this.chatHub.UserList[model.UserName].First();
    await this.chatHub.Clients.Client(connections).SendAsync("Recv", new object[] { message });
   }

   return Json(new { Code = 0 });
  }
UserController 에서 위의 인터페이스 SendToUser 를 정의 합 니 다.클 라 이언 트 가 사용자 의 닉네임 과 메 시 지 를 전송 한 다음 에 서버 는 ChatHub.UserList 구성원 에 따라 대상 사용자 의 연결 정 보 를 찾 고 마지막 으로 SendAsync 를 통 해 메 시 지 를 대상 클 라 이언 트 연결 에 전달 합 니 다.
2.조 를 나눈다
그룹 을 나 누 는 개념 은 채 팅 방 과 유사 합 니 다.각 방 은 하나의 독립 된 그룹 입 니 다.사용 자 는 A 방 에 가입 할 수도 있 고 B 방 에 가입 할 수도 있 습 니 다.업무 가 허락 되면 한 사용 자 는 여러 개의 그룹(방)에 가입 할 수 있 습 니 다.그룹 을 나 누 어 사용 자 를 관리 하면 하나 이상 의 채 팅 방 을 실현 할 수 있 습 니 다.사용 자 는 그룹 에 가입 할 수 있 습 니 다.그룹 에서 사용 자 를 삭제 할 수도 있 습 니 다.(방 을 떠 나 는 것 과 유사 합 니 다)이곳 의 사용 자 는 진정한 의미 의'시스템 사용자'를 병발 할 수 있 습 니 다.시스템 사용자 가 만 든 SignalR 연결 을 말 합 니 다.
**메모:연결 이 끊 긴 후 다시 연결 을 시작 할 때 SignalR 은 그룹 구성원 신분 을 유지 하지 않 고 그룹 에 다시 가입 해 야 합 니 다.
다음 코드 는 그룹 을 어떻게 조작 하 는 지 보 여 줍 니 다.그룹 을 어떻게 조작 하 는 지 보 여 줍 니 다.주로 세 가지 측면 을 포함 합 니 다.
2.1 그룹 가입

 public async Task AddToGroupAsync(string groupName)
  {
   await Groups.AddToGroupAsync(this.Context.ConnectionId, groupName);
  }
2.2 그룹 을 떠 나 기

 public async Task RemoveFromGroupAsync(string groupName)
  {
   await Groups.RemoveFromGroupAsync(this.Context.ConnectionId, groupName);
  }
2.3 지정 한 그룹 으로 메 시 지 를 보 내기

 public async Task SendToGroupAsync(string groupName, ChatMessage message)
  {
   await Clients.Group(groupName).SendAsync(groupName, new object[] { message });
  }
그룹 을 나 누 는 작업 은 매우 간단 하고 거의 한 줄 의 코드 일 뿐 이 므 로 마이크로소프트 의 패키지 가 정말 좋다 고 말 할 수 밖 에 없다.
3.signalR 의 메 시 지 를 푸 시 하 는 다른 방식
위 에서 사용자 와 그룹 에 대한 학습 을 통 해 다른 푸 시 메 시 지 를 배 우 는 방식 을 확대 하면 매우 이해 하기 쉽 고 손 에 넣 을 수 있 습 니 다.SignalR 내부 에는 여러 가지 푸 시 메 시 지 를 전달 하 는 방식 이 있 습 니 다.그들 은 각각...
3.1 All(전역 푸 시)
3.2 Others(전역 푸 시 자신 제외)
3.3 OthersInGroup(그룹 푸 시 지정,자신 제외)
3.4 AllExcept(지정 목록 을 제외 한 모든 사람)
3.5 데모 코드

 List<string> blackList = new List<string>();
  public async Task OtherSendAsync(ChatMessage body)
  {
   //        Hub           ,     
   await Clients.All.SendAsync("Recv", body);

   //            
   await Clients.Caller.SendAsync("Recv", body);

   //                ,            
   await Clients.Others.SendAsync("Recv", body);

   //             (    ),         ,        
   await Clients.OthersInGroup("groupName").SendAsync("Recv", body);

   //     blackList(   )          
   await Clients.AllExcept(blackList).SendAsync("Recv", body);
  }
4.간단 한 예시
이 예제 코드 는 두 개의 간단 한 인터페이스 를 포함한다.
4.1 로그 인

4.2 다양한 방식 으로 메 시 지 를 보낸다

종결 어
최근 에 오픈 소스 프로젝트 를 하고 있 습 니 다.아직 테스트 단계 에 있 습 니 다.사용 하 는 와 이 키 를 써 서 관심 이 있 는 지 확인 하 세 요.이 싱글 R 시 리 즈 는 비정 기적 으로 업데이트 할 수 밖 에 없습니다.죄송합니다.
데모 코드 다운로드
GitHub 창고 에 위탁 관리 됨
https://github.com/lianggx/Examples/tree/master/SignalR/Ron.SignalRLesson2
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기