Remove socket and protobuf related files
This commit is contained in:
parent
870eba5e94
commit
b2ce159bed
11 changed files with 0 additions and 759 deletions
|
|
@ -1,14 +0,0 @@
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
message PacketBase {
|
|
||||||
string typeName = 1;
|
|
||||||
int32 nonce = 2;
|
|
||||||
bytes data = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message HeartBeat {}
|
|
||||||
|
|
||||||
message TestData {
|
|
||||||
int32 index = 1;
|
|
||||||
string message = 2;
|
|
||||||
}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
|
|
||||||
// ignore_for_file: prefer_final_fields
|
|
||||||
|
|
||||||
import 'package:protobuf/protobuf.dart';
|
|
||||||
|
|
||||||
abstract class Communicator
|
|
||||||
{
|
|
||||||
Map<String, IDataHandler> _handlerDic = {};
|
|
||||||
late Map<String, GeneratedMessage Function(List<int>)> _instanceGenerator;
|
|
||||||
|
|
||||||
Communicator();
|
|
||||||
|
|
||||||
void initialize(Map<String, GeneratedMessage Function(List<int>)> instanceGenerator)
|
|
||||||
{
|
|
||||||
_instanceGenerator = instanceGenerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
T Function(List<int>) getGenerator<T extends GeneratedMessage>(String type)
|
|
||||||
{
|
|
||||||
if(!_instanceGenerator.containsKey(type))
|
|
||||||
{
|
|
||||||
throw Exception('Must set protobuf packet creator before use it. Type: ${(T).toString()}');
|
|
||||||
}
|
|
||||||
return _instanceGenerator[type] as T Function(List<int>);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future send<T extends GeneratedMessage>(T data);
|
|
||||||
|
|
||||||
void onReceivedData(String typeName, List<int> data)
|
|
||||||
{
|
|
||||||
if( _handlerDic.containsKey(typeName) ) {
|
|
||||||
_handlerDic[typeName]?.onMessage(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addListener<T extends GeneratedMessage>(void Function(T) listener)
|
|
||||||
{
|
|
||||||
var type = T.toString();
|
|
||||||
if(!_handlerDic.containsKey(type))
|
|
||||||
{
|
|
||||||
_handlerDic[type] = DataHandler<T>(getGenerator(type));
|
|
||||||
}
|
|
||||||
var handler = _handlerDic[type] as DataHandler<T>;
|
|
||||||
handler.addListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeListener<T extends GeneratedMessage>(void Function(T) listener)
|
|
||||||
{
|
|
||||||
var type = T.toString();
|
|
||||||
if(_handlerDic.containsKey(type))
|
|
||||||
{
|
|
||||||
var handler = _handlerDic[type] as DataHandler<T>;
|
|
||||||
handler.removeListener(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class IDataHandler
|
|
||||||
{
|
|
||||||
void onMessage(List<int> data);
|
|
||||||
}
|
|
||||||
|
|
||||||
class DataHandler<T extends GeneratedMessage> implements IDataHandler
|
|
||||||
{
|
|
||||||
T Function(List<int>) _generator;
|
|
||||||
List<void Function(T)> _listeners = [];
|
|
||||||
|
|
||||||
DataHandler(this._generator);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onMessage(List<int> data)
|
|
||||||
{
|
|
||||||
for(var listener in _listeners)
|
|
||||||
{
|
|
||||||
listener.call(_generator(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addListener(void Function(T) handler)
|
|
||||||
{
|
|
||||||
removeListener(handler); //중복 리스너 불허
|
|
||||||
_listeners.add(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeListener(void Function(T) handler)
|
|
||||||
{
|
|
||||||
_listeners.remove(handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
||||||
//
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: message_common.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
|
|
||||||
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
|
|
||||||
// ignore_for_file: constant_identifier_names, library_prefixes
|
|
||||||
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
|
|
||||||
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
|
|
||||||
|
|
||||||
import 'dart:core' as $core;
|
|
||||||
|
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
|
||||||
|
|
||||||
class PacketBase extends $pb.GeneratedMessage {
|
|
||||||
factory PacketBase({
|
|
||||||
$core.String? typeName,
|
|
||||||
$core.int? nonce,
|
|
||||||
$core.List<$core.int>? data,
|
|
||||||
}) {
|
|
||||||
final $result = create();
|
|
||||||
if (typeName != null) {
|
|
||||||
$result.typeName = typeName;
|
|
||||||
}
|
|
||||||
if (nonce != null) {
|
|
||||||
$result.nonce = nonce;
|
|
||||||
}
|
|
||||||
if (data != null) {
|
|
||||||
$result.data = data;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
PacketBase._() : super();
|
|
||||||
factory PacketBase.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
|
||||||
factory PacketBase.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
|
||||||
|
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'PacketBase', createEmptyInstance: create)
|
|
||||||
..aOS(1, _omitFieldNames ? '' : 'typeName', protoName: 'typeName')
|
|
||||||
..a<$core.int>(2, _omitFieldNames ? '' : 'nonce', $pb.PbFieldType.O3)
|
|
||||||
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'data', $pb.PbFieldType.OY)
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
PacketBase clone() => PacketBase()..mergeFromMessage(this);
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
PacketBase copyWith(void Function(PacketBase) updates) => super.copyWith((message) => updates(message as PacketBase)) as PacketBase;
|
|
||||||
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static PacketBase create() => PacketBase._();
|
|
||||||
PacketBase createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<PacketBase> createRepeated() => $pb.PbList<PacketBase>();
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static PacketBase getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<PacketBase>(create);
|
|
||||||
static PacketBase? _defaultInstance;
|
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
$core.String get typeName => $_getSZ(0);
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
set typeName($core.String v) { $_setString(0, v); }
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
$core.bool hasTypeName() => $_has(0);
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
void clearTypeName() => clearField(1);
|
|
||||||
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
$core.int get nonce => $_getIZ(1);
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
set nonce($core.int v) { $_setSignedInt32(1, v); }
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
$core.bool hasNonce() => $_has(1);
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
void clearNonce() => clearField(2);
|
|
||||||
|
|
||||||
@$pb.TagNumber(3)
|
|
||||||
$core.List<$core.int> get data => $_getN(2);
|
|
||||||
@$pb.TagNumber(3)
|
|
||||||
set data($core.List<$core.int> v) { $_setBytes(2, v); }
|
|
||||||
@$pb.TagNumber(3)
|
|
||||||
$core.bool hasData() => $_has(2);
|
|
||||||
@$pb.TagNumber(3)
|
|
||||||
void clearData() => clearField(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
class HeartBeat extends $pb.GeneratedMessage {
|
|
||||||
factory HeartBeat() => create();
|
|
||||||
HeartBeat._() : super();
|
|
||||||
factory HeartBeat.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
|
||||||
factory HeartBeat.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
|
||||||
|
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'HeartBeat', createEmptyInstance: create)
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
HeartBeat clone() => HeartBeat()..mergeFromMessage(this);
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
HeartBeat copyWith(void Function(HeartBeat) updates) => super.copyWith((message) => updates(message as HeartBeat)) as HeartBeat;
|
|
||||||
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static HeartBeat create() => HeartBeat._();
|
|
||||||
HeartBeat createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<HeartBeat> createRepeated() => $pb.PbList<HeartBeat>();
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static HeartBeat getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<HeartBeat>(create);
|
|
||||||
static HeartBeat? _defaultInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestData extends $pb.GeneratedMessage {
|
|
||||||
factory TestData({
|
|
||||||
$core.int? index,
|
|
||||||
$core.String? message,
|
|
||||||
}) {
|
|
||||||
final $result = create();
|
|
||||||
if (index != null) {
|
|
||||||
$result.index = index;
|
|
||||||
}
|
|
||||||
if (message != null) {
|
|
||||||
$result.message = message;
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
TestData._() : super();
|
|
||||||
factory TestData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
|
||||||
factory TestData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
|
||||||
|
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'TestData', createEmptyInstance: create)
|
|
||||||
..a<$core.int>(1, _omitFieldNames ? '' : 'index', $pb.PbFieldType.O3)
|
|
||||||
..aOS(2, _omitFieldNames ? '' : 'message')
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
TestData clone() => TestData()..mergeFromMessage(this);
|
|
||||||
@$core.Deprecated(
|
|
||||||
'Using this can add significant overhead to your binary. '
|
|
||||||
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
|
||||||
'Will be removed in next major version')
|
|
||||||
TestData copyWith(void Function(TestData) updates) => super.copyWith((message) => updates(message as TestData)) as TestData;
|
|
||||||
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static TestData create() => TestData._();
|
|
||||||
TestData createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<TestData> createRepeated() => $pb.PbList<TestData>();
|
|
||||||
@$core.pragma('dart2js:noInline')
|
|
||||||
static TestData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TestData>(create);
|
|
||||||
static TestData? _defaultInstance;
|
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
$core.int get index => $_getIZ(0);
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
set index($core.int v) { $_setSignedInt32(0, v); }
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
$core.bool hasIndex() => $_has(0);
|
|
||||||
@$pb.TagNumber(1)
|
|
||||||
void clearIndex() => clearField(1);
|
|
||||||
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
$core.String get message => $_getSZ(1);
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
set message($core.String v) { $_setString(1, v); }
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
$core.bool hasMessage() => $_has(1);
|
|
||||||
@$pb.TagNumber(2)
|
|
||||||
void clearMessage() => clearField(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
|
|
||||||
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
//
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: message_common.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
|
|
||||||
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
|
|
||||||
// ignore_for_file: constant_identifier_names, library_prefixes
|
|
||||||
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
|
|
||||||
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
|
|
||||||
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
//
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: message_common.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
|
|
||||||
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
|
|
||||||
// ignore_for_file: constant_identifier_names, library_prefixes
|
|
||||||
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
|
|
||||||
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
|
|
||||||
|
|
||||||
import 'dart:convert' as $convert;
|
|
||||||
import 'dart:core' as $core;
|
|
||||||
import 'dart:typed_data' as $typed_data;
|
|
||||||
|
|
||||||
@$core.Deprecated('Use packetBaseDescriptor instead')
|
|
||||||
const PacketBase$json = {
|
|
||||||
'1': 'PacketBase',
|
|
||||||
'2': [
|
|
||||||
{'1': 'typeName', '3': 1, '4': 1, '5': 9, '10': 'typeName'},
|
|
||||||
{'1': 'nonce', '3': 2, '4': 1, '5': 5, '10': 'nonce'},
|
|
||||||
{'1': 'data', '3': 3, '4': 1, '5': 12, '10': 'data'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Descriptor for `PacketBase`. Decode as a `google.protobuf.DescriptorProto`.
|
|
||||||
final $typed_data.Uint8List packetBaseDescriptor = $convert.base64Decode(
|
|
||||||
'CgpQYWNrZXRCYXNlEhoKCHR5cGVOYW1lGAEgASgJUgh0eXBlTmFtZRIUCgVub25jZRgCIAEoBV'
|
|
||||||
'IFbm9uY2USEgoEZGF0YRgDIAEoDFIEZGF0YQ==');
|
|
||||||
|
|
||||||
@$core.Deprecated('Use heartBeatDescriptor instead')
|
|
||||||
const HeartBeat$json = {
|
|
||||||
'1': 'HeartBeat',
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Descriptor for `HeartBeat`. Decode as a `google.protobuf.DescriptorProto`.
|
|
||||||
final $typed_data.Uint8List heartBeatDescriptor = $convert.base64Decode(
|
|
||||||
'CglIZWFydEJlYXQ=');
|
|
||||||
|
|
||||||
@$core.Deprecated('Use testDataDescriptor instead')
|
|
||||||
const TestData$json = {
|
|
||||||
'1': 'TestData',
|
|
||||||
'2': [
|
|
||||||
{'1': 'index', '3': 1, '4': 1, '5': 5, '10': 'index'},
|
|
||||||
{'1': 'message', '3': 2, '4': 1, '5': 9, '10': 'message'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Descriptor for `TestData`. Decode as a `google.protobuf.DescriptorProto`.
|
|
||||||
final $typed_data.Uint8List testDataDescriptor = $convert.base64Decode(
|
|
||||||
'CghUZXN0RGF0YRIUCgVpbmRleBgBIAEoBVIFaW5kZXgSGAoHbWVzc2FnZRgCIAEoCVIHbWVzc2'
|
|
||||||
'FnZQ==');
|
|
||||||
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
//
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: message_common.proto
|
|
||||||
//
|
|
||||||
// @dart = 2.12
|
|
||||||
|
|
||||||
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
|
|
||||||
// ignore_for_file: constant_identifier_names
|
|
||||||
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
|
|
||||||
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
|
|
||||||
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
|
|
||||||
|
|
||||||
export 'message_common.pb.dart';
|
|
||||||
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
// ignore_for_file: avoid_init_to_null, prefer_final_fields, avoid_print
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:async';
|
|
||||||
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';
|
|
||||||
|
|
||||||
abstract class ProtobufClient extends Communicator {
|
|
||||||
final int _headerSize = 4;
|
|
||||||
late int _heartbeatIntervalTime;
|
|
||||||
late int _heartbeatWaitTime;
|
|
||||||
final Socket _socket;
|
|
||||||
late ResponseChecker? _heartbeatChecker = null;
|
|
||||||
int? _length = null;
|
|
||||||
bool _isAlive = false;
|
|
||||||
late List<int> _arrivedData = [];
|
|
||||||
List<void Function(ProtobufClient)> _onDisconnectListenerList = [];
|
|
||||||
|
|
||||||
ProtobufClient(
|
|
||||||
this._socket,
|
|
||||||
this._heartbeatIntervalTime,
|
|
||||||
this._heartbeatWaitTime,
|
|
||||||
Map<String, GeneratedMessage Function(List<int>)> parserMap) {
|
|
||||||
print('Connected New Client');
|
|
||||||
_isAlive = true;
|
|
||||||
parserMap.addAll({
|
|
||||||
(TestData).toString(): TestData.fromBuffer,
|
|
||||||
(HeartBeat).toString(): HeartBeat.fromBuffer
|
|
||||||
});
|
|
||||||
super.initialize(parserMap);
|
|
||||||
_socket.listen(onData, onError: onError).asFuture().then(onDisconnected);
|
|
||||||
addListener(onHeartBeat);
|
|
||||||
sendHeartBeat();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendHeartBeat() {
|
|
||||||
if (_isAlive) {
|
|
||||||
_heartbeatChecker?.responsed();
|
|
||||||
_heartbeatChecker =
|
|
||||||
ResponseChecker.second(this, _heartbeatIntervalTime, (client) {
|
|
||||||
if (_isAlive) {
|
|
||||||
send(HeartBeat());
|
|
||||||
_heartbeatChecker =
|
|
||||||
ResponseChecker.second(this, _heartbeatWaitTime, (client) {
|
|
||||||
if (_isAlive) {
|
|
||||||
dispose();
|
|
||||||
onDisconnected(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onHeartBeat(HeartBeat data) {
|
|
||||||
print('=== onHeartBeat');
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
if (_isAlive) {
|
|
||||||
for (var item in _onDisconnectListenerList) {
|
|
||||||
item.call(this);
|
|
||||||
}
|
|
||||||
_onDisconnectListenerList.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
sendHeartBeat();
|
|
||||||
}
|
|
||||||
} on Exception catch (e) {
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future send<T extends GeneratedMessage>(T data) async {
|
|
||||||
if (_isAlive) {
|
|
||||||
try {
|
|
||||||
List<int> 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();
|
|
||||||
} catch (e) {
|
|
||||||
onDisconnected(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return simpleFuture;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printPacket(String prefix, List<int> packet) {
|
|
||||||
var s = StringBuffer();
|
|
||||||
for (var item in packet) {
|
|
||||||
s.write('$item, ');
|
|
||||||
}
|
|
||||||
print('$prefix: ${s.toString()}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() async {
|
|
||||||
if (_isAlive) {
|
|
||||||
_isAlive = false;
|
|
||||||
_heartbeatChecker?.responsed();
|
|
||||||
try {
|
|
||||||
await _socket.close();
|
|
||||||
_socket.destroy();
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ResponseChecker<T> {
|
|
||||||
final T _responser;
|
|
||||||
late int _time;
|
|
||||||
late Timer? _timer = null;
|
|
||||||
late void Function(T) _notResponseListener;
|
|
||||||
T get responser => _responser;
|
|
||||||
ResponseChecker(this._responser, this._time, this._notResponseListener) {
|
|
||||||
startTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
ResponseChecker.second(this._responser, int time, this._notResponseListener) {
|
|
||||||
this._time = time * 1000;
|
|
||||||
startTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void startTimer() {
|
|
||||||
_timer = Timer(Duration(milliseconds: _time), () {
|
|
||||||
_notResponseListener(_responser);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
T responsed() {
|
|
||||||
_timer?.cancel();
|
|
||||||
_timer = null;
|
|
||||||
return _responser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
// ignore_for_file: avoid_print, prefer_final_fields
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
import 'package:dart_framework/socket/packets/message_common.pb.dart';
|
|
||||||
import 'package:dart_framework/socket/protobuf_client.dart';
|
|
||||||
import 'package:dart_framework/utils/system_util.dart';
|
|
||||||
import 'package:protobuf/protobuf.dart';
|
|
||||||
|
|
||||||
abstract class ProtobufServer
|
|
||||||
{
|
|
||||||
List<ProtobufClient> _clientList = [];
|
|
||||||
bool _started = false;
|
|
||||||
late ServerSocket? _server;
|
|
||||||
final String _host;
|
|
||||||
final int _port;
|
|
||||||
final ProtobufClient Function(Socket) _createNewClient;
|
|
||||||
|
|
||||||
bool get started => _started;
|
|
||||||
|
|
||||||
ProtobufServer(this._host, this._port, this._createNewClient);
|
|
||||||
|
|
||||||
Future start() async
|
|
||||||
{
|
|
||||||
_server = await ServerSocket.bind(_host, _port);
|
|
||||||
_server?.listen((Socket socket) {
|
|
||||||
var client = _createNewClient(socket);
|
|
||||||
client.addDisconnectListener(onDisconnectedClient);
|
|
||||||
client.addListener(onTemplateData);
|
|
||||||
_clientList.add(client);
|
|
||||||
onClientConnected(client);
|
|
||||||
_started = true;
|
|
||||||
});
|
|
||||||
return simpleFuture;
|
|
||||||
}
|
|
||||||
|
|
||||||
//implement in child
|
|
||||||
void onClientConnected(ProtobufClient client);
|
|
||||||
|
|
||||||
void onDisconnectedClient(ProtobufClient client)
|
|
||||||
{
|
|
||||||
_clientList.remove(client);
|
|
||||||
client.dispose();
|
|
||||||
print('Client disconnected');
|
|
||||||
}
|
|
||||||
|
|
||||||
void onTemplateData(TestData data)
|
|
||||||
{
|
|
||||||
print(data.message);
|
|
||||||
var template = TestData();
|
|
||||||
template.index = 3125;
|
|
||||||
template.message = 'This message from flutter';
|
|
||||||
_clientList[0].send(template);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future broadcast<T extends GeneratedMessage>(T data) async {
|
|
||||||
for(var client in _clientList) {
|
|
||||||
await client.send(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future stop() async {
|
|
||||||
await _server?.close();
|
|
||||||
_started = false;
|
|
||||||
return simpleFuture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import 'package:web_socket_channel/html.dart';
|
|
||||||
|
|
||||||
class WebSocketConnector {
|
|
||||||
late HtmlWebSocketChannel _socket;
|
|
||||||
|
|
||||||
Future connect() async {
|
|
||||||
_socket =
|
|
||||||
HtmlWebSocketChannel.connect('ws://127.0.0.1:9090/ws/view/');
|
|
||||||
_socket.stream.listen((message) async {
|
|
||||||
print('Received message from server');
|
|
||||||
print(message);
|
|
||||||
_socket.sink.add('this is from flutter');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -16,9 +16,7 @@ dependencies:
|
||||||
yaml: ^3.1.3
|
yaml: ^3.1.3
|
||||||
http: ^1.2.1
|
http: ^1.2.1
|
||||||
color: ^3.0.0
|
color: ^3.0.0
|
||||||
protobuf: ^3.1.0
|
|
||||||
encrypt: ^5.0.3
|
encrypt: ^5.0.3
|
||||||
web_socket_channel: ^3.0.2
|
|
||||||
# subtitle_wrapper_package: ^2.1.1
|
# subtitle_wrapper_package: ^2.1.1
|
||||||
# equatable: ^2.0.5
|
# equatable: ^2.0.5
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue