Configure flutter web app to broadcast data to any subscribed listeners with sse - flutter

I am currently developing a flutter web app, and would like to implement a feature to broadcast json data to any listeners/subscribers.
To give more detail:
The web app has a flutter front end server running on localhost. A user will be able to fetch some JSON data from an external backend server using a simple GET request.
Once the app has loaded the JSON data, it will need to broadcast it down an SSE stream to any listeners. This listener will be a seperate flutter application.
Now, I understand that there a few problems with this.
Firstly, Flutter web doesn't support dart:io... Fine - I have managed to get round this by using the universal_io dart package instead of dart:io. The api is the same, and after solving a few CORS errors, works a charm for the GET requests in the first bullet above. This means that the json data can be successfully loaded into the Flutter app.
(universal_io dart package -> https://pub.dev/packages/universal_io).
The next issue is with SSE. Part one of this is that there is not much documentation on implementing an SSE server in Flutter - only a client that can listen. However, I have managed to find a solution in the sse dart package example app...
import 'package:shelf/shelf_io.dart' as io;
import 'package:sse/server/sse_handler.dart';
/// A basic server which sets up an SSE handler.
///
/// When a client connnects it will send a simple message and print the
/// response.
void main() async {
var handler = SseHandler(Uri.parse('/sseHandler'));
await io.serve(handler.handler, 'localhost', 0);
var connections = handler.connections;
while (await connections.hasNext) {
var connection = await connections.next;
connection.sink.add('foo');
connection.stream.listen(print);
}
}
(sse dart package -> https://pub.dev/packages/sse)
(continued) Usually, this would be a fine solution, and it could probably be modified a little for implementation within a flutter app. However, the shelf_io.dart package, used to spin up the server, depends on the dart:io package, which doesn't work with Flutter Web.
The other thought is - why do we need to set up a new server connection (with io.server(...)) when the flutter web app is already running on its own localhost server? This begs the question: Is there a way to add this sseHandler endpoint onto the localhost server that the Flutter Web app is running on?
All in all, what i'm trying to ask is:
Is there a way for a Flutter Web App to send SSE messages to a collection of listeners?
At the moment I've hit a bit of a deadend with research on this so if anyone had any bright ideas on a potential solution then the help would be greatly appreciated. Thanks :)
Side Note: Obviously this is something that could very easily be done with Java, J2Html and so on, but wheres the fun in giving up just like that... On the other hand, maybe flutter web is still just too new to support stuff like this?

Related

Is it possible to open two websockets connection using SignalR package in Dart?

I have been working with SignalR package for a while, so now I have a task which requires me to create two websockets connection. One channel is for taking about 50 photos (it comes from server having about 2MB size for each, which is pretty big), the second is for getting time, user's auth, keep user's data, so my question is:
How can I open two websockets connection concurrently?
I have read that the websocket works synchronously and it is impossible to make it asynchronous (I guess?...), so may be, someone have had the same issue and solved it?
Now with SignalR package I need to start my websockets connection every time I want to use request to the server. For example, now it looks like this:
The first request on page
Future<String> getTime()async{
//some code for building url which I took from from SignalR official docs
await connection.start()
hubconnection.invoke('getTime');
}
the second request on this page
Future<String> getUsersData()async{
//some code for building url which I took from from SignalR official docs
await connection.start()
hubconnection.invoke('getUsersData');
}
So I am not sure about this line: await connection.start() because I think this means that every time I go to a page where there can be up to five such requests, the websocket starts every time, which greatly affects the performance of the app. Is it possible to make this line shared between all requests once or is there some way to improve the work?
So after this research I was thinking may be I can open two websockets request to make workload less?

Problem using signalr for chat application flutter

I had made a whole chat application using signalr as a socket with the online and offline facility. I am facing a few problems,
Signalr connection is always time out after some time, to overcome that I had condition if hubconnection is not connected then create new hubconnection (onResume app), but still it get hubconnection._callback got increased when sending message and not moving to server side socket. Again need to refresh whole app.
Can someone tell me whether this is problem because there are lot of operations going on and so signalr loses its connection as flutter is single thread and it cannot handle much? or should I use Isolate or inherit widget.
Summary problem:
I cannot send message in chat after sometime. It stores all message in hubconnection._callback and not going for server.
Is anything better solution to keep alive in both Android+iOS.
I had used https://pub.dev/packages/signalr_netcore package.
Please do not mention about firebase.
Any other logic suggestion is appreciable.
Thank you.
I've been using a different package, https://pub.dev/packages/signalr_core, which works fine without any particular issues what I have observed at the moment.
I'm only running about 10 listeners simultaneously, not sure if that is more or less than you. In the package I'm running you can establish connection with automatic reconnect. It looks like this:
HubConnectionBuilder().withAutomaticReconnect().withUrl(....)
It seems like your package have the same functionality... Have you tried that?

How can i use sockets with Flutter web

I'm trying to make a connection between a socket server written in Python using socketio to a client made with Flutter Web.
I tested various socket packages like adhara_socket_io and flutter_socket_io and nothing worked. I tried the same code snippets on Android and they didn't work too.
I kept searching and i found this code snippet. It uses the Socket class from the dart.io package.
Socket socket = await Socket.connect('192.168.2.190', 7003);
print('connected');
// listen to the received data event stream
socket.listen((List<int> event) {
print(utf8.decode(event));
});
// send hello
socket.add(utf8.encode('hello'));
// wait 5 seconds
await Future.delayed(Duration(seconds: 5));
// .. and close the socket
socket.close();
This one connected to the Python server and sent the data from Android but when i tested it from Web i didn't connect.
Is there some things extra i need to add for it to work on Web?
Or in the worst case, is there another way to do what i want to do, my goal is to display a video feed in a website. The video is actually a bunch of images taken from Python, there is some machine learning that will be performed on them and i want to send them over socket and each image is displaying as soon as it is received so it looks like a video feed. (Similar thing was done using React)
dart.io package is not compatible with flutter web. And I suppose As pskink suggested websockets is the way to go. You can use HtmlWebSocketChannel from the web_socket_channel package as documented here. I have used this package and can confirm it works well in flutter web.
In your case should be using something as follows.
var channel = HtmlWebSocketChannel.connect("ws://192.168.2.190:7003");
But do note that this is not inter operable with regular flutter app. If you aim to target both android and flutter web, then you should handle this channel creation conditionally depending on target you are building it for and decide between HtmlWebSocketChannel or IOWebSocketChannel to create the connection. If you are interested you can use a conditional stub based implementation as suggested in this post*.
* Note: its my post. :)

What is the difference between MethodChannel, EventChannel & BasicMessageChannel?

In Flutter, there are three types of platform channels, and I want to know about the difference between them.
These channels are used to communicate between native code (plugins or native code inside of your project) and the Flutter framework.
MethodChannel
A MethodChannel is used for "communicating with platform plugins using asynchronous method calls". This means that you use this channel to invoke methods on the native side and can return back a value and vise versa.
You can e.g. call a method that retrieves the device name this way.
EventChannel
An EventChannel is used to stream data. This results in having a Stream on the Dart side of things and being able to feed that stream from the native side.
This is useful if you want to send data every time a particular event occurs, e.g. when the wifi connection of a device changes.
BasicMessageChannel
This is probably not something you will want to use. BasicMessageChannel is used to encode and decode messages using a specified codec.
An example of this would be working with JSON or binary data. It is just a simpler version because your data has a clear type (codec) and you will not send multiple parameters etc.
Here is a link to a good explanation for you https://medium.com/flutter-io/flutter-platform-channels-ce7f540a104e
Basically there are two main types:
Method Channels: designed for invoking named pieces of code across Dart and Java/Kotlin or Objective-C/Swift. (From flutter to the platform)
Event Channels: specialized platform channel intended for the use case of exposing platform events to Flutter as a Dart stream. (From the platform to flutter)
#creativecreatorormaybenot answer clears the things, let me add more to this.
Method Channel
This is more like RPC call. You invoke a method from your Flutter app to the native code, the native code does something and finally responds with a success or error. This call could be to get the current battery status, network information or temperature data. Once the native side has responded, it can no longer send more information until the next call.
Method Channel provides platform communication using asynchronous method calls.
Note:- If desired, method calls can also be sent in the reverse
direction, with the platform acting as client to methods implemented
in Dart.
Event Channel
This is more like reactive programming where platform communication using asynchronous event streams. These events could be anything that you need streamed to your Flutter application.Streaming data from the native code to Flutter app like continuously updating BLE or WiFi scanning results, accelerometer and gyro, or even periodic status updates from intensive data collection.
Basic Message Channel
It provides basic messaging services similar to BinaryMessages, but with pluggable message codecs in support of sending strings or semi-structured messages. Messages are encoded into binary before being sent, and binary messages received are decoded into Dart values. The MessageCodec used must be compatible with the one used by the platform plugin.

Does the Rx Framework have any use in a web application?

I have been looking at the Rx Framework aslo refered to as LINQ to events. This is definately a great thing but I have been wondering if anyone sees this as having any uses in web applications rather than just normal windows based apps?
You can use Rx in various call back scenarios, not just when you work 'normal windows apps'. Especially, when you work with Async operations - for ex, you might need to make a call to the server or cloud from your silverlight or desktop client and to receive the data back. Or in cases you'll get a call back from the server (in cases like Polling Duplex).
Also, another scenario for web apps - to invalidate your cache when you receive a data changed event from the model. Just some 'imaginary' code here if you've a cache and model designed accordingly...
var cacheListeners=from sender in myModel.GetDataChangedEvents()
select sender;
//Subscribe
cacheListeners.Subscribe(data=>Cache.Invalidate(data.Key));
Have a look at this http://amazedsaint.blogspot.com/2009/11/systemreactive-or-net-reactive.html
It appears that the original spark for the Rx was around web based programming - in particular to simplify the challenges of AJAX style applications.
Here's a web based example
http://blogs.msdn.com/somasegar/archive/2009/11/18/reactive-extensions-for-net-rx.aspx
See the project http://reactivetrader.com/ to see Rx in use in a web application.