shamblett / coap

A Coap package for dart
Other
16 stars 13 forks source link

Bad state: Cannot add new events after calling close #25

Closed anayajoshi closed 3 years ago

anayajoshi commented 3 years ago

Hello, I am facing this issue while working with coal operations. I don't want to keep coap client running continuously in my app application. So that I am closing it at some point. But whenever required, when I tried to create new instance and send command on it, I am getting this exception. Is there any method to clear bloc instances of coap client?

Please guide.

shamblett commented 3 years ago

OK, this shouldn't happen, I'll l add a fix for this.

shamblett commented 3 years ago

This should be fixed, please re test. Package re published at version 2.0.4.

anayajoshi commented 3 years ago

Ok, I will check it. Thank you so much for the prompt reply and fix of issue.

anayajoshi commented 3 years ago

Hello, I have checked by update coap version 2.9.4.

But still the issue exist. Following is the log:

I/flutter ( 9609): Closing client I/flutter ( 9609): 2021-02-14 16:53:49.951: INFO: >> Close - closing client I/flutter ( 9609): 2021-02-14 16:53:49.952: INFO: >> Endpoint - stopping endpoint bound to InternetAddress('192.168.1.59', IPv4) I/flutter ( 9609): 2021-02-14 16:53:49.952: INFO: >> Network UDP - closing 192.168.1.59, port 5683 I/HwPointEventFilter( 9609): do not support AFT because of no config I/flutter ( 9609): 2021-02-14 16:53:59.709: INFO: >> Start Mark-And-Sweep with 0 entries I/flutter ( 9609): Initialising client I/flutter ( 9609): Coap client instantiated: Instance of 'MyCoapClient' I/flutter ( 9609): 2021-02-14 16:54:01.282: INFO: >> CoapUtils:lookupHost host '192.168.1.59' is an IP address, not resolving I/flutter ( 9609): 2021-02-14 16:54:01.287: SEVERE: >> BlockwiseLayer uses MaxMessageSize: 1024 and DefaultBlockSize: 512 I/flutter ( 9609): 2021-02-14 16:54:01.288: INFO: >> CoapNetworkUDP - binding to 0.0.0.0 I/flutter ( 9609): 2021-02-14 16:54:01.289: INFO: >> Starting endpoint bound to InternetAddress('192.168.1.59', IPv4) I/flutter ( 9609): 2021-02-14 16:54:01.294: INFO: >> Reliability - Scheduling transmission for I/flutter ( 9609): <<< Request Message >>> I/flutter ( 9609): Type: 0, Code: GET, Id: 1708, Token: 000008f0, I/flutter ( 9609): Options = I/flutter ( 9609): [ I/flutter ( 9609): If-Match : I/flutter ( 9609): Uri Host : Uri-Host: 192.168.1.59 I/flutter ( 9609): E-tags : I/flutter ( 9609): None I/flutter ( 9609): Uri Port : 5683 I/flutter ( 9609): Location Paths: I/flutter ( 9609): Uri Paths : inline I/flutter ( 9609): Content-Type : None I/flutter ( 9609): Max Age : None I/flutter ( 9609): Uri Queries : Uri-Query: 117/12/115/134/status/3/2/2 I/flutter ( 9609): Accept : None I/flutter ( 9609): Location Queries : I/flutter ( 9609): Proxy Uri : None I/flutter ( 9609): Proxy Scheme : None I/flutter ( 9609): Block 1 : None I/flutter ( 9609): Block 2 : None I/flutter ( 9609): Observe : -1 I/flutter ( 9609): Size 1 : 0 I/flutter ( 9609): Size 2 : 0 I/flutter ( 9609): ], I/flutter ( 9609): Payload : I/flutter ( 9609): null I/flutter ( 9609): 2021-02-14 16:54:01.295: INFO: >> Reliability - sending request, failed transmission count: 0 I/flutter ( 9609): 2021-02-14 16:54:01.295: INFO: >> Reliability - Retransmission timeout is 724 ms I/flutter ( 9609): 2021-02-14 16:54:01.296: INFO: >> Matcher - Stored open request by KeyID[1708]) + KeyToken[000008f0] E/flutter ( 9609): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: Cannot add new events after calling close E/flutter ( 9609): #0 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:249:24) E/flutter ( 9609): #1 EventBus.fire (package:event_bus/event_bus.dart:61:22) E/flutter ( 9609): #2 CoapEventBus.fire (package:coap/src/event/coap_event_bus.dart:153:17) E/flutter ( 9609): #3 CoapEndPoint.sendRequest (package:coap/src/net/coap_endpoint.dart:176:15) E/flutter ( 9609): #4 CoapStackBottomLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:110:21) E/flutter ( 9609): #5 CoapNextLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:20:10) E/flutter ( 9609): #6 CoapAbstractLayer.sendRequest (package:coap/src/stack/coap_abstract_layer.dart:18:15) E/flutter ( 9609): #7 CoapReliabilityLayer.sendRequest (package:coap/src/stack/coap_reliability_layer.dart:139:11) E/flutter ( 9609): #8 CoapNextLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:20:10) E/flutter ( 9609): #9 CoapAbstractLayer.sendRequest (package:coap/src/stack/coap_abstract_layer.dart:18:15) E/flutter ( 9609): #10 CoapTokenLayer.sendRequest (package:coap/src/stack/coap_token_layer.dart:28:11) E/flutter ( 9609): #11 CoapNextLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:20:10) E/flutter ( 9609): #12 CoapAbstractLayer.sendRequest (package:coap/src/stack/coap_abstract_layer.dart:18:15) E/flutter ( 9609): #13 CoapBlockwiseLayer.sendRequest (package:coap/src/stack/coap_blockwise_layer.dart:56:13) E/flutter ( 9609): #14 CoapNextLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:20:10) E/flutter ( 9609): #15 CoapAbstractLayer.sendRequest (package:coap/src/stack/coap_abstract_layer.dart:18:15) E/flutter ( 9609): #16 CoapNextLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:20:10) E/flutter ( 9609): #17 CoapAbstractLayer.sendRequest (package:coap/src/stack/coap_abstract_layer.dart:18:15) E/flutter ( 9609): #18 CoapStackTopLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:66:11) E/flutter ( 9609): #19 CoapLayerStack.sendRequest (package:coap/src/stack/coap_layer_stack.dart:136:17) E/flutter ( 9609): #20 CoapEndPoint.sendEpRequest. (package:coap/src/net/coap_endpoint.dart:81:37) E/flutter ( 9609): #21 CoapExecutor.start. (package:coap/src/threading/coap_executor.dart:18:11) E/flutter ( 9609): #22 _Executor.scheduleTask (package:executor/src/executor_impl.dart:61:29) E/flutter ( 9609): E/flutter ( 9609): #23 CoapExecutor.start (package:coap/src/threading/coap_executor.dart:17:14) E/flutter ( 9609): #24 CoapEndPoint.sendEpRequest (package:coap/src/net/coap_endpoint.dart:81:14) E/flutter ( 9609): #25 CoapRequest.send (package:coap/src/coap_request.dart:120:14) E/flutter ( 9609): #26 MyCoapClient.send (package:gladiance_one/repository/coap/my_coap_client.dart:282:20) E/flutter ( 9609): E/flutter ( 9609): #27 MyCoapClient.get (package:gladiance_one/repository/coap/my_coap_client.dart:120:12) E/flutter ( 9609): #28 CoapClientWrapper.getLoadStatus (package:gladiance_one/repository/coap/coap_client_wrapper.dart:213:39) E/flutter ( 9609): E/flutter ( 9609): #29 LoadBloc.getLoadStatus (package:gladiance_one/blocs/load_bloc.dart:162:39) E/flutter ( 9609): #30 new LoadListItem (package:gladiance_one/screens/list/listitem/load_list_item.dart:25:16) E/flutter ( 9609): #31 LoadList.getLoadCardWidget. (package:gladiance_one/screens/list/load_list.dart:87:24) E/flutter ( 9609): #32 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:449:22) E/flutter ( 9609): #33 SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1130:28) E/flutter ( 9609): #34 SliverMultiBoxAdaptorElement.createChild. (package:flutter/src/widgets/sliver.dart:1143:55) E/flutter ( 9609): #35 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2683:19) E/flutter ( 9609): #36 SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:1136:11) E/flutter ( 9609): #37 RenderSliverMultiBoxAdaptor._createOrObtainChild. (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:350:23) E/flutter ( 9609): #38 RenderObject.invokeLayoutCallback. (package:flutter/src/rendering/object.dart:1883:59) E/flutter ( 9609): #39 PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:915:15) E/flutter ( 9609): #40 RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1883:14) E/flutter ( 9609): #41 RenderSliverMultiBoxAda I/flutter ( 9609): 2021-02-14 16:54:02.022: WARNING: >> Reliability - Retransmission timeout elapsed I/flutter ( 9609): 2021-02-14 16:54:02.023: WARNING: >> Reliability - Timeout: retransmit message, failed count: 1 message: 1708 I/flutter ( 9609): 2021-02-14 16:54:02.024: INFO: >> Reliability - Scheduling transmission for I/flutter ( 9609): <<< Request Message >>> I/flutter ( 9609): Type: 0, Code: GET, Id: 1708, Token: 000008f0, I/flutter ( 9609): Options = I/flutter ( 9609): [ I/flutter ( 9609): If-Match : I/flutter ( 9609): Uri Host : Uri-Host: 192.168.1.59 I/flutter ( 9609): E-tags : I/flutter ( 9609): None I/flutter ( 9609): Uri Port : 5683 I/flutter ( 9609): Location Paths: I/flutter ( 9609): Uri Paths : inline I/flutter ( 9609): Content-Type : None I/flutter ( 9609): Max Age : None I/flutter ( 9609): Uri Queries : Uri-Query: 117/12/115/134/status/3/2/2 I/flutter ( 9609): Accept : None I/flutter ( 9609): Location Queries : I/flutter ( 9609): Proxy Uri : None I/flutter ( 9609): Proxy Scheme : None I/flutter ( 9609): Block 1 : None I/flutter ( 9609): Block 2 : None I/flutter ( 9609): Observe : -1 I/flutter ( 9609): Size 1 : 0 I/flutter ( 9609): Size 2 : 0 I/flutter ( 9609): ], I/flutter ( 9609): Payload : I/flutter ( 9609): null I/flutter ( 9609): 2021-02-14 16:54:02.024: INFO: >> Reliability - sending request, failed transmission count: 1 I/flutter ( 9609): 2021-02-14 16:54:02.025: INFO: >> Reliability - Retransmission timeout is 1448 ms I/flutter ( 9609): 2021-02-14 16:54:02.026: INFO: >> Matcher - Stored open request by KeyID[1708]) + KeyToken[000008f0] E/flutter ( 9609): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: Cannot add new events after calling close E/flutter ( 9609): #0 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:249:24) E/flutter ( 9609): #1 EventBus.fire (package:event_bus/event_bus.dart:61:22) E/flutter ( 9609): #2 CoapEventBus.fire (package:coap/src/event/coap_event_bus.dart:153:17) E/flutter ( 9609): #3 CoapEndPoint.sendRequest (package:coap/src/net/coap_endpoint.dart:176:15) E/flutter ( 9609): #4 CoapStackBottomLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:110:21) E/flutter ( 9609): #5 CoapNextLayer.sendRequest (package:coap/src/stack/coap_layer_stack.dart:20:10) E/flutter ( 9609): #6 CoapAbstractLayer.sendRequest (package:coap/src/stack/coap_abstract_layer.dart:18:15) E/flutter ( 9609): #7 CoapReliabilityLayer.sendRequest (package:coap/src/stack/coap_reliability_layer.dart:139:11) E/flutter ( 9609): #8 CoapReliabilityLayer.sendRequest. (package:coap/src/stack/coap_reliability_layer.dart:136:28) E/flutter ( 9609): #9 CoapTransmissionContext._timerElapsed (package:coap/src/stack/coap_reliability_layer.dart:97:20) E/flutter ( 9609): #10 _rootRun (dart:async/zone.dart:1182:47) E/flutter ( 9609): #11 _CustomZone.run (dart:async/zone.dart:1093:19) E/flutter ( 9609): #12 _CustomZone.runGuarded (dart:async/zone.dart:997:7) E/flutter ( 9609): #13 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23) E/flutter ( 9609): #14 _rootRun (dart:async/zone.dart:1190:13) E/flutter ( 9609): #15 _CustomZone.run (dart:async/zone.dart:1093:19) E/flutter ( 9609): #16 _CustomZone.bindCallback. (dart:async/zone.dart:1021:23) E/flutter ( 9609): #17 Timer._createTimer. (dart:async-patch/timer_patch.dart:18:15) E/flutter ( 9609): #18 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19) E/flutter ( 9609): #19 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5) E/flutter ( 9609): #20 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12) E/flutter ( 9609): I/flutter ( 9609): 2021-02-14 16:54:03.476: WARNING: >> Reliability - Retransmission timeout elapsed

