import 'dart:async'; import 'dart:convert'; import 'dart:core'; import 'dart:core'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:huixiang/im/Proto.dart'; import 'package:huixiang/im/database/message.dart'; import 'package:huixiang/im/out/auth.pb.dart'; import 'package:huixiang/im/out/message.pb.dart'; import 'package:huixiang/main.dart'; import 'package:shared_preferences/shared_preferences.dart'; class SocketClient { //47.93.216.24:9090 线上 192.168.10.129:9090 测试 final String ip = kDebugMode ? '192.168.10.129' : '47.93.216.24'; final num port = 9090; Socket _socket; SharedPreferences shared; connect() async { shared = await SharedPreferences.getInstance(); await Socket.connect(ip, port).then((value) { debugPrint("socket-connect-$ip"); _socket = value; _socket.listen((data) { print(data); print("socket-listen"); Proto proto = Proto.fromBytes(data); MsgData dataResult = MsgData.fromBuffer(proto.body); print('收到来自:${dataResult.from},消息内容: ${utf8.decode(dataResult.data)} '); Map messageMap = createMessage(userId, utf8.decode(dataResult.data), msgType: dataResult.type.value, userId: dataResult.from); Message message = Message.fromJson(messageMap); callbacks[userId]?.call(message); /// user self conversation callback if (callbacks[dataResult.from] != null) { // messageMap["state"] = 1; message.state = 1; callbacks[dataResult.from].call(message); /// user conversation callback } hxDatabase.insert(messageMap); }, onError: (Object error, StackTrace stackTrace) { debugPrint("socket-listen-error: $error, stackTrace: $stackTrace"); reconnect(); }, onDone: () { debugPrint("socket-listen-down: down"); }); authRequest(shared.getString("token")); heartbeat(); }).catchError((error) { debugPrint("socket-connect-error: $error"); reconnectTime = 1500; _socket = null; reconnect(); }); } heartbeat() { Timer.periodic(const Duration(milliseconds: 30000), (timer) { int milliseTime = DateTime.now().millisecondsSinceEpoch; debugPrint("heartbeat: ${milliseTime}"); Uint8List data = utf8.encode(jsonEncode({"heartbeat": milliseTime})); MsgData msgData = MsgData(from: userId, type: MsgType.TEXT, data: data); final proto2 = Proto(3, 1, msgData.writeToBuffer()); if(!checkSocket()) { timer.cancel(); return; } _socket.add(proto2.toBytes()); }); } int reconnectTime = 600; reconnect() { Future.delayed(Duration(milliseconds: reconnectTime *= 2), () { dispose(); connect(); }); } Map callbacks = {}; addCallback(String userId, callback) { callbacks[userId] = callback; } removeCallback(String userId) { callbacks.remove(userId); } dispose() { if (_socket != null) { _socket.close(); _socket = null; } } authRequest(String token) { if (!checkSocket()) { return; } final authReq = AuthReq() ..uid = userId ..token = token; final authReqBytes = authReq.writeToBuffer(); final proto = Proto(1, 1, authReqBytes); // 假设 operation 和 seqId 为 1 final protoBytes = proto.toBytes(); _socket.add(protoBytes); } Future sendMessage(String toId, String content) async { Map message = createMessage(toId, content, userId: userId); int id = await hxDatabase.insert(message).catchError((error) { debugPrint("insertMessage: $error"); }); if (!checkSocket()) { hxDatabase.update({"id": id, "state": 3}).catchError((error) { debugPrint("insertMessage: ${error.toString()}"); }); message["id"] = id; message["state"] = 3; return Message.fromJson(message); } message["id"] = id; Uint8List data = utf8.encode(content); MsgData msgData = MsgData(to: toId, from: userId, type: MsgType.TEXT, data: data); final proto2 = Proto(5, 1, msgData.writeToBuffer()); _socket.add(proto2.toBytes()); debugPrint("sendMessage: ${message["id"]}"); return Message.fromJson(message); } checkSocket() { if (_socket == null) { reconnectTime = 1000; reconnect(); return false; } return true; } String get userId => shared.getString("userId"); }