Asp.Net Core 는 SignalR 을 사용 하여 서비스 간 호출 방법 예제

인터넷 에서 ASP.NET core 가 Signalr 를 사용 하 는 간단 한 예 를 많이 조 회 했 지만 대부분 간단 한 채 팅 기능 이 었 다.오늘 은 Signalr 를 사용 하여 서비스 간 호출 을 하 는 간단 한 DEMO 를 만 들 었 다.
SignalR 이 무엇 인지 에 대해 서 는 더 이상 말 하지 않 겠 습 니 다.마이크로소프트 공식 문서 도 적지 않 습 니 다.
첫 번 째 새 항목
모든 VS 개발 의 첫 번 째 단 계 는 새로운 솔 루 션 을 만 드 는 것 입 니 다.여 기 는 제 가 새로운 프로젝트 를 만 드 는 방법 을 많이 소개 하지 않 겠 습 니 다~
  • 개발 환경,VS 2017,.NET CORE 2.1
  • asp.net core 프로젝트 두 개 새로 만 들 기 
  • 이렇게 간단 한 조작 은 다 들 아 실 거 예요.
    Signal R 주입
    호출 된 서버 의 Startup.cs 에 SignalR 을 주입 하면 asp.net core 2.1 에 SignalR 라 이브 러 리 가 기본적으로 포함 되 어 있 습 니 다.ConfigureServices방법 에 다음 코드 를 직접 추가 합 니 다.services.AddSignalR().AddMessagePackProtocol() AddMessagePackProtocol()서버 에서 Message Pack 지원 사용 하기
    Hub 클래스 를 계승 하 는 클래스 를 새로 만 듭 니 다.
    
    public class ServerHub : Hub
    {
     }
    클 라 이언 트 에 의 해 실행 되 어야 하 는 방법 을 실현 할 수 있 습 니 다.
    허브 연결 URL 설정Startup.csConfigure에 아래 코드 를 추가 합 니 다.
    
    app.UseSignalR(routes =>
    {
    
      routes.MapHub<ServerHub>("/myserver");
    
    });
    서비스 추가
    서비스 인터페이스 와 인터페이스 구현 클래스 를 추가 하 는 Services 폴 더 를 새로 만 듭 니 다.
    
    public interface IMyService
    
    {
    
      Task<string> SayHello();
    
      Task Sleep();
    
    }
    
    public class MyService : IMyService
    
    {
    
      public async Task<string> SayHello()
    
      {
    
        return await Task.Factory.StartNew(() => "Hello");
    
      }
    
      public async Task Sleep()
    
      {
    
        await Task.Delay(3000);      
    
      }
    
    }
    Startup.cs 의ConfigureServices방법 에서 의존 주입 을 하고AddSignalR()전에 주입 해 야 합 니 다.services.AddScoped<IMyService, MyService>();ServerHub 에 의존 주입 추가
    ServerHub 에 다음 코드 를 추가 합 니 다.
    
    private readonly IServiceProvider _serviceProvider;
    
     public ServerHub(IServiceProvider serviceProvider)
    
     {
    
       _serviceProvider = serviceProvider;
    
     }
    주입 에 의존 하여 지정 한 서 비 스 를 가 져 올 때 까지 사용 해 야 하기 때문에IServiceProvider만 주입 하고IServiceProvider동적 으로 서비스 인 터 페 이 스 를 가 져 옵 니 다.
    반사 동적 으로 서비스 인 터 페 이 스 를 가 져 오고 지정 한 방법 을 실행 합 니 다.
    동적 으로 서 비 스 를 선택 하고 서비스 에 해당 하 는 방법 을 집행 하기 위해 저 희 는 반사 로 동적 으로 얻 습 니 다.여기 서 우 리 는 두 가지 방법 을 추가 합 니 다.하 나 는 반환 값 이 있 고 하 나 는 반환 값 이 없습니다.
    
    public async Task<dynamic> Excute(string serverName,string functionName,object[] parameters)
    
    {
    
      return await Task.Factory.StartNew(() =>
    
      {
    
        var type = Type.GetType(serverName);
    
        var service = _serviceProvider.GetRequiredService(type);
    
        var method = type.GetMethod(functionName);
    
        var resultTask = method.Invoke(service, new object[] { }) as Task;
    
        dynamic result = resultTask.GetType().GetProperty("Result").GetValue(resultTask, null);
    
        return result;
    
      });
    
    }
    
     
    
    public async Task ExcuteWithoutResult(string serverName, string functionName, object[] parameters)
    
    {
    
      var type = Type.GetType(serverName);
    
      var service = _serviceProvider.GetRequiredService(type);
    
      var method = type.GetMethod(functionName);
    
      var resultTask = method.Invoke(service, new object[] { }) as Task;
    
      await resultTask;
    
      var msg = "task done";
    
      await Clients.Caller.SendAsync("callback",msg);
    
    }
    방법 에 세 개의 매개 변 수 를 입력 합 니 다.
  • server Name:서비스 인터페이스 이름(완전한 네 임 스페이스)
  • functionName:방법의 이름
  • parameters:방법 에 필요 한 매개 변수
  • 1.Type.GetType(server Name)을 사용 하여 서비스 인터페이스의 Type 을 가 져 옵 니 다.
    2.사용serviceProvider.GetRequiredService(type)는 의존 주입 에서 대응 하 는 서 비 스 를 가 져 옵 니 다.
    3.type.GetMethod(functionName)를 사용 하여 실행 할 방법 을 가 져 옵 니 다.
    4.실행 방법 method.Invoke(service,new object[]{})
    우리 의 서 비 스 는 비동기 적 인 방법 이기 때문에method.Invoke()은 하나의object대상 으로 돌아 가기 때문에method.Invoke()반환 유형 을Task유형 으로 바 꾸 고 있 습 니 다.resultTask.GetType().GetProperty("Result").GetValue(resultTask, null)는 반사 획득TaskResult속성 을 통 해 해당 하 는 반환 결 과 를 되 돌려 줍 니 다.
    우 리 는 방법 이 되 돌아 오 는Task에서 되 돌아 오 는 결과 유형 이 무엇 인지 모 르 기 때문에 우 리 는 여전히 반사 로Task의 결 과 를 얻 고dynamic로 받는다.
    반환 값 이 없 는 우 리 는Clients.Caller.SendAsync()작업 처리 가 끝 난 후에 호출 자 에 게 메 시 지 를 되 돌려 줍 니 다.
    호출 자 에 SingalRClient 클래스 를 추가 합 니 다.
    
    public class SignalRClient
    
    {
    
      private readonly HubConnection connection;
    
      public SignalRClient()
    
      {
    
        connection = new HubConnectionBuilder()
    
            .WithUrl("http://localhost:5000/myserver")
    
            .AddMessagePackProtocol()
    
            .Build();
    
     
    
        connection.Closed += async (error) =>
    
        {
    
          await Task.Delay(new Random().Next(0, 5) * 1000);
    
          await connection.StartAsync();
    
        };
    
        InitOnMethod();
    
        connection.StartAsync().ConfigureAwait(false).GetAwaiter().GetResult();
    
      }
    
    }
    구조 함수 에서 Signal R 연결 초기 화
    
    WithUrl("http://localhost:5000/myserver")         URL
    AddMessage PackProtocol()은 빠 르 고 간단 한 바 이 너 리 직렬 화 형식 으로 전송 합 니 다.connection.Closed연결 닫 기 이벤트 에 가입 하면 닫 힌 후 자동 으로 다시 연결 합 니 다.InitOnMethod서비스 측의 리 턴 감청 사건 초기 화
    
    private void InitOnMethod()
    
    {
    
      connection.On<string>("callback",(msg)=> {
    
        Console.WriteLine($"------------{msg}----------");
    
      });
    
    }
    connection.StartAsync()연결 을 시작 합 니 다.
    요청 서버 에 두 가지 방법 을 추가 합 니 다.
    하 나 는 반환 값 이 있 고,하 나 는 반환 값 이 없다.
    
    public async Task<dynamic> RequestServer1()
    {
      var result = await connection.InvokeAsync<dynamic>("Excute", "SignalRServer1.Services.IMyService", "SayHello",new object[] { });
      return result;
    }
    
    public async Task RequestWithoutResult()
    {
    
      await connection.SendAsync("ExcuteWithoutResult", "SignalRServer1.Services.IMyService", "Sleep", new object[] { });
    
    }
    반환 값 이 필요 한 우리 가 사용 하 는 방법connection.InvokeAsync()반환 값 이 필요 없 는 우리 가 사용 하 는 방법connection.SendAsync()Signal RClient 를 단일 형식 으로 등록 하여 주입 에 의존 합 니 다.Startup.cs중의ConfigureServices방법 에 첨가services.AddSingleton<SignalRClient>().
    Signal RClient 요청 서비스 사용 하기
    컨트롤 러 에 Signal RClient 주입
    
    private readonly SignalRClient _signalRClient;
    
     
    
    public ValuesController(SignalRClient signalRClient)
    
    {
    
      _signalRClient = signalRClient;
    
    }
    
    // GET api/values
    
    [HttpGet]
    
    public async Task<ActionResult<IEnumerable<string>>> Get()
    
    {
    
      var str = await _signalRClient.RequestServer1().ConfigureAwait(false);
    
      await _signalRClient.RequestWithoutResult().ConfigureAwait(false);
    
      return new string[] { str };
    
    }
    요청 에서 반환 값 이 있 고 반환 값 이 없 는 방법 을 동시에 호출 합 니 다.반환 값 이 없 는 방법 은 작업 이 끝 난 후에 리 셋 을 수행 합 니 다.
    시작 서비스
     
     

    서비스 호출 이 성공 한 task done 을 볼 수 있 습 니 다.
    
    connection.On<string>("callback",(msg)=> {
    
          Console.WriteLine($"------------{msg}----------");
    
        });
    이상 은 제 가 간단하게 만 든 데모 입 니 다.여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

    좋은 웹페이지 즐겨찾기