본문 바로가기
Software Development/Web Development

닷넷 실시간 업데이트 - signalR 적용해보기

by El스토리 2023. 3. 21.
반응형

웹애플리케이션에 시그널 R을 적용하기 위한 코드를 설명하겠습니다.

시그널 R이란

시그널 R이란 마이크로소프트에서 만든 오픈소스 라이브러리로 실시간 웹 기능을 앱에 추가하는 것을 가능하게 합니다. 클라이언트의 요청에 따라 API가 불러졌을 때에 Hub 클래스를 통해 클라이언트(자바스크립트, 자바, 닷넷 프레임워크 등) 데이터를 실시간으로 업데이트 해줍니다. 특정이벤트에 따른 클라이언트 화면 업데이트가 필요한 앱에 이용될 수 있습니다. 소셜 네트워크, 경매, 지도, 주식 등에서 사용 될 수 있습니다. 저는 대시보드가 필요해서 사용했는데요. 실시간으로 특정 이벤트가 불러졌을 때에 대시보드를 실시간으로 바로 업데이트 할 수 있게 구현해 보았습니다. 제가 프로젝트에 사용하며 직접 구현한 내용을 바탕으로 방법을 자세하게 써 보았습니다. 

백엔드는 닷넷, 프론트엔드는 리액트로 만들어진 어플에 실시간으로 업데이트 되는 화면을 구현해야 한다면 signalR을 적용해야 합니다. 백엔드와 프론트엔드를 구별하여 해야할 일들에 대해 알아보겠습니다.

Microsoft signalR
Microsoft signalR

백엔드

패키지 설치

먼저 프론트엔드에서 신호를 받을 수 있게 백엔드에서 시스템을 구축해야 합니다. nuget 패키지를 먼저 설치해줍니다.

    <PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
    <PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.1" />

웹소켓과 signalR 두개 패키지가 필요합니다. IDE에 맞게 패키지 설치 매니저로 들어가서 두개를 설치해줍니다.

헙 파일 추가

Hub을 상속하는 

using Microsoft.AspNetCore.SignalR;

namespace API.SignalR
{
    public class YourHub : Hub
    {
        public async Task SendNotification(string message)
        {
            await Clients.All.SendAsync("ReceiveNotification", message);
        }
    }
}

Program.cs 수정

페이지가 

혹시 Startup.cs파일이 존재한다면 해당 파일의 적소에 아래 코드를 추가해주세요.  컨트롤러가 애드된 직후 아래코드를 추가해주세요.

builder.Services.AddSignalR();

컨트롤러가 맵 된 직후(app.MapControllers()) 아래코드를 추가해주세요.

app.UseWebSockets();
app.MapHub<YourHub>("/YourHub");

일단 기본적인 세팅은 여기서 끝났습니다. 이제는 원하는 컨트롤러에 hubContext를 추가해주는 작업입니다.

Controller.cs 수정

여러분 API 구성에서 해당 API가 호출될 때 신호를 보내려면 해당 컨트롤러 파일로 들어간 후 컨스트럭터에 아래 코드(Add 부분)를 추가해줍니다.

    public class YourController : Controller
    {
        private readonly DbContext _context;
        private readonly IHubContext<YourHub> _hubContext; // <===== Add

        public ReservationsController(DbContext context, IHubContext<YourHub> hubContext)
        {
            _context = context;
            _hubContext = hubContext; // <===== Add
        }

컨스트럭터에 hubContext 를 추가한후 signalR 커넥션을 추가하고 싶은 메소드 안에 다음과 같은 코드를 추가해줍니다.

await _hubContext.Clients.All.SendAsync("ReceiveNotification", Guid.NewGuid());

Guid.NewGuid() 부분은 늘 새로운 메세지를 보낼 수 있도록 저렇게 설정을 해두었는데요. 간단히 "Database is updated"로 하셔도 되지만 이 경우에는 항상 프론트엔드에서 같은 스트링을 받으므로 변화가 없어서 페이지가 리렌더 되지 않습니다.

프론트엔드

패키지 설치

먼저 마이크로소프트의 signalR 패키지를 설치해줍니다. 노드 패키지 매니저를 사용하고 있다는 가정하에 아래 명령어를 타이핑해주세요.

npm install @microsoft/signalr

업데이트가 잘 된 package.json 파일

패키지 매니저에 signalr이 잘 추가된 것을 확인 할 수 있습니다.

커넥션 만들기

커넥션 오브젝트를 생성해줍니다.

const [notification, setNotification] = useState("");

useEffect(() => {
    // signalR connection
    const connection = new signalR.HubConnectionBuilder()
        .configureLogging(signalR.LogLevel.None)
        .withUrl("/YourHub", {
            skipNegotiation: true,
            transport: signalR.HttpTransportType.WebSockets,
        })
        .build();

    connection.start();

    connection.on("ReceiveNotification", (msg) => {
        setNotification(msg);
    });
}, []);

YourHub부분에 적힌 내용과 클래스명이 같아야 합니다. 그렇게 되면 리액트에서 자바스크립트로 백엔드와 신호를 교류할 수 있게 되어서 닷넷 컨트롤러에 추가된 엔드포인트가 호출될때마다 notification이 업데이트 됩니다. notification의 업데이트 유무에 따라 페이지가 다시 렌더링되어서 실시간으로 변화하는 코드를 작성할 수 있게 됩니다. 가령, useEffect를 하나 더 만들고 디펜던트에 notification을 넣어 노티피케이션이 업데이트 될때마다 특정 코드를 실행하는 것입니다.

정리

  • 백엔드
    • 패키지 설치
    • 헙 클래스 추가
    • program.cs 업데이트
    • 컨트롤러 업데이트
  • 프론트엔드
    • 패키지 설치
    • 커넥션 만들기

이상으로 signalR을 웹앱에 적용하는 방법에 대해 알아보았습니다. 도움이 되셨다면 좋겠네요. 혹시 궁금한 점이 있으시다면 댓글로 알려주세요! 감사합니다.

반응형

댓글