Skip to content

Commit

Permalink
添加MQTT客户端
Browse files Browse the repository at this point in the history
  • Loading branch information
Nokecy committed Jul 29, 2019
1 parent c436706 commit 8bb03be
Show file tree
Hide file tree
Showing 7 changed files with 352 additions and 8 deletions.
5 changes: 5 additions & 0 deletions config/private.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"broker": "192.168.1.230",
"username": "your username",
"key": "your AIO key"
}
149 changes: 149 additions & 0 deletions lib/pages/mqtt_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import 'package:flutter/material.dart';
import '../util/mqtt/mqtt_stream.dart';
import 'package:mqtt_client/mqtt_client.dart';

class MqttPage extends StatefulWidget {
MqttPage({this.title});
final String title;

@override
MqttPageState createState() => MqttPageState();
}

class MqttPageState extends State<MqttPage> {
final myTopicController = TextEditingController();
final myValueController = TextEditingController();

String _textValue;

@override
void initState() {
AppMqttTransactions.instance.connectToClient().then((value) {
if (value) {
AppMqttTransactions.instance.updates
.listen((List<MqttReceivedMessage<MqttMessage>> c) {
final MqttPublishMessage recMess = c[0].payload;
final String pt =
MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
setState(() {
_textValue = pt;
});
});
}
});
_textValue = "";
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("widget.title"),
),
body: _body(),
);
}

//
// The body of the page. The children contain the main components of
// the UI.
Widget _body() {
return Column(
children: <Widget>[
_subscriptionInfo(),
_subscriptionData(),
_publishInfo(),
],
);
}

//
// The UI to get and subscribe to the mqtt topic.
//
Widget _subscriptionInfo() {
return Container(
margin: EdgeInsets.fromLTRB(20.0, 50.0, 20.0, 20.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(
'Topic:',
style: TextStyle(fontSize: 24),
),
// To use TextField within a row, it needs to be wrapped in a Flexible
// widget. See Stackoverflow: https://bit.ly/2IkzqBk
Flexible(
child: TextField(
controller: myTopicController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter topic to subscribe to',
),
),
),
],
),
RaisedButton(
color: Colors.blue,
textColor: Colors.white,
child: Text('Subscribe'),
onPressed: () {
subscribe(myTopicController.text);
},
),
],
),
);
}

Widget _subscriptionData() {
return Text(_textValue);
}

Widget _publishInfo() {
return Container(
margin: EdgeInsets.fromLTRB(20.0, 50.0, 20.0, 20.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(
'Value:',
style: TextStyle(fontSize: 24),
),
// To use TextField within a row, it needs to be wrapped in a Flexible
// widget. See Stackoverflow: https://bit.ly/2IkzqBk
Flexible(
child: TextField(
controller: myValueController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter value to publish',
),
),
),
],
),
RaisedButton(
color: Colors.blue,
textColor: Colors.white,
child: Text('Publish'),
onPressed: () {
publish(myTopicController.text, myValueController.text);
},
),
],
),
);
}

void subscribe(String topic) {
AppMqttTransactions.instance.subscribe(topic);
}

void publish(String topic, String value) {
AppMqttTransactions.instance.publish(topic, value);
}
}
18 changes: 17 additions & 1 deletion lib/pages/splash/splash_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import '../../util/screen_utils.dart';
import '../container_page.dart';
import '../wifi_page.dart';
import '../mqtt_page.dart';
import '../../constant/constant.dart';

///打开APP首页
Expand All @@ -15,6 +16,7 @@ class SplashWidget extends StatefulWidget {
class _SplashWidgetState extends State<SplashWidget> {
var container = ContainerPage();
var wifiPage = WifiPage();
var mqttPage = MqttPage();

bool showAd = true;

Expand All @@ -37,7 +39,9 @@ class _SplashWidgetState extends State<SplashWidget> {
textColor: Colors.white,
child: Text("蓝牙助手"),
),
Container(width: 30,),
Container(
width: 30,
),
MaterialButton(
onPressed: () {
Navigator.of(context).push(
Expand All @@ -46,6 +50,18 @@ class _SplashWidgetState extends State<SplashWidget> {
color: Colors.blue,
textColor: Colors.white,
child: Text("WIFI智能配置"),
),
Container(
width: 30,
),
MaterialButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => MqttPage()));
},
color: Colors.blue,
textColor: Colors.white,
child: Text("MQTT客户端"),
)
],
),
Expand Down
145 changes: 145 additions & 0 deletions lib/util/mqtt/mqtt_stream.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import 'package:mqtt_client/mqtt_client.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:logging/logging.dart';
// import 'Adafruit_feed.dart';

