dart-app-core/lib/socket/socket_client.dart

116 lines
3.4 KiB
Dart

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<int> _byteList = <int>[];
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<int>? 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();
}
}