// ignore_for_file: avoid_init_to_null, prefer_final_fields, avoid_print import 'dart:io'; import 'dart:typed_data'; import 'package:dart_framework/utils/system_util.dart'; import 'package:protobuf/protobuf.dart'; import 'package:dart_framework/communicator.dart'; import 'package:dart_framework/socket/packets/message_common.pb.dart'; class ProtobufClient extends Communicator { final int _headerSize = 4; final Socket _socket; int? _length = null; late List _arrivedData = []; List _onDisconnectListenerList = []; ProtobufClient(this._socket) { print('Connected New Client'); super.initialize({ (TemplateData).toString() : TemplateData.fromBuffer }); addListener(onHeartBeat); _socket.listen(onData, onError: onError) .asFuture().then(onDisconnected); } void onHeartBeat(HeartBeat data) { } void addDisconnectListener(void Function(ProtobufClient) handler) { if(!_onDisconnectListenerList.contains(handler)) { _onDisconnectListenerList.add(handler); } } void removeDisconnectListener(void Function(ProtobufClient) handler) { if(_onDisconnectListenerList.contains(handler)) { _onDisconnectListenerList.remove(handler); } } void onDisconnected(dynamic data) { //client disconnected for (var item in _onDisconnectListenerList) { item.call(this); } } void onError(dynamic e) { print('=========> onError: $e'); } void onData(Uint8List data) async { try { // printPacket('## Received', data); if(_length == null) { var header = data.sublist(0, _headerSize); _length = header.buffer.asByteData().getInt32(0); _arrivedData.addAll(data.sublist(_headerSize)); } else { _arrivedData.addAll(data); } if(_arrivedData.length == _length) { var common = PacketBase.fromBuffer(_arrivedData); var nonce = common.nonce; onReceivedData(common.typeName, common.data); _length = null; _arrivedData.clear(); } } on Exception catch(e) { print(e); } } @override Future send(T data) async { List packet = []; var base = PacketBase(); base.typeName = data.info_.qualifiedMessageName; base.nonce = 0; base.data = data.writeToBuffer(); var baseBytes = base.writeToBuffer(); int length = baseBytes.length + _headerSize; var header = Uint8List(_headerSize) ..buffer.asByteData().setInt32(0, length); packet.addAll(header); packet.addAll(baseBytes); // printPacket('Send', packet); _socket.add(packet); await _socket.flush(); return simpleFuture; } void printPacket(String prefix, List packet) { var s = StringBuffer(); for(var item in packet) { s.write('$item, '); } print('$prefix: ${s.toString()}'); } void dispose() { _onDisconnectListenerList.clear(); _arrivedData.clear(); _socket.close(); } }