IT개발

MQTT vs SignalR 비교 및 코드 예제

HyochulLab 2025. 3. 17. 14:19

 

 

현대 애플리케이션 개발에서는 실시간 통신이 점점 더 중요해지고 있습니다.

이번 글에서는 C#에서 대표적인 실시간 통신 기술인 MQTTSignalR을 비교하고, 각각의 기술을 이용한 코드 예제를 통해 어떤 상황에서 어느 기술을 선택할 수 있는지 알아보겠습니다.


1. MQTT란?

MQTT(Message Queuing Telemetry Transport) 는 경량 메시징 프로토콜로, 주로 사물인터넷(IoT) 환경에서 센서 데이터나 원격 제어 메시지를 주고받을 때 많이 사용됩니다.

  • 특징:
    • 경량성: 적은 네트워크 대역폭과 리소스를 사용합니다.
    • 퍼블리시/서브스크라이브 모델: 클라이언트는 브로커를 통해 메시지를 발행(publish)하고, 필요한 메시지를 구독(subscribe)할 수 있습니다.
    • 신뢰성: QoS(Quality of Service) 옵션을 제공하여 메시지 전달의 신뢰성을 보장할 수 있습니다.

MQTT 사용 예제 (MQTTnet 라이브러리)

먼저 MQTTnet 라이브러리를 NuGet을 통해 프로젝트에 추가합니다.

using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using System;
using System.Text;
using System.Threading.Tasks;

class MqttExample
{
    public static async Task RunAsync()
    {
        // MQTT 클라이언트 생성
        var factory = new MqttFactory();
        var mqttClient = factory.CreateMqttClient();

        // 연결 옵션 구성
        var options = new MqttClientOptionsBuilder()
            .WithClientId("CSharpClient")
            .WithTcpServer("broker.hivemq.com", 1883) // 공용 MQTT 브로커 사용
            .Build();

        mqttClient.UseConnectedHandler(async e =>
        {
            Console.WriteLine("MQTT 브로커에 연결됨");

            // 토픽 구독
            await mqttClient.SubscribeAsync("test/topic");
            Console.WriteLine("토픽 구독 완료");
        });

        mqttClient.UseDisconnectedHandler(e =>
        {
            Console.WriteLine("MQTT 브로커와 연결 해제됨");
        });

        mqttClient.UseApplicationMessageReceivedHandler(e =>
        {
            string topic = e.ApplicationMessage.Topic;
            string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
            Console.WriteLine($"수신된 메시지 - 토픽: {topic}, 메시지: {payload}");
        });

        // MQTT 브로커에 연결
        await mqttClient.ConnectAsync(options);

        // 메시지 발행 예제
        var message = new MqttApplicationMessageBuilder()
            .WithTopic("test/topic")
            .WithPayload("안녕하세요, MQTT!")
            .WithExactlyOnceQoS()
            .WithRetainFlag()
            .Build();

        await mqttClient.PublishAsync(message);
        Console.WriteLine("메시지 발행 완료");

        // 잠시 대기 후 연결 종료
        await Task.Delay(TimeSpan.FromSeconds(5));
        await mqttClient.DisconnectAsync();
    }

    static async Task Main(string[] args)
    {
        await RunAsync();
    }
}

위 코드는 간단한 MQTT 클라이언트를 구현하여, 브로커에 연결 후 특정 토픽을 구독하고 메시지를 발행하는 예제입니다.


2. SignalR란?

SignalR 은 ASP.NET Core에서 제공하는 라이브러리로, 웹 애플리케이션에 실시간 기능을 쉽게 추가할 수 있도록 돕습니다.

  • 특징:
    • 실시간 양방향 통신: 클라이언트와 서버 간에 즉각적인 메시지 교환이 가능합니다.
    • 자동 재연결: 연결이 끊어지면 자동으로 재연결을 시도합니다.
    • 다양한 전송 프로토콜 지원: WebSocket, Server-Sent Events, Long Polling 등을 상황에 맞게 선택합니다.

