shamblett / mqtt_client

A server and browser based MQTT client for dart
Other
548 stars 176 forks source link

Unsupported operation: default SecurityContext getter #461

Closed maliswe closed 1 year ago

maliswe commented 1 year ago

I have project to work on and need to subscribe broker with the system software, I am using mosquitto to do that. I have worked on it for 1,5 weeks, and still can not solve the problem.

While I am using MqttServerClient, to initialize the client in the project, I am getting this bug here : Unsupported operation: default SecurityContext getter

When I am using the MqttBrowserClient it is trying to connect but I got these here `Launching lib\main.dart on Edge in debug mode... Waiting for connection from debug service on Edge... This app is linked to the debug service: ws://127.0.0.1:64988/FPiulRVAyyM=/ws Debug service listening on ws://127.0.0.1:64988/FPiulRVAyyM=/ws

Running with sound null safety Debug service listening on ws://127.0.0.1:64988/FPiulRVAyyM=/ws Mosquitto client connecting.... 1-2023-05-05 10:10:43.246 -- MqttClient::connect - Connection timeout period is 2000 milliseconds 1-2023-05-05 10:10:43.249 -- MqttClient::connect - keep alive is enabled with a value of 20 seconds 1-2023-05-05 10:10:43.250 -- MqttConnectionKeepAlive:: Initialised with a keep alive value of 20 seconds 1-2023-05-05 10:10:43.250 -- MqttConnectionKeepAlive:: Disconnect on no ping response is disabled 1-2023-05-05 10:10:43.251 -- MqttConnectionHandlerBase::connect - server wss://192.168.50.225:8883, port 8883 1-2023-05-05 10:10:43.252 -- SynchronousMqttBrowserConnectionHandler::internalConnect entered 1-2023-05-05 10:10:43.252 -- SynchronousMqttBrowserConnectionHandler::internalConnect - initiating connection try 0, auto reconnect in progress false 1-2023-05-05 10:10:43.253 -- SynchronousMqttBrowserConnectionHandler::internalConnect - calling connect 1-2023-05-05 10:10:43.254 -- MqttBrowserWsConnection::connect - entered 1-2023-05-05 10:10:43.255 -- MqttBrowserWsConnection::connect - WS URL is wss://192.168.50.225:8883 1-2023-05-05 10:10:43.257 -- MqttBrowserWsConnection::connect - connection is waiting 1-2023-05-05 10:10:43.610 -- MqttBrowserWsConnection::connect - websocket has erred 1-2023-05-05 10:10:43.611 -- SynchronousMqttBrowserConnectionHandler::internalConnect - connection complete 1-2023-05-05 10:10:43.611 -- SynchronousMqttBrowserConnectionHandler::internalConnect sending connect message 1-2023-05-05 10:10:43.611 -- MqttConnectionHandlerBase::sendMessage - MQTTMessage of type MqttMessageType.connect Header: MessageType = MqttMessageType.connect, Duplicate = false, Retain = false, Qos = MqttQos.atMostOnce, Size = 0 Connect Variable Header: ProtocolName=MQTT, ProtocolVersion=4, ConnectFlags=Connect Flags: Reserved1=false, CleanStart=true, WillFlag=true, WillQos=MqttQos.atLeastOnce, WillRetain=false, PasswordFlag=false, UserNameFlag=false, KeepAlive=20 MqttConnectPayload - client identifier is : MiniProject

1-2023-05-05 10:10:43.613 -- SynchronousMqttBrowserConnectionHandler::internalConnect - pre sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none 1-2023-05-05 10:10:45.615 -- SynchronousMqttBrowserConnectionHandler::internalConnect - post sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none 1-2023-05-05 10:10:45.615 -- SynchronousMqttBrowserConnectionHandler::internalConnect - initiating connection try 1, auto reconnect in progress false 1-2023-05-05 10:10:45.616 -- SynchronousMqttBrowserConnectionHandler::internalConnect - calling connect 1-2023-05-05 10:10:45.616 -- MqttBrowserWsConnection::connect - entered 1-2023-05-05 10:10:45.617 -- MqttBrowserWsConnection::connect - WS URL is wss://192.168.50.225:8883 1-2023-05-05 10:10:45.619 -- MqttBrowserWsConnection::connect - connection is waiting 1-2023-05-05 10:10:45.634 -- MqttBrowserWsConnection::connect - websocket has erred 1-2023-05-05 10:10:45.635 -- SynchronousMqttBrowserConnectionHandler::internalConnect - connection complete 1-2023-05-05 10:10:45.635 -- SynchronousMqttBrowserConnectionHandler::internalConnect sending connect message 1-2023-05-05 10:10:45.635 -- MqttConnectionHandlerBase::sendMessage - MQTTMessage of type MqttMessageType.connect Header: MessageType = MqttMessageType.connect, Duplicate = false, Retain = false, Qos = MqttQos.atMostOnce, Size = 60 Connect Variable Header: ProtocolName=MQTT, ProtocolVersion=4, ConnectFlags=Connect Flags: Reserved1=false, CleanStart=true, WillFlag=true, WillQos=MqttQos.atLeastOnce, WillRetain=false, PasswordFlag=false, UserNameFlag=false, KeepAlive=20 MqttConnectPayload - client identifier is : MiniProject

1-2023-05-05 10:10:45.635 -- SynchronousMqttBrowserConnectionHandler::internalConnect - pre sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none 1-2023-05-05 10:10:47.637 -- SynchronousMqttBrowserConnectionHandler::internalConnect - post sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none 1-2023-05-05 10:10:47.637 -- SynchronousMqttBrowserConnectionHandler::internalConnect - initiating connection try 2, auto reconnect in progress false 1-2023-05-05 10:10:47.638 -- SynchronousMqttBrowserConnectionHandler::internalConnect - calling connect 1-2023-05-05 10:10:47.638 -- MqttBrowserWsConnection::connect - entered 1-2023-05-05 10:10:47.639 -- MqttBrowserWsConnection::connect - WS URL is wss://192.168.50.225:8883 1-2023-05-05 10:10:47.640 -- MqttBrowserWsConnection::connect - connection is waiting 1-2023-05-05 10:10:47.654 -- MqttBrowserWsConnection::connect - websocket has erred 1-2023-05-05 10:10:47.654 -- SynchronousMqttBrowserConnectionHandler::internalConnect - connection complete 1-2023-05-05 10:10:47.654 -- SynchronousMqttBrowserConnectionHandler::internalConnect sending connect message 1-2023-05-05 10:10:47.654 -- MqttConnectionHandlerBase::sendMessage - MQTTMessage of type MqttMessageType.connect Header: MessageType = MqttMessageType.connect, Duplicate = false, Retain = false, Qos = MqttQos.atMostOnce, Size = 60 Connect Variable Header: ProtocolName=MQTT, ProtocolVersion=4, ConnectFlags=Connect Flags: Reserved1=false, CleanStart=true, WillFlag=true, WillQos=MqttQos.atLeastOnce, WillRetain=false, PasswordFlag=false, UserNameFlag=false, KeepAlive=20 MqttConnectPayload - client identifier is : MiniProject

1-2023-05-05 10:10:47.655 -- SynchronousMqttBrowserConnectionHandler::internalConnect - pre sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none 1-2023-05-05 10:10:49.657 -- SynchronousMqttBrowserConnectionHandler::internalConnect - post sleep, state = Connection status is connecting with return code of noneSpecified and a disconnection origin of none 1-2023-05-05 10:10:49.657 -- SynchronousMqttBrowserConnectionHandler::internalConnect failed client exception - mqtt-client::NoConnectionException: The maximum allowed connection attempts ({3}) were exceeded. The broker is not responding to the connection request message (Missing Connection Acknowledgement? 1-2023-05-05 10:10:49.658 -- MqttConnectionHandlerBase::disconnect - entered 1-2023-05-05 10:10:49.658 -- MqttConnectionHandlerBase::_performConnectionDisconnect entered 1-2023-05-05 10:10:49.659 -- MqttConnectionKeepAlive::stop - stopping keep alive OnDisconnected client callback - Client disconnection OnDisconnected callback is solicited, this is correct ERROR Mosquitto client connection failed - disconnecting, status is Connection status is disconnected with return code of noneSpecified and a disconnection origin of solicited OnDisconnected client callback - Client disconnection OnDisconnected callback is solicited, this is correct Error: Unsupported operation: ProcessUtils._exit and here is the broker on the terminal 1683274214: mosquitto version 2.0.15 starting 1683274214: Config loaded from mosquitto.conf. 1683274214: Opening ipv6 listen socket on port 8883. 1683274214: Opening ipv4 listen socket on port 8883. 1683274214: mosquitto version 2.0.15 running 1683274243: New connection from 192.168.50.225:65000 on port 8883. 1683274243: Client disconnected due to protocol error. 1683274243: New connection from 192.168.50.225:65002 on port 8883. 1683274243: Client disconnected due to protocol error. 1683274245: New connection from 192.168.50.225:65005 on port 8883. 1683274245: Client disconnected due to protocol error. 1683274245: New connection from 192.168.50.225:65006 on port 8883. 1683274245: Client disconnected due to protocol error. 1683274247: New connection from 192.168.50.225:65009 on port 8883. 1683274247: Client disconnected due to protocol error. 1683274247: New connection from 192.168.50.225:65010 on port 8883. 1683274247: Client disconnected due to protocol error. `

