shamblett / mqtt_client

A server and browser based MQTT client for dart
Other
552 stars 179 forks source link

Difficulty creating project using both client varients #167

Closed dedvalson closed 4 years ago

dedvalson commented 4 years ago

First, this is an amazing package. Thank you for your efforts.

I have a project that deploys to both browsers and mobile devices. It is amazing that the only difference required is the type of client I create.

In my dart code I do the following:


import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_browser_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
...
    if (kIsWeb) {
      _client = MqttBrowserClient(url, clientId);
    } else {
      var c = MqttServerClient(url, clientId);
      c.useWebSocket = true;
      _client = c;
    }

This works fine when building for web and the Dart Analyzer has no problem with it for either build. However when I try to build for mobile (android) I get the errors below. For now I just comment out the include version I don't need and it works fine. Can you suggest a better way to do this?

Thanks,

Don

PS C:\Users\Don\source\CoralVue\Apps\hydros> flutter build appbundle 

Compiler message:
/c:/Src/flutter/.pub-cache/hosted/pub.dartlang.org/mqtt_client-6.1.0/lib/mqtt_browser_client.dart:11:8: Error: Not found: 'dart:html'
import 'dart:html';
       ^
/c:/Src/flutter/.pub-cache/hosted/pub.dartlang.org/mqtt_client-6.1.0/lib/src/connectionhandling/mqtt_client_mqtt_browser_ws_connection.dart:52:16: Error: The method 'WebSocket' isn't defined for the class 'MqttBrowserWsConnection'.
 - 'MqttBrowserWsConnection' is from 'package:mqtt_client/mqtt_browser_client.dart' ('/c:/Src/flutter/.pub-cache/hosted/pub.dartlang.org/mqtt_client-6.1.0/lib/mqtt_browser_client.dart').
Try correcting the name to the name of an existing method, or defining a method named 'WebSocket'.
      client = WebSocket(uriString, protocols);
               ^^^^^^^^^
/c:/Src/flutter/.pub-cache/hosted/pub.dartlang.org/mqtt_client-6.1.0/lib/src/connectionhandling/mqtt_client_mqtt_browser_connection.dart:51:32: Error: 'MessageEvent' isn't a type.
      client.onMessage.listen((MessageEvent e) {
                               ^^^^^^^^^^^^
U                                                                       
nhandled exception:
FileSystemException(uri=org-dartlang-untranslatable-uri:da
rt%3Ahtml; message=StandardFileSystem only supports file:* and data:* URIs)
#0      StandardFileSystem.entityForUri (package:front_end/src/api_prototype/standard_file_system.dart:33:7)
#1      asFileUri (package:vm/kernel_front_end.dart:567:37
)
<asynchronous suspension>
#2      writeDepfile (package:vm/kernel_front_end.dart:760:21)
<asynchronous suspension>
#3      Fron
tendCompiler.compile (package:frontend_server/frontend_server.dart:536:15)
<asynchronous suspension>
#4      _FlutterFr
ontendCompiler.compile (package:flutter_f
rontend_server/server.dart:38:22)
#5      starter (package:flutter_frontend_server/server.dart:162        
:27)
#6      main (file:///C:/b/s/w/ir/cache/builder/src/flutter/flutter_frontend_server/bin/starter.dart:8:30)

#7      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:299:32)
#8      _RawReceivePortImpl
._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

Target kernel_snapshot failed: Exception: Errors during snapshot creation: null
build failed.

FAILURE: Build failed with an exception.

* Where:
Script 'C:\Src\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 833

* What went wrong:
Execution failed for task ':app:compileFlutterBuildRelease'.
> Process 'command 'C:\Src\flutter\bin\flutter.bat'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 20s
Running Gradle task 'bundleRelease'...
Running Gradle task 'bundleRelease'... Done                        21.8s
Gradle task bundleRelease failed with exit code 1
shamblett commented 4 years ago

As far as I know you can't mix client and server versions together, I'm not a flutter user but it is essentially a server side environment, the client was working on flutter well before the browser version came along, this is why its barfing on 'import 'dart:html';', it would be the same in the VM.

I don't know anything about this new building for web targets that you can do(or is it will be able to do?) with flutter, you may be better asking the flutter guys.

dedvalson commented 4 years ago

Hi,

Thanks for the quick response.

I did find a way to resolve my issue. You might want to consider adding it to the library in a future version. To do it I had to create 4 tiny dart files. Here is the full contents of them:

The first is called MqttClientFactory.dart

export 'MqttClientFactoryNull.dart'
    if (dart.library.html) 'MqttClientFactoryWeb.dart'
    if (dart.library.io) 'MqttClientFactoryServer.dart';

The second is MqttClientFactoryWeb.dart

import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_browser_client.dart';

MqttClient makeClient(String url, String clientId) => MqttBrowserClient(url, clientId);

The third is MqttClientFactoryServer.dart

import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
MqttClient makeClient(String url, String clientId) {
  var client = MqttServerClient(url, clientId);
  client.useWebSocket = true;
  return client;
}

And finally MqttClientFactoryNull.dart

import 'package:mqtt_client/mqtt_client.dart';

MqttClient makeClient(String url, String clientId) {
  throw 'Platform not supported';
}

Once all of this was in place, all I had to do in my app was:

import 'package:mqtt_client/mqtt_client.dart';
import 'MqttClientFactory.dart';
...
    _client = makeClient(url, clientId);

With this, it compiles and runs correctly on both browser and server with no code changes.

Thanks,

Don

shamblett commented 4 years ago

Thanks for this, I've never been a fan of conditional library includes but this looks quite clean. I'll have a look at incorporating this into the client and maybe some of my other packages.

DragonSlayer88 commented 1 year ago

Hello I am looking to do the same thing. I cant get it to work with the code that you posted here. It would be cool to bring this up again and implement it into the package itself. I mean flutter is meant to use the same code to build for multiple platforms. It would make sense to add this in. THanks!