Blazor 서버에서 브라우저로 사용자 인터페이스를 변경하면 이벤트가 발생합니다.

6792 단어 blazoraspnetdotnet
웹 브라우저와 웹 서버 간의 전형적인 상호작용은 일련의 HTTP 요청과 응답으로 구성된다.HTTP와 반대로 웹소켓은 여러 개의 메시지를 왔다 갔다 보낼 수 있는 지속적인 양방향 연결을 열 것입니다.이것은 서버가 언제든지 클라이언트에게 메시지를 보낼 수 있다는 것을 의미한다.Blazor 서버는 SignalR에, SignalR은 WebSocket 및 기타 기술에 구축됩니다.이러한 기술의 결합으로 Blazor 서버는 클라이언트가 요청하지 않아도 UI 변경 사항을 클라이언트로 전송할 수 있습니다.
클라이언트 이벤트(예를 들어 단추 클릭)가 Blazor 서버로 전송되고 서버가 상태를 변경하고 다시 표시됩니다.그러나 일부 응용 프로그램에서도 다른 곳에서 사건을 일으킬 수 있다.본고에서 이러한 유형의 사건을'서버가 일으킨 사건'이라고 부른다.서버에서 발생하는 이벤트는 트리거될 수 있습니다
  • 웹 API 또는 webhooks
  • 호출
  • 서버와 상호작용하는 다른 사용자
  • 대기열 및 이벤트 버스
  • SQL Server의 조회 알림, 알림 응용 프로그램 데이터 변경
  • 은 Firestore
  • 과 같은 실시간 데이터베이스에서의 데이터 변경 사항을 모니터링합니다.
    이러한 이벤트로 인해 상태가 변경되면 Blazor 서버는 자동으로 구성 요소를 다시 렌더링하지 않습니다.구성 요소 업데이트는 두 가지 문제를 해결해야 합니다.
  • Blazor 서버는 상태 변경 통지를 받아야 합니다.StateHasChanged()으로 전화를 걸어 이 문제를 해결할 수 있습니다.
  • 응답 이벤트의 코드는 렌더링기와 같은 라인에 없을 수 있습니다.StateHasChanged()을 호출하면 무시되거나 렌더링 라인 밖으로 끝날 때 이상이 발생할 수 있습니다.반대로 InvokeAsync에 작업을 전달할 수 있습니다. 이 작업은 오른쪽 라인과 렌더링기의 동기화 상하문에서 호출됩니다.
  • StateHasChanged()에 전송된 작업에서 InvokeAsync을 호출하면 Blazor 서버는 구성 요소를 성공적으로 다시 보여주고 신호기를 사용하여 변경 사항을 브라우저로 전송합니다.
    서버에서 발생하는 이벤트를 시뮬레이션하기 위해 Timer을 사용할 수 있습니다. 이것은 일정 시간마다 코드를 호출합니다.

    서버에서 발생한 이벤트 예


    GitHub Repository에서 예시 코드를 찾을 수 있습니다.
    선행 조건:
  • .순수 코어 3.1 이상 버전 (download here)
  • 다음 절차에 따라 Blazor 서버에서 발생한 이벤트를 시뮬레이션합니다.
  • 다음 명령을 실행하여 새 Blazor 서버 응용 프로그램을 만듭니다.
  • mkdir BlazorServerSample
    cd BlazorServerSample
    dotnet new blazorserver
    
  • 은 다음 코드와 일치하도록 구성 요소 Pages\Counter.razor을 업데이트합니다.
  • @page "/counter"
    @implements IDisposable
    @using System.Timers
    
    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
            Console.WriteLine($"Count incremented: {currentCount}");
        }
    
        private Timer timer;
    
        protected override void OnAfterRender(bool firstRender)
        {
            if (firstRender)
            {
                timer = new Timer();
                timer.Interval = 1000;
                timer.Elapsed += OnTimerInterval;
                timer.AutoReset = true;
                // Start the timer
                timer.Enabled = true;
            }
            base.OnAfterRender(firstRender);
        }
    
        private void OnTimerInterval(object sender, ElapsedEventArgs e)
        {
            IncrementCount();
        }
    
        public void Dispose()
        {
            // During prerender, this component is rendered without calling OnAfterRender and then immediately disposed
            // this mean timer will be null so we have to check for null or use the Null-conditional operator ? 
            timer?.Dispose();
        }
    }
    
    카운터razor는 현재 1000ms (1s) 간격의 타이머를 설정합니다.카운터 페이지를 보고 있으면 초당 IncrementCount()으로 호출합니다.
    다른 페이지로 이동하면 Dispose을 호출하고 정지 간격 때 타이머 자원을 제거합니다.
  • 다음 명령을 실행하여 응용 프로그램을 실행합니다: dotnet run
  • 브라우저를 열고 Blazor 서버 응용 프로그램으로 이동합니다. 보통 https://localhost:5001에 있습니다.
  • 계수기 페이지로 이동하여 변경 사항을 관찰

  • 불행하게도,'현재 계수'는 초마다 한 번씩 바뀌는 것이 아닙니다. 설령 당신이 그것을 이렇게 프로그래밍하더라도.콘솔 출력을 보고 간격이 예상대로 작동하는지 확인할 수 있지만 currentCount 상태 변경이 브라우저에 반영되지 않았습니다.이것은 출력의 모양입니다.
    dotnet run
    # output:
    #   info: Microsoft.Hosting.Lifetime[0]
    #         Now listening on: https://localhost:5001
    #   info: Microsoft.Hosting.Lifetime[0]
    #         Now listening on: http://localhost:5000
    #   info: Microsoft.Hosting.Lifetime[0]
    #         Application started. Press Ctrl+C to shut down.
    #   info: Microsoft.Hosting.Lifetime[0]
    #         Hosting environment: Development
    #   info: Microsoft.Hosting.Lifetime[0]
    #         Content root path: C:\Users\niels\source\repos\BlazorServerEvents
    #   Count incremented: 1
    #   Count incremented: 2
    #   Count incremented: 3
    #   Count incremented: 4
    #   Count incremented: 5
    #   Count incremented: 6
    #   Count incremented: 7
    #   Count incremented: 8
    
    클릭미(Click me) 단추를 누르면 브라우저에 표시된 숫자가 서버의 currentCount에 갑자기 반영됩니다.
    클라이언트 이벤트가 Blazor 서버로 전송될 때, 자신이 어느 라인에 있는지 걱정할 필요도, Blazor 상태 변경을 현저하게 알릴 필요도 없습니다.이 모든 것은 자동으로 발생한 것이다.
    "나를 클릭"단추를 누르면 IncrementCount이 호출되고 currentCount이 추가됩니다. 이 필드는 타이머가 증가함에 따라 증가합니다.그러면 Blazor가 최신 currentCount 상태로 어셈블리를 다시 렌더링합니다.
    클라이언트와 서버에서 상태가 동기화되는지 확인하기 위해 InvokeAsync(() => StateHasChanged());을 타이머 간격 리셋에 추가합니다.업데이트 함수 OnTimerInterval은 다음과 같습니다.
    private void OnTimerInterval(object sender, ElapsedEventArgs e)
    {
        IncrementCount();
        InvokeAsync(() => StateHasChanged());
    }
    
    응용 프로그램을 다시 실행하면 브라우저의 숫자가 초당 증가합니다!

    Blazor 구성 요소 외부에서 발생한 이벤트


    타이머는 Blazor 구성 요소 클래스에서 발생하는 서버에서 발생하는 이벤트를 처리하는 방법을 보여 주지만, 다른 이벤트는 구성 요소 외부에서 발생할 수 있습니다.이 경우 이벤트 데이터를 활성 구성 요소로 보내는 방법은 무엇입니까?이 문제를 해결하는 데는 여러 가지 방법이 있는데, 여기에는 두 가지 건의가 있다.
  • , 만약 사건이 같은 시간 내에 발생한다면.NET 핵심 서버 인스턴스 (비로드 밸런싱) 는 "Blazor.EventAggregator"과 같은 라이브러리를 사용하여 이벤트를 게시/구독할 수 있습니다.이 라이브러리를 사용하면 웹 훅에서 이벤트를 발표하고 Blazor 구성 요소 내의 이벤트를 구독할 수 있습니다.
  • 은 부하가 균형 잡힌 환경에서, 또는 웹 훅이 단독으로 위탁 관리될 때, 많은 이벤트/발표/하위 시스템 (예를 들어 Redis) 중 하나를 사용할 수 있습니다. 이것은 한 서버에서 이벤트를 제출하고 여러 서버에 전달할 수 있도록 합니다.
  • 총결산


    WebSocket은 양방향 영구 연결로 여러 메시지를 보낼 수 있습니다.WebSocket은 서버가 언제든지 클라이언트에게 메시지를 전달할 수 있도록 합니다.Blazor 서버는 Signal에, Signal은 웹소켓에 구축됩니다.Blazor 서버는 지속적인 양방향 연결로 인해 브라우저에서 요청하지 않고도 UI 변경 사항을 브라우저로 전송할 수 있습니다.반대로 사용자 인터페이스의 변경은 서버가 일으킨 이벤트에 의해 촉발될 수 있다.상태 및 UI 변경이 클라이언트로 전송되도록 하려면 InvokeAsync(() => StateHasChanged());을 호출해야 합니다.
    이 반례는 반기후일 수도 있지만, 타이머가 아닌 실시간 데이터베이스를 사용하는 것을 상상해 보세요.Blazor 서버 UI를 실시간으로 다시 렌더링할 수 있습니다!

    좋은 웹페이지 즐겨찾기