and when I try to use MqttServerClient I am getting:

`======== Exception caught by widgets library ======================================================= The following UnsupportedError was thrown building MediaQuery(MediaQueryData(size: Size(0.0, 0.0), devicePixelRatio: 1.0, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding: EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, alwaysUse24HourFormat: false, accessibleNavigation: false, highContrast: false, disableAnimations: false, invertColors: false, boldText: false, navigationMode: traditional, gestureSettings: DeviceGestureSettings(touchSlop: 18), displayFeatures: [])): Unsupported operation: default SecurityContext getter

The relevant error-causing widget was: MediaQuery MediaQuery:file:///C:/Users/M%20Ali/Desktop/Mini%20project/sleep-well/sleep_well/lib/main.dart:15:13 When the exception was thrown, this was the stack: C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddcruntime/errors.dart 266:49 throw C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart 589:5 get defaultContext packages/mqtt_client/src/mqtt_server_client.dart 34:53 withPort packages/sleep_well/MQTT/BrokerConnection.dart 20:31 new packages/sleep_well/main.dart 44:9 initState packages/flutter/src/widgets/framework.dart 5101:55 [_firstBuild] packages/flutter/src/widgets/framework.dart 4944:5 mount packages/flutter/src/widgets/framework.dart 3953:15 inflateWidget packages/flutter/src/widgets/framework.dart 3682:18 updateChild packages/flutter/src/widgets/framework.dart 4993:16 performRebuild packages/flutter/src/widgets/framework.dart 4690:5 rebuild packages/flutter/src/widgets/framework.dart 4950:5 [_firstBuild] packages/flutter/src/widgets/framework.dart 4944:5 mount packages/flutter/src/widgets/framework.dart 3953:15 inflateWidget packages/flutter/src/widgets/framework.dart 3682:18 updateChild packages/flutter/src/widgets/framework.dart 6377:14 mount packages/flutter/src/widgets/framework.dart 3953:15 inflateWidget packages/flutter/src/widgets/framework.dart 3682:18 updateChild packages/flutter/src/widgets/framework.dart 4993:16 performRebuild packages/flutter/src/widgets/framework.dart 4690:5 rebuild`

