I am unable to get messages on subscribe. what am I doing wrong?
I am able to register a connection to the broker. I just can't emit any thing in client.updates.listen.
also what is the difference between MqttPublishMessage and MqttSubscribeMessage?
import 'dart:async';
import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
final client = MqttServerClient.withPort('ws://192.168.43.56', 'cliendId', 8080,);
Future<int> main() async {
/// Set logging on if needed, defaults to off
client.logging(on: false);
client.keepAlivePeriod = 20;
client.port = 8080;
client.useWebSocket = true;
client.onDisconnected = onDisconnected;
client.onConnected = onConnected;
client.onSubscribed = onSubscribed;
client.pongCallback = pong;
final connMess = MqttConnectMessage()
.withClientIdentifier('client_id')
.keepAliveFor(60) // Must agree with the keep alive set above or not set
.startClean() // Non persistent session for testing
.withWillQos(MqttQos.atLeastOnce);
print('EXAMPLE::Mosquitto client connecting....');
client.connectionMessage = connMess;
try {
await client.connect();
} on Exception catch (e) {
print('EXAMPLE::client exception - $e');
client.disconnect();
}
/// Check we are connected
if (client.connectionStatus.state == MqttConnectionState.connected) {
print('EXAMPLE::Mosquitto client connected');
} else {
/// Use status here rather than state if you also want the broker return code.
print(
'EXAMPLE::ERROR Mosquitto client connection failed - disconnecting, status is ${client.connectionStatus}');
client.disconnect();
return -1;
}
/// Ok, lets try a subscription
print('EXAMPLE::Subscribing to the test/lol topic');
const topic = '/busline/201'; // Not a wildcard topic
client.subscribe(topic, MqttQos.exactlyOnce);
client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) {
final MqttPublishMessage recMess = c[0].payload;
final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
print(
'EXAMPLE::Change notification:: topic is <${c[0].topic}>, payload is <-- $pt -->');
print('');
});
print('EXAMPLE::Sleeping....');
await MqttUtilities.asyncSleep(120);
}
/// The subscribed callback
void onSubscribed(String topic) {
print('EXAMPLE::Subscription confirmed for topic $topic');
}
/// The unsolicited disconnect callback
void onDisconnected() {
print('EXAMPLE::OnDisconnected client callback - Client disconnection');
if (client.connectionStatus.disconnectionOrigin ==
MqttDisconnectionOrigin.solicited) {
print('EXAMPLE::OnDisconnected callback is solicited, this is correct');
}
}
/// The successful connect callback
void onConnected() {
print(
'EXAMPLE::OnConnected client callback - Client connection was sucessful');
}
/// Pong callback
void pong() {
print('EXAMPLE::Ping response client callback invoked');
}
you can do like this
// connection succeeded
void onConnected() {
print('Connected');
}
// unconnected
void onDisconnected() {
print('Disconnected');
}
// subscribe to topic succeeded
void onSubscribed(String topic) {
print('Subscribed topic: $topic');
}
// subscribe to topic failed
void onSubscribeFail(String topic) {
print('Failed to subscribe $topic');
}
// unsubscribe succeeded
void onUnsubscribed(String topic) {
print('Unsubscribed topic: $topic');
}
// PING response received
void pong() {
print('Ping response client callback invoked');
}
var data;
Future<MqttServerClient> connect() async {
MqttServerClient client = MqttServerClient.withPort(
'broker', "client something unique", port);
client.logging(on: false);
client.onConnected = onConnected;
client.onDisconnected = onDisconnected;
// client.onUnsubscribed = onUnsubscribed;
client.onSubscribed = onSubscribed;
client.onSubscribeFail = onSubscribeFail;
client.pongCallback = pong;
final connMessage = MqttConnectMessage()
.authenticateAs('Enter Client Id', 'Enter Password')
.withClientIdentifier("something unique match with client")
.startClean()
// .withWillRetain()
.withWillQos(MqttQos.atLeastOnce);
client.connectionMessage = connMessage;
try {
await client.connect();
// client.unsubscribe('topic/');
client.subscribe('topic/', MqttQos.atLeastOnce);
} catch (e) {
print('Exception: $e');
client.disconnect();
}
client.updates!.listen((List<MqttReceivedMessage<MqttMessage>> c) {
final MqttPublishMessage message = c[0].payload as MqttPublishMessage;
final payload =
MqttPublishPayload.bytesToStringAsString(message.payload.message);
data = jsonDecode(payload);
print('Received message:$payload from topic: ${c[0].topic}>');
});
return client;
}
Related
I've initialized a WebSocket connection and I'm listening to stream which I've defined as asBroadcastStream so it does not return stream has already been listened to listening for events from same stream.
Stream is listening to same message multiple times.
For example
On 1st message
Stream prints data 1 time
On 2nd message
Stream prints data 2 times
On 3rd message
Stream prints data 3 times
... and so on.
class NotificationController {
static final NotificationController _singleton =
NotificationController._internal();
StreamController<String> streamController =
StreamController.broadcast(sync: true);
IOWebSocketChannel? channel;
late var channelStream = channel?.stream.asBroadcastStream();
factory NotificationController() {
return _singleton;
}
NotificationController._internal() {
initWebSocketConnection();
}
initWebSocketConnection() async {
var storedUserInfo = storage.getUserInfoStorage();
Map storedData = await storedUserInfo;
String userID = storedData['user_id'];
print("conecting...");
try {
channel = IOWebSocketChannel.connect(
Uri.parse('ws://127.0.0.1:8001/chat/$userID/'),
pingInterval: const Duration(seconds: 10),
);
} on Exception catch (e) {
print(e);
return await initWebSocketConnection();
}
print("socket connection initializied");
channel?.sink.done.then((dynamic _) => _onDisconnected());
}
void sendMessage(messageObject, Function messageListener) {
try {
channel?.sink.add(json.encode(messageObject));
var mystream = channelStream?.listen((data) {
print(data);
Map message = json.decode(data);
messageListener(message);
});
} on Exception catch (e) {
print(e);
}
}
void _onDisconnected() {
initWebSocketConnection();
}
}
You may be initializing the listener multiple times.
put your code where your initialized code is called only once may be initState method or globally.
I subscribe to a graphql document:
// Dart imports:
import 'dart:async';
// Package imports:
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:phoenix_socket/phoenix_socket.dart';
// Project imports:
import 'package:core/util/confirmations/phoenix_link.dart';
class SubscriptionChannel {
PhoenixSocket? socket;
PhoenixChannel? channel;
GraphQLClient? client;
final StreamController<Map> _onMessageController = StreamController<Map>();
Stream<Map> get onMessage => _onMessageController.stream;
Future<void> connect(
String phoenixHttpLinkEndpoint, String websocketUriEndpoint) async {
final HttpLink phoenixHttpLink = HttpLink(
phoenixHttpLinkEndpoint,
);
channel =
await PhoenixLink.createChannel(websocketUri: websocketUriEndpoint);
final phoenixLink = PhoenixLink(
channel: channel!,
);
var link = Link.split(
(request) => request.isSubscription, phoenixLink, phoenixHttpLink);
client = GraphQLClient(
link: link,
cache: GraphQLCache(),
);
}
void addSubscriptionTransactionConfirmed(
String address, Function(QueryResult) function) {
final subscriptionDocument = gql(
'subscription { transactionConfirmed(address: "$address") { nbConfirmations } }',
);
Stream<QueryResult> subscription = client!.subscribe(
SubscriptionOptions(document: subscriptionDocument),
);
subscription.listen(function);
}
Future<Message> onPushReply(Push push) async {
final Completer<Message> completer = Completer<Message>();
final Message result = await channel!.onPushReply(push.replyEvent);
completer.complete(result);
return completer.future;
}
void close() {
_onMessageController.close();
if (socket != null) {
socket!.close();
}
}
}
The goal is, after a api request, to wait a notification with a nb of confirmations:
{
...
await subscriptionChannel.connect(
'https://mainnet.archethic.net/socket/websocket',
'ws://mainnet.archethic.net/socket/websocket');
subscriptionChannel.addSubscriptionTransactionConfirmed(
transaction.address!, waitConfirmations);
transactionStatus = sendTx(signedTx); // API Request
...
}
void waitConfirmations(QueryResult event) {
if (event.data != null &&
event.data!['transactionConfirmed'] != null &&
event.data!['transactionConfirmed']['nbConfirmations'] != null) {
EventTaxiImpl.singleton().fire(TransactionSendEvent(
response: 'ok',
nbConfirmations: event.data!['transactionConfirmed']
['nbConfirmations']));
} else {
EventTaxiImpl.singleton().fire(
TransactionSendEvent(nbConfirmations: 0, response: 'ko'),
);
}
subscriptionChannel.close();
}
My code works in a StatefulWidget but doesn't work in a class
Have you got some examples in a class where you subscribe to a grapqhql notification please to understand how to code this in a class
NB: i'm using Phoenix link
// Dart imports:
import 'dart:async';
// Package imports:
import 'package:gql_exec/gql_exec.dart';
import 'package:gql_link/gql_link.dart';
import 'package:phoenix_socket/phoenix_socket.dart';
/// a link for subscriptions (or also mutations/queries) over phoenix channels
class PhoenixLink extends Link {
/// the underlying phoenix channel
final PhoenixChannel channel;
final RequestSerializer _serializer;
final ResponseParser _parser;
/// create a new [PhoenixLink] using an established PhoenixChannel [channel].
/// You can use the static [createChannel] method to create a [PhoenixChannel]
/// from a websocket URI and optional parameters (e.g. for authentication)
PhoenixLink(
{required PhoenixChannel channel,
ResponseParser parser = const ResponseParser(),
RequestSerializer serializer = const RequestSerializer()})
: channel = channel,
_serializer = serializer,
_parser = parser;
/// create a new phoenix socket from the given websocketUri,
/// connect to it, and create a channel, and join it
static Future<PhoenixChannel> createChannel(
{required String websocketUri, Map<String, String>? params}) async {
final socket = PhoenixSocket(websocketUri,
socketOptions: PhoenixSocketOptions(params: params));
await socket.connect();
final channel = socket.addChannel(topic: '__absinthe__:control');
final push = channel.join();
await push.future;
return channel;
}
#override
Stream<Response> request(Request request, [NextLink? forward]) async* {
assert(forward == null, '$this does not support a NextLink (got $forward)');
final payload = _serializer.serializeRequest(request);
String? phoenixSubscriptionId;
StreamSubscription<Response>? websocketSubscription;
StreamController<Response>? streamController;
final push = channel.push('doc', payload);
try {
final pushResponse = await push.future;
//set the subscription id in order to cancel the subscription later
phoenixSubscriptionId =
pushResponse.response['subscriptionId'] as String?;
if (phoenixSubscriptionId != null) {
//yield all messages for this subscription
streamController = StreamController();
websocketSubscription = channel.socket
.streamForTopic(phoenixSubscriptionId)
.map((event) => _parser.parseResponse(
event.payload!['result'] as Map<String, dynamic>))
.listen(streamController.add, onError: streamController.addError);
yield* streamController.stream;
} else if (pushResponse.isOk) {
yield _parser
.parseResponse(pushResponse.response as Map<String, dynamic>);
} else if (pushResponse.isError) {
throw _parser.parseError(pushResponse.response as Map<String, dynamic>);
}
} finally {
await websocketSubscription?.cancel();
await streamController?.close();
//this will be called once the caller stops listening to the stream
// (yield* stops if there is no one listening)
if (phoenixSubscriptionId != null) {
channel.push('unsubscribe', {'subscriptionId': phoenixSubscriptionId});
}
}
}
}
I'm having trouble connecting to mqtt in flutter. I can't connect. The code I am using is as follows.
import 'package:mqtt_client/mqtt_server_client.dart';
late MqttServerClient client;
// ignore: camel_case_types
class mqttconnect {
Future<MqttServerClient> connect() async {
try {
client =
MqttServerClient.withPort('broker.emqx.io', 'flutter_client', 1883);
client.logging(on: true);
client.onConnected = onConnected;
client.onDisconnected = onDisconnected;
} catch (e) {
print(e.toString());
}
try {
await client.connect();
} catch (e) {
print('Exception: $e');
client.disconnect();
}
return client;
}
void onConnected() {
print('object');
}
void onDisconnected() {}
}
While trying to connect to mqtt, I get an error as above in the console. How can I fix.
import 'dart:convert';
import 'dart:developer';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
late MqttServerClient client;
mqttSubscribe() async {
client = MqttServerClient.withPort("broker.emqx.io", "daly", 1883);
client.keepAlivePeriod = 30;
client.autoReconnect = true;
await client.connect().onError((error, stackTrace) {
log("error -> " + error.toString());
});
client.onConnected = () {
log('MQTT connected');
};
client.onDisconnected = () {
log('MQTT disconnected');
};
client.onSubscribed = (String topic) {
log('MQTT subscribed to $topic');
};
if (client.connectionStatus!.state == MqttConnectionState.connected) {
client.subscribe("battery", MqttQos.atMostOnce);
client.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) {
final recMess = c![0].payload as MqttPublishMessage;
final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
log("message payload => " + pt);
});
}
}
import 'dart:async';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
class MqttService{
MqttService._();
/// Our mqtt client object.
static late MqttClient client;
// for listen from other pages.
// and can close listen mqtt.
static StreamSubscription? mqttListen;
static void initMqtt(){
/// Initialize Mqtt and connect.
client = MqttServerClient(/* Your mqtt host address */)
..logging(on: false)
..port = MqttConstants.mqttPort
..keepAlivePeriod = 20
..onDisconnected = _onDisconnected
..onSubscribed = _onSubscribed
..onConnected = _onConnected
..onUnsubscribed = _onUnsubscribed
..onSubscribeFail = _onSubscribeFail;
/// If the mqtt connection lost
/// MqttBroker publish this message on this topic.
final mqttMsg = MqttConnectMessage()
.withWillMessage('connection-failed')
.withWillTopic('willTopic')
.startClean()
.withWillQos(MqttQos.atLeastOnce)
.withWillTopic('failed');
client.connectionMessage = mqttMsg;
await _connectMqtt();
}
/// Mqtt server connected.
void _onConnected() {
log('Connected');
_listenMqtt();
}
/// Mqtt server disconnected
void _onDisconnected() {
log('Disconnected');
}
/// Mqtt server subscribed
void _onSubscribed(String? topic) {
log('Subscribed topic is : $topic');
}
void _onUnsubscribed(String? topic) {
log('Unsubscribed topic is : $topic');
}
void _onSubscribeFail(String? topic) {
log('Failed subscribe topic : $topic');
}
/// Connection MQTT Server.
Future<void> _connectMqtt() async {
if (client.connectionStatus!.state != MqttConnectionState.connected) {
try {
await client.connect();
} catch (e) {
log('Connection failed' + e.toString());
}
} else {
log('MQTT Server already connected ');
}
}
/// Diconnection MQTT Server.
static Future<void> disconnectMqtt() async {
if (client.connectionStatus!.state == MqttConnectionState.connected) {
try {
client.disconnect();
} catch (e) {
log('Disconnection Failed ' + e.toString());
}
} else {
log('MQTT Server already disconnected ');
}
}
/// Subscribe a topic
static void subscribeTopic(String topic) {
final state = client.connectionStatus?.state;
if (state != null) {
if (state == MqttConnectionState.connected) {
client.subscribe(topic + "/data", MqttQos.atLeastOnce);
}
}
}
/// Publish a message to topic
/// [reatain] means last message save the broker.
static void publish(String topic, String message, {bool retain = true}) {
final builder = MqttClientPayloadBuilder();
builder.addString(message);
client.publishMessage(
topic,
MqttQos.atLeastOnce,
builder.payload!,
retain: retain,
);
builder.clear();
}
static void unSubscribeTopic(String topic) {
final state = client.connectionStatus?.state;
if (state != null) {
if (state == MqttConnectionState.connected) {
client.unsubscribe(topic + "/data");
}
}
}
static void onClose(){
mqttListen?.close();
disconnectMqtt();
}
void _listenMqtt() {
mqttListen = client.updates!.listen((dynamic t) {
MqttPublishMessage recMessage = t[0].payload;
final message =
MqttPublishPayload.bytesToStringAsString(recMessage.payload.message);
/*
Listen subscribe topic.
*/
log(message);
});
}
}
I have created a nice format for MQTT and I wanted to share with you through this question.
Package: mqtt_client
I'm implementing socket.
Two clients connect to the server with no problem, when client1 sends a message to the server, the server publishes it to every other client (which in this case is client2). but client2 won't get the message unless it sends a message. It seems the listener of the client doesn't work. Obviously, I want client2 to get the message from client1 instantly.
here is my sever code:
import 'dart:io';
import 'dart:typed_data';
void main() async {
// bind the socket server to an address and port
MySocket mySocket = MySocket();
await mySocket.init();
}
class MySocket {
ServerSocket? server;
List<Socket> clients = [];
//initialize the socket
init() async {
server = await ServerSocket.bind("192.168.0.112", 4000);
// listen for client connections to the server
server!.listen((client) {
handleConnection(client);
addClient(client);
});
}
void handleConnection(Socket client) async {
print('Connection from'
' ${client.remoteAddress.address}:${client.remotePort}');
// listen for events from the client
client.listen(
// handle data from the client
(Uint8List data) async {
await Future.delayed(Duration(seconds: 1));
final message = String.fromCharCodes(data);
print(message);
publish(message, client);
},
// handle errors
onError: (error) {
print(error);
client.close();
},
// handle the client closing the connection
onDone: () {
print('Client left');
client.close();
},
);
}
void addClient(Socket client) {
//if client doesn't already exist add it to the list of clients
if (!clients.any((element) =>
'${client.remoteAddress.address}:${client.remotePort}' ==
'${element.remoteAddress.address}:${element.remotePort}')) {
clients.add(client);
}
}
void publish(String message, Socket client) {
//write the message to every client except the author of it
clients.forEach((element) async {
if ('${client.remoteAddress.address}:${client.remotePort}' !=
'${element.remoteAddress.address}:${element.remotePort}') {
element.write(message);
}
});
}
}
here is my client-side code:
import 'dart:io';
import 'dart:typed_data';
void main() async {
//gets the username
String name = '';
while (name.isEmpty) {
print('Enter your name: ');
name = stdin.readLineSync() ?? '';
}
// connect to the socket server
final socket = await Socket.connect("192.168.0.112", 4000);
print('Connected to: ${socket.remoteAddress.address}:${socket.remotePort}');
// listen for responses from the server
socket.listen(
// handle data from the server
(Uint8List data) {
final serverResponse = String.fromCharCodes(data);
print('$serverResponse');
},
// handle errors
onError: (error) {
print(error);
socket.destroy();
},
// handle server ending connection
onDone: () {
print('Left server.');
socket.destroy();
},
);
// sending messages to the server
String message = "";
while (message != "exit") {
message = stdin.readLineSync() ?? '';
await sendMessage(socket, name, message);
}
socket.close();
}
Future<void> sendMessage(Socket socket, String name, String message) async {
socket.write('$name: $message');
await Future.delayed(Duration(seconds: 2));
}
Thank you in advance.
The issue is because stdin.readLineSync() in your client blocks the current thread. You can get around this by spawning an isolate to handle that portion of the code, so that it does not block the socket.listen from printing out the responses from the server.
See updated client code below:
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';
void main() async {
//gets the username
String name = '';
while (name.isEmpty) {
print('Enter your name: ');
name = stdin.readLineSync() ?? '';
}
// connect to the socket server
final socket = await Socket.connect("192.168.0.112", 4000);
print('Connected to: ${socket.remoteAddress.address}:${socket.remotePort}');
// listen for responses from the server
socket.listen(
// handle data from the server
(Uint8List data) {
final serverResponse = String.fromCharCodes(data);
print('$serverResponse');
},
// handle errors
onError: (dynamic error) {
print(error);
socket.destroy();
},
// handle server ending connection
onDone: () {
print('Left server.');
socket.destroy();
},
);
final receive = ReceivePort();
final isolate = await Isolate.spawn(readMessages, receive.sendPort);
await for (final message in receive) {
if (message == 'exit') break;
await sendMessage(socket, name, message as String);
}
socket.close();
}
void readMessages(SendPort port) {
String message = '';
while (message != 'exit') {
message = stdin.readLineSync() ?? '';
port.send(message);
}
Isolate.exit(port);
}
Future<void> sendMessage(Socket socket, String name, String message) async {
socket.write('$name: $message');
await Future<void>.delayed(Duration(seconds: 2));
}
I want to connect mqtt using wss protocol.
What have I tried ->
import 'dart:async';
import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
final client = MqttServerClient('wss://myServer.com/mqtt', '');
Future<int> main() async {
client.useWebSocket = true;
client.port = 8083;
client.logging(on: true);
client.keepAlivePeriod = 20;
client.onDisconnected = onDisconnected;
client.onConnected = onConnected;
client.onSubscribed = onSubscribed;
client.pongCallback = pong;
final connMess = MqttConnectMessage()
.withClientIdentifier('Mqtt_MyClientUniqueId')
.keepAliveFor(20)
.withWillTopic('willtopic')
.withWillMessage('My Will message')
.startClean()
.withWillQos(MqttQos.atLeastOnce);
print('EXAMPLE::Mosquitto client connecting....');
client.connectionMessage = connMess;
try {
await client.connect();
} on NoConnectionException catch (e) {
print('EXAMPLE::client exception - $e');
client.disconnect();
} on SocketException catch (e) {
print('EXAMPLE::socket exception - $e');
client.disconnect();
}
/// Check we are connected
if (client.connectionStatus.state == MqttConnectionState.connected) {
print('EXAMPLE::Mosquitto client connected');
} else {
print(
'EXAMPLE::ERROR Mosquitto client connection failed - disconnecting, status is
${client.connectionStatus}');
client.disconnect();
exit(-1);
}
print('EXAMPLE::Subscribing to the test/lol topic');
const topic = 'test/lol';
client.subscribe(topic, MqttQos.atMostOnce);
client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) {
final MqttPublishMessage recMess = c[0].payload;
final pt =
MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
print(
'EXAMPLE::Change notification:: topic is <${c[0].topic}>, payload is <-- $pt -->');
print('');
});
client.published.listen((MqttPublishMessage message) {
print(
'EXAMPLE::Published notification:: topic is ${message.variableHeader.topicName}, with Qos ${message.header.qos}');
});
const pubTopic = 'Dart/Mqtt_client/testtopic';
final builder = MqttClientPayloadBuilder();
builder.addString('Hello from mqtt_client');
print('EXAMPLE::Subscribing to the Dart/Mqtt_client/testtopic topic');
client.subscribe(pubTopic, MqttQos.exactlyOnce);
print('EXAMPLE::Publishing our topic');
client.publishMessage(pubTopic, MqttQos.exactlyOnce, builder.payload);
print('EXAMPLE::Sleeping....');
await MqttUtilities.asyncSleep(120);
print('EXAMPLE::Unsubscribing');
client.unsubscribe(topic);
await MqttUtilities.asyncSleep(2);
print('EXAMPLE::Disconnecting');
client.disconnect();
return 0;
}
void onSubscribed(String topic) {
print('EXAMPLE::Subscription confirmed for topic $topic');
}
void onDisconnected() {
print('EXAMPLE::OnDisconnected client callback - Client disconnection');
if (client.connectionStatus.disconnectionOrigin ==
MqttDisconnectionOrigin.solicited) {
print('EXAMPLE::OnDisconnected callback is solicited, this is correct');
}
exit(-1);
}
void onConnected() {
print(
'EXAMPLE::OnConnected client callback - Client connection was sucessful');
}
void pong() {
print('EXAMPLE::Ping response client callback invoked');
}
and I get below response in logs
EXAMPLE::Mosquitto client connecting....
I/flutter (17123): 1-2021-01-27 15:15:27.085221 -- MqttConnectionHandlerBase::connect - server wss://myServer.com/mqtt, port 1883
I/flutter (17123): 1-2021-01-27 15:15:27.103638 -- SynchronousMqttServerConnectionHandler::internalConnect entered
I/flutter (17123): 1-2021-01-27 15:15:27.104865 -- SynchronousMqttServerConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress false
I/flutter (17123): 1-2021-01-27 15:15:27.107198 -- SynchronousMqttServerConnectionHandler::internalConnect - websocket selected
I/flutter (17123): 1-2021-01-27 15:15:27.110498 -- SynchronousMqttServerConnectionHandler::internalConnect - calling connect
I/flutter (17123): 1-2021-01-27 15:15:27.117350 -- MqttWsConnection::connect - entered
I/flutter (17123): 1-2021-01-27 15:15:27.168054 -- MqttWsConnection::connect - WS URL is wss://myServer.com:1883/mqtt, protocols are [mqtt, mqttv3.1, mqttv3.11]
I/flutter (17123): 1-2021-01-27 15:17:37.221102 -- MqttConnectionBase::_onError - calling disconnected callback
I/flutter (17123): EXAMPLE::socket exception - SocketException: OS Error: Connection timed out, errno = 110, address = myServer.com, port = 32892
I/flutter (17123): 1-2021-01-27 15:17:37.243831 -- MqttConnectionHandlerBase::disconnect - entered
I/flutter (17123): 1-2021-01-27 15:17:37.245454 -- MqttConnectionHandlerBase::_performConnectionDisconnect entered
I/flutter (17123): EXAMPLE::OnDisconnected client callback - Client disconnection
it made me tired but this code is working
please don't 'secure = true'
this is set to 'web socket base'
class MqttConnection {
static MqttConnection? _mqttConnection;
static MqttServerClient? _mqttClient;
MqttConnection._() {
_mqttClient =
MqttServerClient("wss://your domain/", "flutter_client");
_mqttClient!.port = 9001;
_mqttClient!.keepAlivePeriod = 20;
_mqttClient!.autoReconnect = true;
_mqttClient!.onConnected = _mqttConnected;
_mqttClient!.onDisconnected = _mqttDisconnected;
_mqttClient!.useWebSocket = true;
_mqttClient!.logging(on: true);
}
static MqttConnection getInstanse() {
if (_mqttConnection != null) return _mqttConnection!;
if (_mqttConnection == null) _mqttConnection = MqttConnection._();
return _mqttConnection!;
}
Future connectMqtt() async {
final MqttConnectMessage connMess = MqttConnectMessage()
.authenticateAs(ApiConstant.mqttUser, ApiConstant.mqttPassword)
.withClientIdentifier((await _getDeviceId())!)
.withWillQos(MqttQos.atLeastOnce)
.startClean();
_mqttClient!.connectionMessage = connMess;
_mqttClient!.securityContext.setTrustedCertificatesBytes(
(await rootBundle.load("assets/cert/bundle.crt")).buffer.asUint8List());
var connection = await _mqttClient!.connect();
isConnect = connection!.state == MqttConnectionState.connected;
_mqttClient!.updates!.listen(mqttEventRecived);
}
Function? callback;
bool isConnect = false;
bool tryToConnect = true;
void stopMqtt() {
tryToConnect = false;
_mqttClient!.disconnect();
isConnect = false;
}
subscribeTopics(List<String> topics) async {
if (!isConnect) {
await connectMqtt();
}
for (var topic in topics) {
_mqttClient!.subscribe(topic, MqttQos.atLeastOnce);
}
}
unSubscribeTopics(List<String> topics) {
for (var topic in topics) {
_mqttClient!.unsubscribe(topic);
}
}
void _mqttConnected() {
print("connected");
isConnect = true;
}
void _mqttDisconnected() {
isConnect = false;
}
Future<void> mqttEventRecived(event) async {
if (callback != null) {
}
}
}