- Flutter에서 MQTT를 이용한 발행(publish) & 구독(subscribe)

 

 

pubspec.yaml 추가

mqtt_client: ^9.6.2

mqtt_client 패키지 추가

 

 

코드 추가

  • MQTT 브로커 설정
Future<void> setupMqtt() async {
    // MQTT 브로커 연결
    client = MqttServerClient.withPort(broker, 'flutter_client', port);
    // MQTT 로그 출력
    client!.logging(on: false);

    // 리스너 등록
    client!.onConnected = onMqttConnected;
    client!.onDisconnected = onMqttDisconnected;
    client!.onSubscribed = onSubscribed;

    try {
      //
      await client!.connect();
    } catch (e) {
      print('Connected Failed.. \nException: $e');
    }
  }

 

 

  • MQTT publish
void publishData(String data) {
    final payload = jsonEncode(data);
    final builder = MqttClientPayloadBuilder();
    builder.addString(payload);

    client!.publishMessage(topic, MqttQos.exactlyOnce, builder.payload!);
  }

 

  • MQTT subscribe
// MQTT 연결 시 토픽 구독.
      client!.subscribe(topic, MqttQos.atLeastOnce);

      // 토픽 수신 리스너
      client!.updates!.listen((List<MqttReceivedMessage<MqttMessage>> c) {
        final MqttPublishMessage recMess = c[0].payload as MqttPublishMessage;
        final String message =
        MqttPublishPayload.bytesToStringAsString(recMess.payload.message);

        // 수신한 메시지 처리
        setState(() {
          print(':: Received message: $message');
        });
      });

 

 

  • 전체코드
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final String broker = /*브로커 주소*/;     // MQTT broker address
  final int port = /*포트*/;                 // MQTT broker port
  final String topic = /*토픽명*/;           // MQTT topic

  MqttServerClient? client;
  bool connected = false;

  @override
  void initState() {
    super.initState();
    setupMqtt();  // MQTT Set
  }

  Future<void> setupMqtt() async {
    // MQTT 브로커 연결
    client = MqttServerClient.withPort(broker, 'flutter_client', port);
    // MQTT 로그 출력
    client!.logging(on: false);

    // 리스너 등록
    client!.onConnected = onMqttConnected;
    client!.onDisconnected = onMqttDisconnected;
    client!.onSubscribed = onSubscribed;

    try {
      //
      await client!.connect();
    } catch (e) {
      print('Connected Failed.. \nException: $e');
    }
  }

  void onMqttConnected() {
    print(':: MqttConnected');
    setState(() {
      connected = true;
      // MQTT 연결 시 토픽 구독.
      client!.subscribe(topic, MqttQos.atLeastOnce);

      // 토픽 수신 리스너
      client!.updates!.listen((List<MqttReceivedMessage<MqttMessage>> c) {
        final MqttPublishMessage recMess = c[0].payload as MqttPublishMessage;
        final String message =
        MqttPublishPayload.bytesToStringAsString(recMess.payload.message);

        // 수신한 메시지 처리
        setState(() {
          print(':: Received message: $message');
        });
      });
    });
  }

  void onMqttDisconnected() {
    print(':: MqttDisconnected');
    setState(() {
      connected = false;
    });
  }

  void onSubscribed(String topic) {
    print(':: Subscribed topic: $topic');
  }

  // 데이터 전송
  void publishData(String data) {
    final payload = jsonEncode(data);
    final builder = MqttClientPayloadBuilder();
    builder.addString(payload);

    client!.publishMessage(topic, MqttQos.exactlyOnce, builder.payload!);
    print(':: Send message: $data');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            connected
                ? Text('CONNECTED')
                : Text('DISCONNECTED'),
            SizedBox(height: 16,),
            ElevatedButton(
                onPressed: () async {
                  publishData('MQTT SEND DATA');
                },
                child: Text('BUTTON'),
            )
          ],
        ),
      ),
    );
  }
}

 

 


  • 앱 실행 시 'topic' 구독 확인

  • 버튼클릭 시 데이터 전송 (발행,구독을 모두 해둔 상태라 같이 보임)

  • MQTT Explorer로 데이터 확인

  • MQTT Explorer에서 데이터 publish 결과

 


+ Recent posts