AS-Devs / signalr_flutter

A flutter plugin for .net SignalR client.
https://pub.dev/packages/signalr_flutter
MIT License
18 stars 29 forks source link

is it possible to open two websockets connection with SignalR #46

Open ingvilow opened 1 year ago

ingvilow commented 1 year ago

Hi. I have been using your package for a while, so it works greate, but 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 maybe you, as the creator of this package, can advise me something to solve this problem (if it exists)?

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 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?

PS I am working on the prev version of you package not the recent one.

Thanks you!

AyonAB commented 1 year ago

Currently it is not possible to open two signalr connections concurrently. This is something absolutely doable but needs some development.

ingvilow commented 1 year ago

Hi :) thanks for replying, I will be waiting for the new feature :)

joseph-lewis commented 1 year ago

This could have been easily avoided if the service wasn't a static class, easy fix and I simply cannot wait for an update, considering last update was 10 months ago. I'll be forking this project with these changes as its a necessity for my app; and appears to be no other alternative flutter plugins yet!

I'll repost with the forked branch here shortly.

joseph-lewis commented 1 year ago

Here's an example of how I have gotten it to work. I have forked his code so you will need to add this to your pubspec.yaml

  signalr_flutter:
    git:
      url: https://github.com/joseph-lewis/signalr_flutter
      ref: master

then in terminal,

flutter clean;flutter pub get;flutter packages upgrade

I haven't found a way to achieve this without the Future.delayed, as it happens too quick and then some SignalR connections get missed. But this now fits my requirements for multiple SignalR connections, and hope it does for you too.

Here's the example below - (Note the only change the to SignalR object is the starting parameter, where it requests an ID field as a string, so it can identify the different SignalR's. I keep track of these SignalR connections in a Map where the key is the ID, and the value is the SignalR object.

Note: I have only spent a couple of hours on this tested both ios and android which work. I will test more soon and make sure everything works as expected. Let me know if you find anything.


Map<String, SignalR> signalRMap = {};

for (int tripId in tripIdList) {
        if (signalRMap[tripId] != null) {
          print("SignalR ($tripId) - Already in signalR LIST! Continue -");
          continue;
        }

        var signalR = SignalR(tripId.toString(), signalRURL, "broadcastHub",
            hubMethods: hubMethods,
            statusChangeCallback: (value) {
              print("SignalR Status: " + value);
            },
            headers: headers,
            queryString: "token=$authKey",
            hubCallback: (methodName, message) => processMessage(message));
        signalRMap[tripId] = signalR;
        print("SignalR Status: " + "Connecting");

        var success = await signalR.connect();
        await Future.delayed(Duration(milliseconds: 500));
        serviceActive = true;

        if (success == true) {
          await signalR.invokeMethod("appWatch", arguments: ['$tripId']);
          print("SignalR Status:" + "Send App Watch");

          await Future.delayed(Duration(milliseconds: 500));
        }
      }