and here my code in flutter:

class BrokerConnection {

String Topic = 'wio/values'; static const String LocalHost = '192.168.50.225'; String MQTT_Server = 'wss://$LocalHost:8883'; int port = 8883; String clientIdentifier = 'MiniProject'; late MqttServerClient client;

BrokerConnection(BuildContext context) { context = context; client = MqttServerClient.withPort(MQTT_Server, clientIdentifier,port); connect(); }

Future connect() async { client.logging(on: true); client.setProtocolV311(); client.securityContext = SecurityContext.defaultContext; client.keepAlivePeriod = 20; client.connectTimeoutPeriod = 2000; client.secure = true;// milliseconds client.onDisconnected = onDisconnected; client.onConnected = onConnected; client.onSubscribed = onSubscribed;

final connMess = MqttConnectMessage()
    .withWillTopic(Topic)
    .withWillMessage('Request to connect.....')
    .startClean()
    .withWillQos(MqttQos.atLeastOnce);
print('Mosquitto client connecting....');
client.connectionMessage = connMess;

try {
  await client.connect();
} on NoConnectionException catch (e) {
  print('client exception - $e');
  client.disconnect();
} on SocketException catch (e) {
  print('socket exception - $e');
  client.disconnect();
}

//Check we are connected
if (client.connectionStatus!.state == MqttConnectionState.connected) {
  print('Mosquitto client connected');
} else {
  print(
      'ERROR Mosquitto client connection failed - disconnecting, status is ${client.connectionStatus}');
  client.disconnect();
  exit(-1);
}

//lets try a subscription
print('Subscribing....');
client.subscribe(Topic, MqttQos.atMostOnce);

/// The client has a change notifier object(see the Observable class) which we then listen to to get
/// notifications of published updates to each subscribed topic.
client.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) {
  final recMess = c![0].payload as MqttPublishMessage;
  final pt = MqttPublishPayload.bytesToString(recMess.payload.message);

  /// The above may seem a little convoluted for users only interested in the
  /// payload, some users however may be interested in the received publish message,
  /// lets not constrain ourselves yet until the package has been in the wild
  /// for a while.
  /// The payload is a byte buffer, this will be specific to the topic
  print(
      'Change notification:: topic is <${c[0].topic}>, payload is <-- $pt -->');
  print('');
});