shamblett commented 3 years ago

I'm having trouble reproducing this, my test does this -

var client = CoapClient(uri, conf);
.
.
.

print('ISSUE: closing the client and re allocating');
  client.close();
  client = CoapClient(uri, conf);
  client.request = request;

  print('ISSUE: resending');
  await client.get();

so I close and re allocate the client, are you doing something else?

anayajoshi commented 3 years ago

Yes I am doing approximately same. My client object is global declared in a singleton class, and I have added some sleep time after closing client.

shamblett commented 3 years ago

I'm not seeing this whether I re allocate the client after the close as above or whether I just close the client and re use it again(this should correspond to your singleton usage). Could you verify you are using 2.0.4, please run a pub upgrade and post the output, also post the code for your singleton class, I may be missing something.

anayajoshi commented 3 years ago

Yes, I am using the latest coap version coap: ^2.0.4. Still is is required to run pub upgrade?

Below is my coap code:

// ----------------------------- coap operations ----------------------------- Future sendCoap(LoadState loadState) async { try { String payload = loadState.payload;

  debugPrint('payload = $payload');

    LoadEntity loadEntity = loadState.loadEntity;
initCoAPClient(loadEntity.ipaddress, loadEntity.port);

      String path = loadState.path;
      String query = loadState.query;

      // Create the request for the get request
      final CoapRequest request = CoapRequest.newPut();

      request.addUriPath(path);
      request.addUriQuery(query);

      Session.shared.client.request = request;

      final CoapResponse response =
          await Session.shared.client.put(payload);

      if (response != null) {
        print('\n--------------------------------------------------------');
        String status = response.payloadString;
        print('Put - response received, $status');
        Session.shared.client.cancelRequest();

        // TODO: remove after markobserve issue fixed
        LoadStatus loadStatus =
            LoadStatus.fromJson(loadEntity.functionno, jsonDecode(status));
        // loadEntity.level = loadStatus.level;

        loadStatusController.sink.add(loadStatus);
        print('--------------------------------------------------------\n');
        sleep(Duration(seconds: 1));

        // Update Other load status if that are dependant on current load
        updateOtherLoadStatus(
            loadEntity.functionno, loadEntity.functioncode, loadStatus);
      } else {
        print('Put - no response received');
        Session.shared.client.cancelRequest();
       }

       closeCoapClient();

} on PlatformException catch (e) {
  print('Error in load on-off. $e');
} catch (e) {
  print('Error in load on-off. $e');
}
return ResponseStatus.withParams(1, "", "");

}

