하트비트 추가

This commit is contained in:
build@lguplus.co.kr 2023-12-16 00:30:06 +09:00
parent d2f5f854ee
commit a0d8e93d6c
6 changed files with 88 additions and 67 deletions

View file

@ -24,14 +24,14 @@ public static partial class MessageCommonReflection {
string.Concat( string.Concat(
"ChRtZXNzYWdlX2NvbW1vbi5wcm90byI7CgpQYWNrZXRCYXNlEhAKCHR5cGVO", "ChRtZXNzYWdlX2NvbW1vbi5wcm90byI7CgpQYWNrZXRCYXNlEhAKCHR5cGVO",
"YW1lGAEgASgJEg0KBW5vbmNlGAIgASgFEgwKBGRhdGEYAyABKAwiCwoJSGVh", "YW1lGAEgASgJEg0KBW5vbmNlGAIgASgFEgwKBGRhdGEYAyABKAwiCwoJSGVh",
"cnRCZWF0Ii4KDFRlbXBsYXRlRGF0YRINCgVpbmRleBgBIAEoBRIPCgdtZXNz", "cnRCZWF0IioKCFRlc3REYXRhEg0KBWluZGV4GAEgASgFEg8KB21lc3NhZ2UY",
"YWdlGAIgASgJYgZwcm90bzM=")); "AiABKAliBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { }, new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::PacketBase), global::PacketBase.Parser, new[]{ "TypeName", "Nonce", "Data" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::PacketBase), global::PacketBase.Parser, new[]{ "TypeName", "Nonce", "Data" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::HeartBeat), global::HeartBeat.Parser, null, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::HeartBeat), global::HeartBeat.Parser, null, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::TemplateData), global::TemplateData.Parser, new[]{ "Index", "Message" }, null, null, null, null) new pbr::GeneratedClrTypeInfo(typeof(global::TestData), global::TestData.Parser, new[]{ "Index", "Message" }, null, null, null, null)
})); }));
} }
#endregion #endregion
@ -324,11 +324,11 @@ public sealed partial class HeartBeat : pb::IMessage<HeartBeat> {
} }
public sealed partial class TemplateData : pb::IMessage<TemplateData> { public sealed partial class TestData : pb::IMessage<TestData> {
private static readonly pb::MessageParser<TemplateData> _parser = new pb::MessageParser<TemplateData>(() => new TemplateData()); private static readonly pb::MessageParser<TestData> _parser = new pb::MessageParser<TestData>(() => new TestData());
private pb::UnknownFieldSet _unknownFields; private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TemplateData> Parser { get { return _parser; } } public static pb::MessageParser<TestData> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor { public static pbr::MessageDescriptor Descriptor {
@ -341,22 +341,22 @@ public sealed partial class TemplateData : pb::IMessage<TemplateData> {
} }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TemplateData() { public TestData() {
OnConstruction(); OnConstruction();
} }
partial void OnConstruction(); partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TemplateData(TemplateData other) : this() { public TestData(TestData other) : this() {
index_ = other.index_; index_ = other.index_;
message_ = other.message_; message_ = other.message_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
} }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TemplateData Clone() { public TestData Clone() {
return new TemplateData(this); return new TestData(this);
} }
/// <summary>Field number for the "index" field.</summary> /// <summary>Field number for the "index" field.</summary>
@ -383,11 +383,11 @@ public sealed partial class TemplateData : pb::IMessage<TemplateData> {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) { public override bool Equals(object other) {
return Equals(other as TemplateData); return Equals(other as TestData);
} }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TemplateData other) { public bool Equals(TestData other) {
if (ReferenceEquals(other, null)) { if (ReferenceEquals(other, null)) {
return false; return false;
} }
@ -446,7 +446,7 @@ public sealed partial class TemplateData : pb::IMessage<TemplateData> {
} }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TemplateData other) { public void MergeFrom(TestData other) {
if (other == null) { if (other == null) {
return; return;
} }

View file

@ -8,7 +8,7 @@ message PacketBase {
message HeartBeat {} message HeartBeat {}
message TemplateData { message TestData {
int32 index = 1; int32 index = 1;
string message = 2; string message = 2;
} }

View file

@ -123,8 +123,8 @@ class HeartBeat extends $pb.GeneratedMessage {
static HeartBeat? _defaultInstance; static HeartBeat? _defaultInstance;
} }
class TemplateData extends $pb.GeneratedMessage { class TestData extends $pb.GeneratedMessage {
factory TemplateData({ factory TestData({
$core.int? index, $core.int? index,
$core.String? message, $core.String? message,
}) { }) {
@ -137,11 +137,11 @@ class TemplateData extends $pb.GeneratedMessage {
} }
return $result; return $result;
} }
TemplateData._() : super(); TestData._() : super();
factory TemplateData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); factory TestData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory TemplateData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(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 ? '' : 'TemplateData', createEmptyInstance: create) static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'TestData', createEmptyInstance: create)
..a<$core.int>(1, _omitFieldNames ? '' : 'index', $pb.PbFieldType.O3) ..a<$core.int>(1, _omitFieldNames ? '' : 'index', $pb.PbFieldType.O3)
..aOS(2, _omitFieldNames ? '' : 'message') ..aOS(2, _omitFieldNames ? '' : 'message')
..hasRequiredFields = false ..hasRequiredFields = false
@ -151,22 +151,22 @@ class TemplateData extends $pb.GeneratedMessage {
'Using this can add significant overhead to your binary. ' 'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version') 'Will be removed in next major version')
TemplateData clone() => TemplateData()..mergeFromMessage(this); TestData clone() => TestData()..mergeFromMessage(this);
@$core.Deprecated( @$core.Deprecated(
'Using this can add significant overhead to your binary. ' 'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version') 'Will be removed in next major version')
TemplateData copyWith(void Function(TemplateData) updates) => super.copyWith((message) => updates(message as TemplateData)) as TemplateData; TestData copyWith(void Function(TestData) updates) => super.copyWith((message) => updates(message as TestData)) as TestData;
$pb.BuilderInfo get info_ => _i; $pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline') @$core.pragma('dart2js:noInline')
static TemplateData create() => TemplateData._(); static TestData create() => TestData._();
TemplateData createEmptyInstance() => create(); TestData createEmptyInstance() => create();
static $pb.PbList<TemplateData> createRepeated() => $pb.PbList<TemplateData>(); static $pb.PbList<TestData> createRepeated() => $pb.PbList<TestData>();
@$core.pragma('dart2js:noInline') @$core.pragma('dart2js:noInline')
static TemplateData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TemplateData>(create); static TestData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TestData>(create);
static TemplateData? _defaultInstance; static TestData? _defaultInstance;
@$pb.TagNumber(1) @$pb.TagNumber(1)
$core.int get index => $_getIZ(0); $core.int get index => $_getIZ(0);

View file

@ -37,17 +37,17 @@ const HeartBeat$json = {
final $typed_data.Uint8List heartBeatDescriptor = $convert.base64Decode( final $typed_data.Uint8List heartBeatDescriptor = $convert.base64Decode(
'CglIZWFydEJlYXQ='); 'CglIZWFydEJlYXQ=');
@$core.Deprecated('Use templateDataDescriptor instead') @$core.Deprecated('Use testDataDescriptor instead')
const TemplateData$json = { const TestData$json = {
'1': 'TemplateData', '1': 'TestData',
'2': [ '2': [
{'1': 'index', '3': 1, '4': 1, '5': 5, '10': 'index'}, {'1': 'index', '3': 1, '4': 1, '5': 5, '10': 'index'},
{'1': 'message', '3': 2, '4': 1, '5': 9, '10': 'message'}, {'1': 'message', '3': 2, '4': 1, '5': 9, '10': 'message'},
], ],
}; };
/// Descriptor for `TemplateData`. Decode as a `google.protobuf.DescriptorProto`. /// Descriptor for `TestData`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List templateDataDescriptor = $convert.base64Decode( final $typed_data.Uint8List testDataDescriptor = $convert.base64Decode(
'CgxUZW1wbGF0ZURhdGESFAoFaW5kZXgYASABKAVSBWluZGV4EhgKB21lc3NhZ2UYAiABKAlSB2' 'CghUZXN0RGF0YRIUCgVpbmRleBgBIAEoBVIFaW5kZXgSGAoHbWVzc2FnZRgCIAEoCVIHbWVzc2'
'1lc3NhZ2U='); 'FnZQ==');

View file

@ -13,77 +13,75 @@ import 'package:dart_framework/socket/packets/message_common.pb.dart';
abstract class ProtobufClient extends Communicator abstract class ProtobufClient extends Communicator
{ {
final int _headerSize = 4; final int _headerSize = 4;
final int _heartbeatBuffer = 10; final int _heartbeatIntervalTime;
final int _heartbeatTime; final int _heartbeatWaitTime;
final Socket _socket; final Socket _socket;
late Timer? _heartbeatTimer = null; late ResponseChecker? _heartbeatChecker;
int? _length = null; int? _length = null;
bool _isAlive = false; bool _isAlive = false;
late List<int> _arrivedData = []; late List<int> _arrivedData = [];
List<void Function(ProtobufClient)> _onDisconnectListenerList = []; List<void Function(ProtobufClient)> _onDisconnectListenerList = [];
ProtobufClient(this._socket, this._heartbeatTime, Map<String, GeneratedMessage Function(List<int>)> parserMap) ProtobufClient(this._socket, this._heartbeatIntervalTime, this._heartbeatWaitTime, Map<String, GeneratedMessage Function(List<int>)> parserMap) {
{
print('Connected New Client'); print('Connected New Client');
_isAlive = true; _isAlive = true;
parserMap.addAll({ parserMap.addAll({
(TemplateData).toString() : TemplateData.fromBuffer, (TestData).toString() : TestData.fromBuffer,
(HeartBeat).toString() : HeartBeat.fromBuffer (HeartBeat).toString() : HeartBeat.fromBuffer
}); });
super.initialize(parserMap); super.initialize(parserMap);
addListener(onHeartBeat); addListener(onHeartBeat);
_socket.listen(onData, onError: onError) _socket.listen(onData, onError: onError)
.asFuture().then(onDisconnected); .asFuture().then(onDisconnected);
// waitHeartbeat(); sendHeartBeat();
} }
void waitHeartbeat() void sendHeartBeat() {
{ _heartbeatChecker?.responsed();
_heartbeatTimer = Timer(Duration(seconds: _heartbeatTime + _heartbeatBuffer), () { _heartbeatChecker = ResponseChecker.seecond(this, _heartbeatIntervalTime, (client) {
send(HeartBeat());
_heartbeatChecker = ResponseChecker.seecond(this, _heartbeatWaitTime, (client) {
dispose(); dispose();
onDisconnected(null);
});
}); });
} }
void onHeartBeat(HeartBeat data) void onHeartBeat(HeartBeat data) {
{ sendHeartBeat();
_heartbeatTimer?.cancel();
waitHeartbeat();
} }
void addDisconnectListener(void Function(ProtobufClient) handler) void addDisconnectListener(void Function(ProtobufClient) handler) {
{
if(!_onDisconnectListenerList.contains(handler)) if(!_onDisconnectListenerList.contains(handler))
{ {
_onDisconnectListenerList.add(handler); _onDisconnectListenerList.add(handler);
} }
} }
void removeDisconnectListener(void Function(ProtobufClient) handler) void removeDisconnectListener(void Function(ProtobufClient) handler) {
{
if(_onDisconnectListenerList.contains(handler)) if(_onDisconnectListenerList.contains(handler))
{ {
_onDisconnectListenerList.remove(handler); _onDisconnectListenerList.remove(handler);
} }
} }
void onDisconnected(dynamic data) void onDisconnected(dynamic data) {
{
//client disconnected //client disconnected
for (var item in _onDisconnectListenerList) { for (var item in _onDisconnectListenerList) {
item.call(this); item.call(this);
} }
_onDisconnectListenerList.clear();
} }
void onError(dynamic e) void onError(dynamic e) {
{
print('=========> onError: $e'); print('=========> onError: $e');
} }
void onData(Uint8List data) async void onData(Uint8List data) async {
{
try try
{ {
sendHeartBeat();
// printPacket('## Received', data); // printPacket('## Received', data);
if(_length == null) if(_length == null)
{ {
@ -130,8 +128,7 @@ abstract class ProtobufClient extends Communicator
return simpleFuture; return simpleFuture;
} }
void printPacket(String prefix, List<int> packet) void printPacket(String prefix, List<int> packet) {
{
var s = StringBuffer(); var s = StringBuffer();
for(var item in packet) for(var item in packet)
{ {
@ -140,9 +137,32 @@ abstract class ProtobufClient extends Communicator
print('$prefix: ${s.toString()}'); print('$prefix: ${s.toString()}');
} }
void dispose() void dispose() async {
if(_isAlive)
{ {
_isAlive = false; _isAlive = false;
_socket.close(); _heartbeatChecker?.responsed();
await _socket.close();
_socket.destroy();
}
}
}
class ResponseChecker<T> {
final T _responser;
late Timer _timer;
ResponseChecker(this._responser, int time, void Function(T) notResponseListener) {
_timer = Timer(Duration(milliseconds: time), () {
notResponseListener(_responser);
});
}
ResponseChecker.seecond(this._responser, int time, void Function(T) notResponseListener) {
ResponseChecker(this._responser, time * 1000, notResponseListener);
}
T responsed() {
_timer.cancel();
return _responser;
} }
} }

View file

@ -34,15 +34,16 @@ abstract class ProtobufServer
void onDisconnectedClient(ProtobufClient client) void onDisconnectedClient(ProtobufClient client)
{ {
client.removeDisconnectListener(onDisconnectedClient);
_clientList.remove(client); _clientList.remove(client);
client.dispose(); client.dispose();
print('Client disconnected'); print('Client disconnected');
} }
void onTemplateData(TemplateData data) void onTemplateData(TestData data)
{ {
print(data.message); print(data.message);
var template = TemplateData(); var template = TestData();
template.index = 3125; template.index = 3125;
template.message = 'This message from flutter'; template.message = 'This message from flutter';
_clientList[0].send(template); _clientList[0].send(template);