Flutter How to check connection TCP IP - flutter

I want to perform an operation, but before that I want to check the connection status to the server whether it is still connected or not. If it is connected then perform the operation, if not then reconnect.
here is my code on button on pressed
Future<void> masuk() async {
if (_socketConnection == null) {
setState(() {
connect();
});
} else if (_subscription == null) {
setState(() {
connect();
});
} else {
_getId().then((id) {
setState(() {
deviceId = id;
print("Sambungan Masih terhubung");
send();
});
});
}
}
and here is code for connection
Future<void> connect() async {
var server = "10.0.2.2";
int port = 8000;
if (server.isNotEmpty) {
SocketClient socketClient = SocketClient(server, port);
_subscription = socketClient.connect().doOnCancel(() {
setState(() {
_subscription = null;
_socketConnection = null;
});
}).listen((connection) async {
print("listen:$connection");
setState(() {
_socketConnection = connection;
});
}, onError: (error) {
_result = "Connect Error:$error";
_subscription?.cancel();
setState(() {
_subscription = null;
_socketConnection = null;
});
}, cancelOnError: true);
}
setState(() {});
}
I have to restart the application first if I want to reconnect if the condition is "The server is off or restarted"

Related

How to show Unhandled Exception message to View FLUTTER

How to show this message to view? so that the user knows that the connection cannot connect to the server
this my socket connection code :
Socket.connect(pIp, port, timeout: const Duration(seconds: 5))
.then((socket) {
_channel = socket;
_isOn = true;
if (pWithdata.isNotEmpty) {
if (_channel != null) {
send(pWithdata);
// submitMessage("LOGIN#xXYjY`#Uf]bXcMM#FFHE#V30#V901");
}
}
socket.listen(
(onData) {
_isOn = true;
_listeners.forEach((Function callback) {
// callback(onData);
callback(String.fromCharCodes(onData).trim());
});
},
onDone: onDone,
onError: onError,
);
});

flutter google_speach response stream not working

final serviceAccount = ServiceAccount.fromString(r'''{
Json private keys
}''');
final speechToText = SpeechToText.viaServiceAccount(serviceAccount);
final config = RecognitionConfig(
encoding: AudioEncoding.LINEAR16,
model: RecognitionModel.basic,
enableAutomaticPunctuation: true,
sampleRateHertz: 16000,
languageCode: 'en-US');
final streamingConfig =
StreamingRecognitionConfig(config: config, interimResults: true);
Stream<List<int>> stream =
(await MicStream.microphone(sampleRate: 16000)) as Stream<List<int>>;
final responseStream =
speechToText.streamingRecognize(streamingConfig, stream);
if (_isListining) {
setState(() {
_isListining = false;
});
} else {
setState(() {
_isListining = true;
print('hello');
try {
responseStream.listen((data) {
print(data.results.length);
setState(() {
_sendController.text = data.results
.map((e) => e.alternatives.first.transcript)
.join('/n');
});
print(content);
}, onDone: () {
setState(() {
setState(() {
_isListining = false;
});
});
}, onError: (e) {
print('errorr : ' + e);
setState(() {
_isListining = false;
});
});
print('streaming');
} catch (e) {
print('not streaming');
print(e);
}
});
}
linke to packages used
https://pub.dev/packages/google_speech
https://pub.dev/packages/mic_stream
so the problem is that microphone streaming is working fine but responseStream from google apis not printing or doing anything
after reading the docs
found this
https://cloud.google.com/speech-to-text/docs/troubleshooting#returns_an_empty_response
and i dont know if it is the problem or not

Flutter can't restore purchases