SignalR 사용 예제 (ASP.NET Core)

아래는 간단한 SignalR 허브와 클라이언트를 구성하는 예제입니다.

2.1. SignalR Hub 구현

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

public class ChatHub : Hub
{
    // 클라이언트로부터 메시지를 받아 모든 연결된 클라이언트에 전송
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

2.2. Startup.cs 또는 Program.cs 설정 (ASP.NET Core 6 이상)

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// SignalR 서비스 추가
builder.Services.AddSignalR();

var app = builder.Build();

app.MapHub<ChatHub>("/chathub");

app.Run();

2.3. 클라이언트 코드 예제 (JavaScript)

    
            // SignalR 허브 연결 생성
            const connection = new signalR.HubConnectionBuilder()
                .withUrl("/chathub")
                .build();
    
            // 서버로부터 메시지를 수신하면 리스트에 추가
            connection.on("ReceiveMessage", function(user, message) {
                const li = document.createElement("li");
                li.textContent = `${user}: ${message}`;
                document.getElementById("messagesList").appendChild(li);
            });
    
            // 허브 연결 시작
            connection.start().catch(function (err) {
                return console.error(err.toString());
            });
    
            // 메시지 전송 함수
            function sendMessage() {
                const user = document.getElementById("userInput").value;
                const message = document.getElementById("messageInput").value;
                connection.invoke("SendMessage", user, message).catch(function (err) {
                    return console.error(err.toString());
                });
            }
        

    위 예제는 SignalR 허브를 통해 실시간 채팅 기능을 구현한 것입니다. 서버에서 클라이언트에게 메시지를 전파하며, 클라이언트는 JavaScript를 통해 연결 및 메시지 전송/수신을 처리합니다.


    3. MQTT vs SignalR 비교

    사용 목적

    • MQTT:
      • IoT 디바이스 간의 데이터 전송, 원격 센서 데이터 모니터링 등 경량 통신이 필요한 경우 적합합니다.
    • SignalR:
      • 웹 애플리케이션에서 채팅, 실시간 알림, 라이브 대시보드 등 실시간 웹 기능을 구현할 때 유용합니다.

    네트워크 특성

    • MQTT:
      • 브로커 기반: 중간 브로커를 통해 메시지가 라우팅됩니다.
      • 경량 프로토콜: 저전력, 낮은 대역폭 환경에 최적화되어 있습니다.
    • SignalR:
      • 서버-클라이언트 직접 연결: 클라이언트와 서버 간의 직접적인 실시간 통신이 이루어집니다.
      • 다양한 전송 방식: 최적의 전송 프로토콜을 자동으로 선택합니다.

    확장성 및 구현 용이성

    • MQTT:
      • IoT 환경에 최적화되어 있으며, 다양한 언어와 플랫폼에서 사용 가능합니다.
    • SignalR:
      • ASP.NET Core와의 통합이 쉬워 웹 개발자가 빠르게 실시간 기능을 추가할 수 있습니다.

    4. 결론

    각 기술은 목적에 따라 장단점이 있습니다.

    • MQTT 는 경량 프로토콜로 IoT 환경에서 데이터 수집, 센서 통신, 원격 제어 등의 요구사항에 적합하며, 브로커 기반의 아키텍처를 통해 안정적인 메시지 전달을 제공합니다.
    • SignalR 은 ASP.NET Core 환경에서 웹 애플리케이션에 실시간 기능을 손쉽게 추가할 수 있도록 도와주며, 채팅, 알림, 실시간 업데이트 등 웹 사용자 경험 향상에 초점을 맞추고 있습니다.

    개발하려는 애플리케이션의 요구사항과 환경에 맞춰 두 기술 중 하나를 선택하거나, 필요에 따라 두 기술을 조합하여 사용할 수도 있습니다.


    위 예제 코드와 설명을 참고하여 여러분의 프로젝트에 맞는 실시간 통신 솔루션을 선택해 보세요. Happy Coding!