class AppMqttTransactions {
Logger log;
MqttClient client;

AppMqttTransactions._() {
log = Logger('mqtt_stream.dart');
}

static AppMqttTransactions _instance = new AppMqttTransactions._();
static AppMqttTransactions get instance => _instance;

Stream<List<MqttReceivedMessage<MqttMessage>>> get updates =>
client != null ? client.updates : null;

Future<bool> subscribe(String topic) async {
if (await connectToClient() == true) {
/// 添加断开连接回调
client.onDisconnected = _onDisconnected;

/// 添加连接成功回调
client.onConnected = _onConnected;

///添加订阅成功回调
client.onSubscribed = _onSubscribed;
//订阅主题
_subscribe(topic);
}
return true;
}

//连接到Server
Future<bool> connectToClient() async {
if (client != null &&
client.connectionStatus.state == MqttConnectionState.connected) {
log.info('already logged in');
} else {
client = await _login();
if (client == null) {
return false;
}
}
return true;
}

/// 订阅回调
void _onSubscribed(String topic) {
log.info('Subscription confirmed for topic $topic');
}

/// 断开连接回调
void _onDisconnected() {
log.info('OnDisconnected client callback - Client disconnection');
if (client.connectionStatus.returnCode == MqttConnectReturnCode.solicited) {
log.info(':OnDisconnected callback is solicited, this is correct');
}
client.disconnect();
}

/// 连接成功回调
void _onConnected() {
log.info('OnConnected client callback - Client connection was sucessful');
}

Future<Map> _getBrokerAndKey() async {
String connect =
await rootBundle.loadString('config/private.json', cache: false);
return (json.decode(connect));
}

Future<MqttClient> _login() async {
Map connectJson = await _getBrokerAndKey();
// TBD Test valid broker and key
log.info('in _login....broker : ${connectJson['broker']}');
log.info('in _login....key : ${connectJson['key']}');
log.info('in _login....username: ${connectJson['username']}');

client = MqttClient(connectJson['broker'], connectJson['key']);
// Turn on mqtt package's logging while in test.
client.logging(on: true);
final MqttConnectMessage connMess = MqttConnectMessage()
.authenticateAs(connectJson['username'], connectJson['key'])
.withClientIdentifier('myClientID')
.keepAliveFor(60) // Must agree with the keep alive set above or not set
.withWillTopic(
'willtopic') // If you set this you must set a will message
.withWillMessage('My Will message')
.startClean() // Non persistent session for testing
.withWillQos(MqttQos.atMostOnce);
log.info('Adafruit client connecting....');
client.connectionMessage = connMess;

/// Connect the client, any errors here are communicated by raising of the appropriate exception. Note
/// in some circumstances the broker will just disconnect us, see the spec about this, we however eill
/// never send malformed messages.
try {
await client.connect();
} on Exception catch (e) {
log.severe('EXCEPTION::client exception - $e');
client.disconnect();
client = null;
return client;
}

/// Check we are connected
if (client.connectionStatus.state == MqttConnectionState.connected) {
log.info('Adafruit client connected');
} else {
/// Use status here rather than state if you also want the broker return code.
log.info(
'Adafruit client connection failed - disconnecting, status is ${client.connectionStatus}');
client.disconnect();
client = null;
}
return client;
}

Future _subscribe(String topic) async {
log.info('Subscribing to the topic $topic');
client.subscribe(topic, MqttQos.atMostOnce);
// client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) {
// final MqttPublishMessage recMess = c[0].payload;
// final String pt =
// MqttPublishPayload.bytesToStringAsString(recMess.payload.message);

// // AdafruitFeed.add(pt);
// log.info(
// 'Change notification:: topic is <${c[0].topic}>, payload is <-- $pt -->');
// return pt;
// });
}

Future<void> publish(String topic, String value) async {
if (await connectToClient() == true) {
final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder();
builder.addString(value);
client.publishMessage(topic, MqttQos.atMostOnce, builder.payload);
}
}
}
1 change: 0 additions & 1 deletion lib/widgets/ble_log.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';

class LogItem {
LogItem({this.time, this.msg});
Expand Down
Loading

0 comments on commit 8bb03be

Please sign in to comment.