initCoAPClient(host, port) async { print('Initialising client'); final CoapConfig conf = CoapConfig();

if (Session.shared.client == null) {
  Uri uri = Uri(scheme: CoapConstants.uriScheme, host: host, port: port);
  Session.shared.client = MyCoapClient(uri, conf);

  print('Coap client instantiated: ${Session.shared.client}');
} else {
  String uriString = Session.shared.client.uri.toString();
  String oldHost = Session.shared.client.uri.host;

  print('Coap client old uri: $uriString, host: $oldHost');

  if (host != oldHost) {
    Uri uri = Uri(scheme: CoapConstants.uriScheme, host: host, port: port);
    Session.shared.client.uri = uri;
    print('Coap client - bind to new uri: $uri');
  }
}

Session.shared.client.timeout = 10000;

}

static Future closeCoapClient() async { try { print('Closing client'); Session.shared.client.close(); Session.shared.client = null;

  sleep(Duration(seconds: 2));
} catch (e) {
  print('Error in closeCoapClient. $e');
}

}

shamblett commented 3 years ago

This just shows me your methods, not the sequence in which you are calling them, looking at the output you posted above it looks as though you are closing the client while a request is still outstanding, i.e. you are getting this straight after your request message is transmitted -

E/flutter ( 9609): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: Cannot add new events after calling close

