21_MQTT協議_客戶端和服務端

甜饼怪2030發表於2024-03-12

MQTT程式_客戶端和服務端

服務端

using System;
using System.Net;
using System.Threading.Tasks;
using DotNetty.Buffers;
using DotNetty.Channel;
using DotNetty.Channel.Sockets;
using DotNetty.Handlers.Logging;
using DotNetty.Transport.Tcp;

class MqttServer
{
    static async Task Main(string[] args)
    {
        // 建立服務端載入程式
        var bootstrap = new ServerBootstrap();

        // 配置服務端
        bootstrap.Group(new MultithreadEventLoopGroup())
            .Channel<TcpServerSocket>()
            .LocalAddress(IPAddress.Any, 1883)
            .Handler(new LoggingHandler("server"))
            .ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>
            {
                // 新增編解碼器
                channel.Pipeline.AddLast(new MqttDecoder());
                channel.Pipeline.AddLast(new MqttEncoder());

                // 新增處理器
                channel.Pipeline.AddLast(new MqttServerHandler());
            }));

        // 繫結埠並啟動服務端
        await bootstrap.BindAsync();

        // 等待服務端關閉
        Console.WriteLine("MQTT Server started at port 1883");
        await Task.Delay(int.MaxValue);
    }
}

class MqttServerHandler : ChannelHandlerAdapter
{
    public override void ChannelRead(IChannelHandlerContext context, object message)
    {
        // 將接收到的訊息原樣返回給客戶端
        context.WriteAsync(message);
    }
}

客戶端

using System;
using System.Net;
using System.Threading.Tasks;
using DotNetty.Buffers;
using DotNetty.Channel;
using DotNetty.Channel.Sockets;
using DotNetty.Handlers.Logging;
using DotNetty.Transport.Tcp;

class MqttClient
{
    static async Task Main(string[] args)
    {
        // 建立客戶端載入程式
        var bootstrap = new Bootstrap();

        // 配置客戶端
        bootstrap.Group(new MultithreadEventLoopGroup())
            .Channel<TcpSocketChannel>()
            .RemoteAddress(IPAddress.Loopback, 1883)
            .Handler(new LoggingHandler("client"))
            .ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>
            {
                // 新增編解碼器
                channel.Pipeline.AddLast(new MqttDecoder());
                channel.Pipeline.AddLast(new MqttEncoder());

                // 新增處理器
                channel.Pipeline.AddLast(new MqttClientHandler());
            }));

        // 連線到服務端
        await bootstrap.ConnectAsync();

        // 釋出訊息
        await channel.WriteAsync(new MqttApplicationMessage
        {
            Topic = "topic/test",
            Payload = Encoding.UTF8.GetBytes("Hello, world!")
        });

        // 訂閱主題
        await channel.WriteAsync(new MqttSubscribeMessage
        {
            Topics = new[] { new MqttTopicFilter { Topic = "topic/test" } }
        });

        // 接收訊息
        while (true)
        {
            var message = await channel.ReadAsync();

            Console.WriteLine(message.Topic);
            Console.WriteLine(Encoding.UTF8.GetString(message.Payload));
        }
    }
}

class MqttClientHandler : ChannelHandlerAdapter
{
    public override void ChannelRead(IChannelHandlerContext context, object message)
    {
        // 將接收到的訊息原樣返回給客戶端
        context.WriteAsync(message);
    }
}

該程式的功能如下:

  • 服務端監聽 TCP 埠 1883,等待客戶端連線。
  • 客戶端連線到服務端後,可以釋出訊息和訂閱主題。
  • 服務端將接收到的訊息轉發給所有訂閱該主題的客戶端。

相關文章