I'm having trouble connecting to mqtt in flutter? - flutter

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

Related

GraphQL notification in flutter - how to catch result?

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});
}
}
}
}

Client only listens to server when sends a message

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));
}

mqtt_client cant emit messages on subscribe flutter

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;
}

How to post observer from normal class and receive listener to widget?

I'm pretty new to Flutter and experimenting with the SDK. I am working with the flutter application which works with Socket connection. I saw lots of example which communicate with widget to widget. But, I want to add listener from Socket class to widgets. The actual scenario is, I have socket listeners in my socket manager class. Here is the rough code for better idea.
class SocketManager {
static SocketIO socketIO;
static SocketIOManager manager = SocketIOManager();
//Constructor
SocketManager(){
initSocket().then((socketIO){
addListener();
});
}
void addListener(){
socketIO.onConnect((data){
print("connected...");
});
}
}
I want to notify to my widgets when socket connected.
What kind of thing am I looking for to implement this?
Thanks in advance.
here is my class, you can follow to create yours
import 'dart:convert';
import 'package:flutter_app/global.dart';
import 'package:flutter_app/strings.dart';
import 'package:rxdart/subjects.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
IO.Socket kSocket;
class Sockets {
static PublishSubject socket = PublishSubject(sync: true);
static PublishSubject status = PublishSubject(sync: true);
static PublishSubject notify = PublishSubject(sync: true);
static PublishSubject chatCount = PublishSubject(sync: true);
static PublishSubject typing = PublishSubject(sync: true);
static PublishSubject login = PublishSubject(sync: false);
static PublishSubject getInfo = PublishSubject(sync: true);
static PublishSubject alreadyLogin = PublishSubject(sync: false);
static void connectSocket() async {
/* kSocket = await IO.io('${Strings.socket}', <String, dynamic>{
'transports': ['websocket', 'polling'],
});*/
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('userToken');
if (token != null && token != '') {
Map<String, dynamic> parsedToken = Functions.parseJwt(token);
String imza = token?.split('.')[2];
kSocket = await IO.io('${Strings.socket}', <String, dynamic>{
'transports': ['websocket', 'polling'],
'query': 'token=$imza'
});
parsedToken['Tur'] = 2;
kSocket.close();
kSocket.disconnect();
kSocket.open();
try {
kSocket.on('connect', (data) {
print('SOCKET CONNECTED');
kSocket.emit('adduser', parsedToken);
kSocket.on('getmessage', (res) {
print('GETMSG: $res');
chatCount.sink.add(res);
socket.sink.add(res);
});
kSocket.on('bildirim', (res) {
print('[BILDIRIM]: $res');
notify.sink.add(res);
});
kSocket.on('durum', (res) {
status.sink.add(res);
});
kSocket.on('disconnect', (data) {
// print('DISCONNECT: $data');
});
kSocket.on('typing', (res) {
typing.sink.add(res);
});
kSocket.on('login', (res) {
//print('Multi Login');
login.sink.add(res);
});
kSocket.on('getinfo', (res) {
//print('GETINFO: $res');
getInfo.sink.add(res);
});
kSocket.on('alreadylogin', (res) {
//print('ALREADY LOGIN: $res');
alreadyLogin.sink.add(res);
});
});
} catch (e) {
print(e);
}
} else {
print('SOCKET: token yok');
}
}
static void setInfo(Map<String, dynamic> data) {
kSocket.emit('setinfo', [data]);
}
static void setRead(String userid) {
kSocket.emit('setreaded', '$userid');
}
static void isTyping(String username, int status) {
kSocket.emit('istyping', [
{"user": int.parse(username), "durum": status}
]);
}
static void isActive(String userid) {
if (kSocket != null) {
if (kSocket.connected) {
try {
//print('${kSocket.connected}');
kSocket.emit('isactive', '$userid');
} catch (e) {
print(e);
}
}
}
}
static void disconnectSocket() async {
try {
await kSocket.disconnect();
await kSocket.close();
await kSocket.destroy();
print('SOCKET DISCONNECTED');
} catch (e) {
//print(e);
}
}
static void dispose(){
socket.close();
status.close();
//notify.close();
chatCount.close();
typing.close();
login.close();
getInfo.close();
alreadyLogin.close();
}
static void unSubNotify(){
notify.close();
}
}
Answer is here !! Here what I found while surfing on the web. Flutter-NotificationCenter. An IOS type post and receive observer. It is Very helpful to other developers who want to post observer from anywhere and want to receive it to anywhere.

running SocketServer as Isolate in dart

I am trying to control dart script via socket, running within isolate
I came up with some (spoiler warning) not working code:
import "dart:io";
import "dart:convert";
import "dart:isolate";
reader(SendPort sendPort) async {
var serverSocket = await ServerSocket.bind("127.0.0.1", 83);
print('connected');
await for (var socket in serverSocket) {
socket.transform(UTF8.decoder).listen((msg) => sendPort.send(msg));
}
}
main() {
bool start = false;
bool stop = false;
listener (message)
{
print ("message from isolate: $message");
stop = start;
start = true;
}
ReceivePort receive = new ReceivePort();
receive.listen(listener);
Isolate.spawn(reader, receive.sendPort).then((Isolate) => print("Isolate started"));
print("Waiting to start");
while (!start) {}
print("Waiting to stop");
while (!stop) {}
print("Ended");
}
But isolate does not even seem to be launched. Only output of script is "Waiting to start"
This worked for me:
import 'dart:async';
import "dart:io";
import "dart:convert";
import "dart:isolate";
reader(SendPort sendPort) async {
print('isolate started');
var serverSocket = await ServerSocket.bind("127.0.0.1", 8123);
sendPort.send('bound');
await for (var socket in serverSocket) {
socket.transform(UTF8.decoder).listen((msg) {
print('server received $msg');
sendPort.send(msg);
if (msg == 'close') {
socket.close();
serverSocket.close();
}
});
}
}
StreamSubscription subscription;
Isolate isolate;
ReceivePort receive;
main() async {
listener(message) async {
print("message from isolate: $message");
if (message == 'bound') {
final socket = await Socket.connect("127.0.0.1", 8123);
print('client connected');
socket.add('close'.codeUnits);
socket.destroy();
}
if (message == 'close') {
subscription.cancel();
// exits application
}
}
receive = new ReceivePort();
subscription = receive.listen(listener);
isolate = await Isolate.spawn(reader, receive.sendPort);
}