flutter_bluetooth_serial icon indicating copy to clipboard operation
flutter_bluetooth_serial copied to clipboard

Allow user to choose between normal and broadcast StreamController

Open FilippoZazzeroni opened this issue 5 years ago • 10 comments

I had to enter a page and opening a stream more times but i always got the error of bad state. I know that there are different ways to solve this issue, by either close the stream or make a broadcast controller. I actually solved the problem by modifying flutter ble serial library and change the controller they provided by a broadcast one. So i ask edufolly if it's possible for users to choose between those two configurations and if he might want to explain how to close correctly the stream, cause i tried and failed. Thank you all in advance for the help.

Steps to reproduce

if you want to add a broadcast controller to the library, you open the bluetooth connection sheet and modify the controller by adding the broadcast method.

FilippoZazzeroni avatar Sep 21 '19 08:09 FilippoZazzeroni

If you need to multiple listen, there is asBroadcastStream in core Dart Stream. Be aware, that these don't buffer - adding another listen allow to listen only further incoming data, not the whole that already were received before listening.

Please, tell me if it fit your needs.

By the way, the situation, when you need to multiple listen on some raw data stream might be app design flaw. I think you might want to have some shared object to manage "resource" like the remote device you are connecting to.

AgainPsychoX avatar Sep 21 '19 10:09 AgainPsychoX

@FilippoZazzeroni, please take a look and tell me if using asBroadcastStream fit your needs. If you need further help (including incorporating the solution), also feel free to ask.

AgainPsychoX avatar Sep 24 '19 14:09 AgainPsychoX

@PsychoXIVI sorry for the delayed answer. Btw i just solved the problem before posting here, by using as you suggested broadcast stream controller. My question was directed to @edufolly, if he could modify the library to allow users, to choose between normal or broadcast controller. my problem was solved by modifying edu's package so i asked.

FilippoZazzeroni avatar Sep 25 '19 10:09 FilippoZazzeroni

I don't quite understand why would you need to modify the library itself, since asBroadcastStream can be used directly on input.

I imagine example case like you described: there is app with 3 screens:

  • 1st, main, which allow you to connect and enter 2nd and 3rd page,
  • 2nd, hex reader page, which would like listen to connection input on initState to display incoming bytes as hex,
  • 3rd, decimal reader page, which would like listen to connection input on initState to display incoming bytes as decimals.

In such app, there can not be multiple listens to the raw connection input - it would cause bad state, because of re-listening to non-broadcast stream. In such case, there must be asBroadcastStream applied, as I mentioned. To solve the problem, in the main page there should be separate Stream broadcastDataStream field initialized after connection using broadcastDataStream = _connection.input.asBroadcastStream(). Then it should be passed to to both hex and decimal reader pages while entering these, where listening to this broadcasting stream is required.

Please note, that this is only simple example, and in more advanced applications even better solution might be to have separated and shared between pages model for all Bluetooth communications.

Ideal design would be not over-implementing extension, which is easily implementable if there is additional cost for default thing. On other hand, it might be somewhat easier to just have even simpler way of doing this 🤔 And whole Dart isn't "ideal" also at all...

AgainPsychoX avatar Sep 25 '19 11:09 AgainPsychoX

thank you @PsychoXIVI. I actually tried your way before but i might did it in the wrong way. i'm in accord with you that dart could be easier than it is and some time more clear.

FilippoZazzeroni avatar Sep 26 '19 08:09 FilippoZazzeroni

ah @PsychoXIVI sorry for disturbing you, but i got other question. i really didn't get it how to close stream properly. in my case i'm sending credentials to arduino with a button and after i open stream to read the connection status from the board. the problem is to close the connection every time i 've done the check.

FilippoZazzeroni avatar Sep 26 '19 09:09 FilippoZazzeroni

You can close connection by either:

  • closing connection.output stream (you might want also to await connection.output.allSent; to be sure all data was sent), or
  • using connection.finish() (best way to close connection rather gracefully), or
  • using connection.close() (this will result in instant disconnection, no matter if all queued data were sent), or

Also, please note, that you should invoke connection.dispose() on disposal (like on exiting the page which contains the connection object, or exiting whole app if there is global model which contains the connection object). This method is intended to make sure that all resources are freed.

If you want notify remote device that you are disconnecting, I think you might also send some specific data just before disconnection too. If you are using something like HC-05 Bluetooth for Arduino module, which works like serial port, you might be unable to tell otherwise is device disconnected, since (as far I know) HC-05 cannot notify your board that it was disconnected (well there is LED which blinks fast if you are disconnected, but it might be unreliable).

For future, please feel free to open another issue even for such question.

AgainPsychoX avatar Sep 26 '19 09:09 AgainPsychoX

Thank you so much @PsychoXIVI, i actually used connection.close() it worked perfectly for closing bluetooth connection, but the connection.output.close() didn't work, the stream is always on read and as i try this method nothing happen, it continue to read untill i close bluetooth connection.

FilippoZazzeroni avatar Sep 30 '19 19:09 FilippoZazzeroni

but the connection.output.close() didn't work

That could be because of your modification (broadcasted streams are not likely to be closed that way afik).

AgainPsychoX avatar Sep 30 '19 20:09 AgainPsychoX

ah ok I'll try to restore it, and let you know

FilippoZazzeroni avatar Oct 01 '19 12:10 FilippoZazzeroni