SecureSocket handshake can stall the main thread for long time

In my application, the SDK used before was 1.9 and everything worked fine. After upgrading to 1.12, android still works well, but ios will get stuck on the splash screen.

Detailed questions:

  1. Sometimes the first time you start it will get stuck on the splash screen.
  2. Manually kill the process and then enter the app, there is a high possibility that it will get stuck on the splash screen page.

Code situation

  1. pubspec.yaml
    http: 0.12.0+4
  2. lib/SplashPage.dart
class SplashPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _StdPageState();
  }
}

class _StdPageState extends State<SplashPage> {
  @override
  void initState() {
    super.initState();
    
    // send Http here
  }
}
  1. lib/util/HttpsUtils.dart
import 'dart:convert' show utf8;
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:inlan_flutter/Config.dart';
import 'package:inlan_flutter/util/DataUtils.dart';
import 'package:inlan_flutter/util/I18nUtils.dart';
import 'package:inlan_flutter/util/JsonUtils.dart';
import 'package:inlan_flutter/util/LogUtils.dart';
import 'package:inlan_flutter/util/ToastUtils.dart';
import 'package:inlan_flutter/util/UpgradeUtils.dart';
import 'package:inlan_flutter/util/UuidUtils.dart';

class HttpsUtils {
  static void apiPostWithUrl(
      String url,
      Map<String, dynamic> body,
      BuildContext context,
      StackTrace callPositionStackTrace,
      State state,
      callback(json)) async {
    body["version"] = Config.apiVersion;
    body["httpId"] = UuidUtils.v4();
    body["lang"] = I18nUtils.languageCode();
    body["path"] = url;

    String fullUrl = Config.apiUrl + url;

    final apiClient = http.Client();

    try {
      await apiClient
          .post(fullUrl,
              headers: {"Content-Type": "application/json"},
              body: JsonUtils.encode(body))
          .then((response) {
        LogUtils.log(response.statusCode, StackTrace.current,
            tag: "statusCode");

        LogUtils.devLog(Config.apiUrl + url, callPositionStackTrace,
            tag: "apiUrl " + url);

        LogUtils.devLog(JsonUtils.prettyJson(body), callPositionStackTrace,
            tag: "req");

        LogUtils.devLog(
            JsonUtils.prettyStr(response.body), callPositionStackTrace,
            tag: "resp ${response.statusCode}");

        switch (response.statusCode) {
          case 200:
            callback(JsonUtils.parse(response.body));
            break;
          case 400:
            Map<String, dynamic> jsonObj = JsonUtils.parse(response.body);
            state.setState(() {
              ToastUtils.short(jsonObj["message"]);
            });
            break;
          case 401:
            Map<String, dynamic> jsonObj = JsonUtils.parse(response.body);
            state.setState(() {
              ToastUtils.withCallback(jsonObj["message"], () {
                DataUtils.setByService('login_data', '-1');
                DataUtils.setByService('isLogined', '-1');
                Navigator.pushNamedAndRemoveUntil(
                    context, '/account', (Route<dynamic> route) => false);
              });
            });
            break;
          case 403:
            break;
          case 406:
            UpgradeUtils().doForceUpgrade(context);
            break;
          case 422:
            Map<String, dynamic> jsonObj = JsonUtils.parse(response.body);
            state.setState(() {
              ToastUtils.short(jsonObj["message"]);
            });
            break;
        }
      });
    } finally {
      apiClient.close();
    }
  }
}

My temporary solution

  void initState() {
    super.initState();
    Timer timer = new Timer(new Duration(milliseconds: 1200), () {
      // send Http here
    });
    
  }

Expected solution

  1. What causes the freeze?
  2. A better solution?

Author: Fantashit

1 thought on “SecureSocket handshake can stall the main thread for long time

Comments are closed.