import 'dart:async'; import 'dart:io'; import 'dart:convert'; import 'dart:typed_data'; class SocketClient { SocketClient(this._ipAddress, this._port); static const int headerSize = 10; static const int intSize = 4; late final String _ipAddress; late final int _port; late Socket? _socket; late List _byteList = []; late int _total = -1; late Function? eventDisconnected; late Function(String) eventReceiveMessage; void connect([void Function(bool result)? resultListener]) { bool connected = false; Socket.connect(_ipAddress, _port).then((socket) { try { _socket = socket; _socket!.listen(_onMessage, onError: _onError, onDone: _onDone); print('[SocketClient] Socket connected to $_ipAddress'); connected = true; } catch (e) { print(e); } resultListener?.call(connected); // ignore: argument_type_not_assignable_to_error_handler }).catchError((AsyncError e) { print('Unable to connect: $e'); resultListener?.call(connected); }); } //extra: 6bytes의 커스텀 정보, 서버와 프로토콜이 맞춰져있어야함 void send(String message, [List? extra]) { final byteMessage = utf8.encode(message); // final byteLength = ByteArray(4); // byteLength.writeInt(byteMessage.length); // final byteArray = byteLength.buffer.asUint8List(0, 4); final byteLength = Uint8List(4); final byteDataLength = byteLength.buffer.asByteData(); byteDataLength.setInt32(0, byteMessage.length); final byteArray = byteLength.buffer.asUint8List(0, 4); final byteExtra = extra == null ? [0, 0, 0, 0, 0, 0] : extra; final byteSend = byteArray + byteExtra + byteMessage; _socket!.add(byteSend); } void disconnect() { eventDisconnected?.call(); _socket!.close(); _socket = null; } void _onMessage(data) { final byteData = data as Uint8List; try { final bytesRead = byteData.length; //print('Data Recevied!! $bytesRead'); if (bytesRead > 0) { _byteList += byteData; } _parsing(); } on Exception catch (e) { print(e); print(utf8.decode(byteData)); } } void _parsing() { if (_total < 0) { if (_byteList.length >= headerSize) { final bytesLength = Uint8List.fromList( _byteList.getRange(0, intSize).toList(growable: false)); final bytesExtra = Uint8List.fromList( _byteList.getRange(intSize, headerSize).toList(growable: false)); _total = bytesLength.buffer.asByteData().getInt32(0, Endian.big); // _total = ByteArray.fromBuffer(bytesLength.buffer).readInt(); print(_total); if (_total == 0) { _total = -1; _byteList.clear(); } else { _parsing(); } } } else { if (_byteList.length >= _total + headerSize) { _byteList.removeRange(0, headerSize); final list = Uint8List.fromList( _byteList.getRange(0, _total).toList(growable: false)); final message = utf8.decode(list); //print(message); eventReceiveMessage(message); _byteList = _byteList.getRange(_total, _byteList.length).toList(); _total = -1; _parsing(); } } } void _onError(error, StackTrace trace) { print('onError: $error'); } void _onDone() { print('Disconnected'); eventDisconnected?.call(); } }