knaeckeKami / gql_phoenix_link

A gql Link for communicating over Phoenix Channels
MIT License
11 stars 9 forks source link

Heartbeat #3

Closed redDwarf03 closed 2 years ago

redDwarf03 commented 2 years ago

Hello

when i use PhoenixLink with SubscriptionChannel class, i try to close subscription but i see after the closing, some logs with Capture d’écran 2022-08-09 à 12 08 43 Do you know how to close completely the connection please

Thx

// 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();
    }
    if (channel != null) {
      channel!.close();
    }
  }
}
knaeckeKami commented 2 years ago

looks good to me. maybe an issue with phoenix_socket? or are you sure that you don't create other instances of the connection?

redDwarf03 commented 2 years ago

i used:

  await subscriptionChannel.connect(
        await preferences.getNetwork().getPhoenixHttpLink(),
        await preferences.getNetwork().getWebsocketUri());

    subscriptionChannel.addSubscriptionTransactionConfirmed(
        keychainTransaction.address!, waitConfirmations);

    final TransactionStatus transactionStatus =
        sendTx(transaction);

    subscriptionChannel.close();

and


  void waitConfirmations(QueryResult event) {
    if (event.data != null &&
        event.data!['transactionConfirmed'] != null &&
        event.data!['transactionConfirmed']['nbConfirmations'] != null) {
      int nb = event.data!['transactionConfirmed']['nbConfirmations'];
    } else {
        throw Exception('no confirmation");
    }
  }

(Another thing, do you know how to catch a timeout if i never receive a response from the server ?)

Thank you for your precious help

redDwarf03 commented 2 years ago

for info, i add a "leave" call but it doesn't work Capture d’écran 2022-08-09 à 15 10 56

knaeckeKami commented 2 years ago

no idea, sorry

redDwarf03 commented 2 years ago

ok thank you. absinthe and phoenix are not simple to manage subscription with flutter... too few public examples :(