This was working already but I updated package to latest version:
https://pub.dev/packages/in_app_purchase
I can make the payment and check what I bought but after refresh it doesn't restore this. If I try to buy the same version again it says that I already own it:
Future<void> initStore() async {
final bool isAvailableTemp = await inAppPurchase.isAvailable();
if (!isAvailable) {
isAvailable = isAvailableTemp;
products = [];
purchases = [];
notFoundIds = [];
purchasePending = false;
loading = false;
return;
}
if (Platform.isIOS) {
final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
inAppPurchase
.getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
await iosPlatformAddition.setDelegate(PaymentQueueDelegate());
}
final ProductDetailsResponse productDetailResponse =
await inAppPurchase.queryProductDetails(_androidProductIds.toSet());
if (productDetailResponse.error != null) {
queryProductError = productDetailResponse.error!.message;
isAvailable = isAvailable;
products = productDetailResponse.productDetails;
purchases = <PurchaseDetails>[];
notFoundIds = productDetailResponse.notFoundIDs;
purchasePending = false;
loading = false;
return;
}
}
Future<List<ProductDetails>> getProducts() async {
if (products.isEmpty) {
final ProductDetailsResponse products =
await inAppPurchase.queryProductDetails(
Platform.isAndroid
? _androidProductIds.toSet()
: _iOSProductIds.toSet(),
);
if (products.productDetails.isNotEmpty) {
// double check the order of the products
if (Helpers.containsInStringIgnoreCase(
products.productDetails[0].title, "plus")) {
this.products.addAll(products.productDetails);
} else {
// pro comes first
this.products.add(products.productDetails[1]);
this.products.add(products.productDetails[0]);
}
}
}
return products;
}
Future<List<PurchaseDetails>> getPastPurchases(BuildContext context) async {
if (purchases.isEmpty) {
final Stream<List<PurchaseDetails>> purchaseUpdated =
inAppPurchase.purchaseStream;
_subscription = purchaseUpdated.listen((purchaseDetailsList) {
if (purchaseDetailsList.isEmpty) {
detectProVideo(context);
} else {
// this.purchases.addAll(purchaseDetailsList);
listenToPurchaseUpdated(context, purchaseDetailsList);
}
_subscription.cancel();
}, onDone: () {
_subscription.cancel();
}, onError: (error) {
// handle error here.
_subscription.cancel();
});
await inAppPurchase.restorePurchases();
if (Platform.isIOS) {
Map<String, PurchaseDetails> purchases =
Map.fromEntries(this.purchases.map((PurchaseDetails purchase) {
if (purchase.pendingCompletePurchase) {
inAppPurchase.completePurchase(purchase);
}
return MapEntry<String, PurchaseDetails>(
purchase.productID, purchase);
}));
if (purchases.isEmpty) {
Provider.of<AdState>(context, listen: false).toggleAds(context, true);
} else {
Provider.of<AdState>(context, listen: false)
.toggleAds(context, false);
}
}
}
return purchases;
}
So this is always true:
if (purchaseDetailsList.isEmpty) {
Testing locally on an Android emulator

"Unable to RTCPeerConnection::setRemoteDescription: Failed to set remote answer sdp: Called in wrong state: kStable"

I am using flutter_webrtc to connect to users peer to peer. I am getting this error on the offer side. I have been looking all over the internet for a fix but couldn't find the solution.
class Webrtc {
bool _offer = false;
RTCPeerConnection _peerConnection;
MediaStream _localStream;
RTCVideoRenderer _localRenderer = new RTCVideoRenderer();
RTCVideoRenderer _remoteRenderer = new RTCVideoRenderer();
get localRe
nderer => _localRenderer;
get remoteRenderer => _remoteRenderer;
//final sdpController = TextEditingController();
Webrtc() {
initRenderers();
_createPeerConnection().then((pc) {
_peerConnection = pc;
});
}
initRenderers() async {
await _localRenderer.initialize();
await _remoteRenderer.initialize();
}
createOffer() async {
_offer = true;
RTCSessionDescription description =
await _peerConnection.createOffer({'offerToReceiveVideo': 1});
// var session = parse(description.sdp);
// print(json.encode(session));
// _offer = true;
var roomDef = Firestore.instance.collection("rooms").document("test");
var data = {
"offer": {
'sdp': description.sdp.toString(),
'type': description.type.toString(),
}
};
await roomDef.setData(data, merge: true);
await _peerConnection.setLocalDescription(description);
Firestore.instance.collection("rooms").document("test").snapshots().listen((event) {
if(event.data["answer"] != null){
_setRemoteDescription(event.data["answer"]);
}
});
}
createAnswer() async {
// Firestore.instance.collection("rooms").document("test").snapshots().listen((event) {
// if(event.data["offer"] != null){
// _setRemoteDescription(event.data["offer"]);
// }
// });
var doc = await Firestore.instance.collection("rooms").document("test").get();
print(doc.data["offer"]);
await _setRemoteDescription(doc.data["offer"]);
RTCSessionDescription description =
await _peerConnection.createAnswer({'offerToReceiveVideo': 1});
//var session = parse(description.sdp);
//print(json.encode(session));
await _peerConnection.setLocalDescription(description);
var data = {
"answer": {
'sdp': description.sdp.toString(),
'type': description.type.toString(),
}
};
Firestore.instance
.collection("rooms")
.document("test")
.setData(data, merge: true);
}
_setRemoteDescription(doc) async {
// String jsonString = doc.toString();
// dynamic session = await jsonDecode('$jsonString');
//String sdp = write(session, null);
// RTCSessionDescription description =
// new RTCSessionDescription(session['sdp'], session['type']);
RTCSessionDescription description =
new RTCSessionDescription(doc["sdp"],doc["type"]);
print(description.toMap());
await _peerConnection.setRemoteDescription(description);
}
void _addCandidate(data) async {
dynamic session = data;
dynamic candidate = new RTCIceCandidate(
session['candidate'], session['sdpMid'], session['sdpMlineIndex']);
await _peerConnection.addCandidate(candidate);
}
_createPeerConnection() async {
Map<String, dynamic> configuration = {
"iceServers": [
{"url": "stun:stun.l.google.com:19302"},
]
};
final Map<String, dynamic> offerSdpConstraints = {
"mandatory": {
"OfferToReceiveAudio": true,
"OfferToReceiveVideo": true,
},
"optional": [],
};
_localStream = await _getUserMedia();
RTCPeerConnection pc =
await createPeerConnection(configuration, offerSdpConstraints);
// if (pc != null) print(pc);
pc.addStream(_localStream);
pc.onIceCandidate = (e) {
if (_offer && e.candidate != null) {
Firestore.instance.collection("caller").add({
'candidate': e.candidate.toString(),
'sdpMid': e.sdpMid.toString(),
'sdpMlineIndex': e.sdpMlineIndex,
});
Firestore.instance.collection("callee").snapshots().listen((event) {
event.documentChanges.forEach((element) {
print(element.document.data);
_addCandidate(element.document.data);
});
});
}
if (!_offer && e.candidate != null) {
Firestore.instance.collection("callee").add({
'candidate': e.candidate.toString(),
'sdpMid': e.sdpMid.toString(),
'sdpMlineIndex': e.sdpMlineIndex,
});
Firestore.instance.collection("caller").snapshots().listen((event) {
event.documentChanges.forEach((element) {
print(element.document.data);
_addCandidate(element.document.data);
});
});
}
// if (e.candidate != null) {
// print(json.encode({
// 'candidate': e.candidate.toString(),
// 'sdpMid': e.sdpMid.toString(),
// 'sdpMlineIndex': e.sdpMlineIndex,
// }));
// }
};
pc.onIceConnectionState = (e) {
print(e);
};
pc.onAddStream = (stream) {
print('addStream: ' + stream.id);
_remoteRenderer.srcObject = stream;
};
return pc;
}
_getUserMedia() async {
final Map<String, dynamic> mediaConstraints = {
'audio': true,
'video': {
'facingMode': 'user',
},
};
MediaStream stream = await navigator.getUserMedia(mediaConstraints);
// _localStream = stream;
_localRenderer.srcObject = stream;
_localRenderer.mirror = true;
// _peerConnection.addStream(stream);
return stream;
}
}
I tried switching the setlocaldescption and setremotedescption but no use. Offer button calls create offer from the ui and answer button calls createanswer function.
I cannot comment yet under your post but I had this problem with the newest version of flutter_webrtc. Three days of head-scratching later and I used:
flutter_webrtc: ^0.2.7
Worked on the first try. Cheers.

How to convert Future<bool> into Stream<bool>

In my Flutter app, I have a function returning Future, but I wanna get result as Stream. Here is the function :
Future<bool> isGpsOn() async {
if (await Geolocator().isLocationServiceEnabled()) {
return true;
} else {
return false;
}
}
How to do that?
Read the manual and check my answer:
Stream<bool> gpsStatusStream() async* {
bool enabled;
while (true) {
try {
bool isEnabled = await Geolocator().isLocationServiceEnabled();
if (enabled != isEnabled) {
enabled = isEnabled;
yield enabled;
}
}
catch (error) {}
await Future.delayed(Duration(seconds: 5));
}
}
gpsStatusStream().listen((enabled) {
print(enabled ? 'enabled' : 'disabled');
});
or create convertor:
Stream futureToStream(fn, defaultValue, Duration duration) async* {
var result;
while (true) {
try {
result = await fn();
}
catch (error) {
result = defaultValue;
}
finally {
yield result;
}
await Future.delayed(duration);
}
}
Future<bool> isGpsOn() async {
return await Geolocator().isLocationServiceEnabled();
}
final gpsStatusStream = futureToStream(isGpsOn, false, Duration(seconds: 5));
gpsStatusStream.listen((enabled) {
print(enabled ? 'enabled' : 'disabled');
});
If you don't want to change the return type of your function, you could make callers convert the Future<T> to a Stream<T> by simply calling asStream() on the returned Future.