Looking at your code closeCoapClient returns a future but when you call it you do not await it i.e. you do this -

 closeCoapClient();

If you call close you must re allocate the client or send your request again, working example below -

import 'dart:async';
import 'package:coap/coap.dart';
import 'config/coap_config.dart';

FutureOr main() async {
  // Create a configuration class. Logging levels can be specified in the
  // configuration file.
  final conf = CoapConfig();

  // Build the request uri, note that the request paths/query parameters can be changed
  // on the request anytime after this initial setup.
  const host = 'coap.me';

  final uri = Uri(scheme: 'coap', host: host, port: conf.defaultPort);

  // Create the client.
  // The method we are using creates its own request so we do not
  // need to supply one.
  // The current request is always available from the client.
  var client = CoapClient(uri, conf);

  // Create the request for the get request
  final request = CoapRequest.withType(CoapCode.methodGET);
  request.addUriPath('obs');
  print('ISSUE: max retransmit from request is ${request.maxRetransmit}');

  // You can override the configured maxretransmit setting on a request by request basis
  request.maxRetransmit = 2;
  print('ISSUE: max retransmit from request is now ${request.maxRetransmit}');
  // Getting responses from the observable resource
  request.responses.listen((CoapResponse response) {
    print('ISSUE: - payload: ${response.payloadString}');
  });

  client.request = request;

  print('ISSUE: - Sending get request to '
      '$host, waiting for responses ....');
  await client.get();

  print('ISSUE: closing the client and re allocating it and the request');
  client.close();
  client = null;
  client = CoapClient(uri, conf);
  final request2 = CoapRequest.withType(CoapCode.methodGET);
  request2.addUriPath('obs');
  request2.maxRetransmit = 2;
  client.request = request2;

  print('ISSUE: resending');
  await client.get();

}

The output of pub upgrade will show you exactly what version you are using, which may not be the one you think you are.

shamblett commented 3 years ago

No further updates, closing.