/// If needed you can listen for published messages that have completed the publishing
/// handshake which is Qos dependant. Any message received on this stream has completed its
/// publishing handshake with the broker.
client.published!.listen((MqttPublishMessage message) {
  print(
      'Published notification:: topic is ${message.variableHeader!.topicName}, with Qos ${message.header!.qos}');
});

/// Lets publish to our topic
/// Use the payload builder rather than a raw buffer
/// Our known topic to publish to
final builder = MqttClientPayloadBuilder();
builder.addString('Hello from mqtt_client');

print('Subscribing....');
client.subscribe(Topic, MqttQos.exactlyOnce);

/// Publish it
print('Publishing our topic');
client.publishMessage(Topic, MqttQos.exactlyOnce, builder.payload!);

print('Sleeping....');
await MqttUtilities.asyncSleep(60);

print('Unsubscribing...');
client.unsubscribe(Topic);

/// Wait for the unsubscribe message from the broker if you wish.
await MqttUtilities.asyncSleep(2);
print('Disconnecting....');
client.disconnect();
print('Exiting normally....');
exit(0);

}

void onSubscribed(String topic) { print('Subscription confirmed for topic $topic'); }

void onDisconnected() { print('OnDisconnected client callback - Client disconnection'); if (client.connectionStatus!.disconnectionOrigin == MqttDisconnectionOrigin.solicited) { print('OnDisconnected callback is solicited, this is correct'); } else { print( 'OnDisconnected callback is unsolicited or none, this is incorrect - exiting'); exit(-1); } }

void onConnected() { print('OnConnected client callback - Client connection was successful'); } void dispose(){ client.disconnect(); } }

shamblett commented 1 year ago

You are getting the server client and the browser client confused somehow, if you are using secure sockets on the server side then you need to use the security context, if you are using the browser client(not for flutter BTW, use the server client) you don't, you can only use ws or wss url's nothing else so you don't need the security context.

Its difficult se what it is your trying to do however one line from your log above shows -

1-2023-05-05 10:10:45.634 -- MqttBrowserWsConnection::connect - websocket has erred

Which means either your broker is not accepting connections from clients or there is no route to it over the network.

You may be better fixing one problem at time rather than swapping between server side and browser initially.

maliswe commented 1 year ago

Yeah, that is happening actually, I am using it for the flutter project, so you mean that I need to use server client. What if I want use like local host, I mean I want to have connection between the the windows terminal and the app in the emulator, I tried to do it, but had problem with the it, do you have any ideas, how can I fix it?

shamblett commented 1 year ago

As far as Dart is concerned flutter is a server side framework, like the VM so you must use the server client, the security context property will then be available, note you only need to use this if you are using secure sockets with TLS, not if you are using normal TCP sockets or websockets using ws or wss.

I don't develop on Windows nor do I use an emulator(presumably you are using android studio which I don't use) so I can't help here, maybe post on a more general flutter board. The client just needs an MQTT broker to connect to.

maliswe commented 1 year ago

DONE!! Working well

jeffreycool commented 1 year ago

I have the same problem, can you tell me how you solved it?

rpungin commented 1 week ago

You need to use MqttBrowserClient on the web and MqttServerClient on mobile. I did it like this.