add protobuf socket

This commit is contained in:
build@lguplus.co.kr 2023-11-25 02:04:16 +09:00
parent 427a6255f5
commit 6d66dc938d
12 changed files with 888 additions and 0 deletions

View file

@ -0,0 +1,5 @@
::Protocol Buffer version 3.11.4
set CURRENT_PATH=%cd%
set UNITY_PACKET_PATH=%CURRENT_PATH%\..\csharp
protoc -I=%CURRENT_PATH%\..\protobuf --dart_out=%CURRENT_PATH%\..\..\lib\socket\packets %CURRENT_PATH%\..\protobuf\*.proto --plugin=protoc_plugin.exe
protoc -I=%CURRENT_PATH%\..\protobuf --csharp_out=%UNITY_PACKET_PATH% %CURRENT_PATH%\..\protobuf\*.proto

BIN
assets/bin/protoc.exe Normal file

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,385 @@
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: message_common.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
/// <summary>Holder for reflection information generated from message_common.proto</summary>
public static partial class MessageCommonReflection {
#region Descriptor
/// <summary>File descriptor for message_common.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
static MessageCommonReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChRtZXNzYWdlX2NvbW1vbi5wcm90byI7CgpQYWNrZXRCYXNlEhAKCHR5cGVO",
"YW1lGAEgASgJEg0KBW5vbmNlGAIgASgFEgwKBGRhdGEYAyABKAwiLgoMVGVt",
"cGxhdGVEYXRhEg0KBWluZGV4GAEgASgFEg8KB21lc3NhZ2UYAiABKAliBnBy",
"b3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
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::TemplateData), global::TemplateData.Parser, new[]{ "Index", "Message" }, null, null, null, null)
}));
}
#endregion
}
#region Messages
public sealed partial class PacketBase : pb::IMessage<PacketBase> {
private static readonly pb::MessageParser<PacketBase> _parser = new pb::MessageParser<PacketBase>(() => new PacketBase());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<PacketBase> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::MessageCommonReflection.Descriptor.MessageTypes[0]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PacketBase() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PacketBase(PacketBase other) : this() {
typeName_ = other.typeName_;
nonce_ = other.nonce_;
data_ = other.data_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PacketBase Clone() {
return new PacketBase(this);
}
/// <summary>Field number for the "typeName" field.</summary>
public const int TypeNameFieldNumber = 1;
private string typeName_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TypeName {
get { return typeName_; }
set {
typeName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "nonce" field.</summary>
public const int NonceFieldNumber = 2;
private int nonce_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Nonce {
get { return nonce_; }
set {
nonce_ = value;
}
}
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 3;
private pb::ByteString data_ = pb::ByteString.Empty;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString Data {
get { return data_; }
set {
data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as PacketBase);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(PacketBase other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (TypeName != other.TypeName) return false;
if (Nonce != other.Nonce) return false;
if (Data != other.Data) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (TypeName.Length != 0) hash ^= TypeName.GetHashCode();
if (Nonce != 0) hash ^= Nonce.GetHashCode();
if (Data.Length != 0) hash ^= Data.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (TypeName.Length != 0) {
output.WriteRawTag(10);
output.WriteString(TypeName);
}
if (Nonce != 0) {
output.WriteRawTag(16);
output.WriteInt32(Nonce);
}
if (Data.Length != 0) {
output.WriteRawTag(26);
output.WriteBytes(Data);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (TypeName.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(TypeName);
}
if (Nonce != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Nonce);
}
if (Data.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(PacketBase other) {
if (other == null) {
return;
}
if (other.TypeName.Length != 0) {
TypeName = other.TypeName;
}
if (other.Nonce != 0) {
Nonce = other.Nonce;
}
if (other.Data.Length != 0) {
Data = other.Data;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
TypeName = input.ReadString();
break;
}
case 16: {
Nonce = input.ReadInt32();
break;
}
case 26: {
Data = input.ReadBytes();
break;
}
}
}
}
}
public sealed partial class TemplateData : pb::IMessage<TemplateData> {
private static readonly pb::MessageParser<TemplateData> _parser = new pb::MessageParser<TemplateData>(() => new TemplateData());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TemplateData> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::MessageCommonReflection.Descriptor.MessageTypes[1]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TemplateData() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TemplateData(TemplateData other) : this() {
index_ = other.index_;
message_ = other.message_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TemplateData Clone() {
return new TemplateData(this);
}
/// <summary>Field number for the "index" field.</summary>
public const int IndexFieldNumber = 1;
private int index_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Index {
get { return index_; }
set {
index_ = value;
}
}
/// <summary>Field number for the "message" field.</summary>
public const int MessageFieldNumber = 2;
private string message_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Message {
get { return message_; }
set {
message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TemplateData);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TemplateData other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (Index != other.Index) return false;
if (Message != other.Message) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Index != 0) hash ^= Index.GetHashCode();
if (Message.Length != 0) hash ^= Message.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Index != 0) {
output.WriteRawTag(8);
output.WriteInt32(Index);
}
if (Message.Length != 0) {
output.WriteRawTag(18);
output.WriteString(Message);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Index != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Index);
}
if (Message.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TemplateData other) {
if (other == null) {
return;
}
if (other.Index != 0) {
Index = other.Index;
}
if (other.Message.Length != 0) {
Message = other.Message;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Index = input.ReadInt32();
break;
}
case 18: {
Message = input.ReadString();
break;
}
}
}
}
}
#endregion
#endregion Designer generated code

View file

@ -0,0 +1,12 @@
syntax = "proto3";
message PacketBase {
string typeName = 1;
int32 nonce = 2;
bytes data = 3;
}
message TemplateData {
int32 index = 1;
string message = 2;
}

89
lib/communicator.dart Normal file
View file

@ -0,0 +1,89 @@
// 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.');
}
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);
}
}

View file

@ -0,0 +1,160 @@
//
// 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 TemplateData extends $pb.GeneratedMessage {
factory TemplateData({
$core.int? index,
$core.String? message,
}) {
final $result = create();
if (index != null) {
$result.index = index;
}
if (message != null) {
$result.message = message;
}
return $result;
}
TemplateData._() : super();
factory TemplateData.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);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'TemplateData', 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')
TemplateData clone() => TemplateData()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
TemplateData copyWith(void Function(TemplateData) updates) => super.copyWith((message) => updates(message as TemplateData)) as TemplateData;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static TemplateData create() => TemplateData._();
TemplateData createEmptyInstance() => create();
static $pb.PbList<TemplateData> createRepeated() => $pb.PbList<TemplateData>();
@$core.pragma('dart2js:noInline')
static TemplateData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TemplateData>(create);
static TemplateData? _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');

View file

@ -0,0 +1,11 @@
//
// 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

View file

@ -0,0 +1,44 @@
//
// 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 templateDataDescriptor instead')
const TemplateData$json = {
'1': 'TemplateData',
'2': [
{'1': 'index', '3': 1, '4': 1, '5': 5, '10': 'index'},
{'1': 'message', '3': 2, '4': 1, '5': 9, '10': 'message'},
],
};
/// Descriptor for `TemplateData`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List templateDataDescriptor = $convert.base64Decode(
'CgxUZW1wbGF0ZURhdGESFAoFaW5kZXgYASABKAVSBWluZGV4EhgKB21lc3NhZ2UYAiABKAlSB2'
'1lc3NhZ2U=');

View file

@ -0,0 +1,14 @@
//
// 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';

View file

@ -0,0 +1,126 @@
// 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<int> _arrivedData = [];
List<void Function(ProtobufClient)> _onDisconnectListenerList = [];
ProtobufClient(this._socket)
{
print('Connected New Client');
super.initialize({
(TemplateData).toString() : TemplateData.fromBuffer
});
_socket.listen(onData, onError: onError)
.asFuture().then(onDisconnected);
}
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 extends GeneratedMessage>(T data) async {
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();
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()
{
_onDisconnectListenerList.clear();
_arrivedData.clear();
_socket.close();
}
}

View file

@ -0,0 +1,42 @@
// 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';
class ProtobufServer
{
late ServerSocket _server;
List<ProtobufClient> _clientList = [];
String _host;
int _port;
ProtobufServer(this._host, this._port);
Future start() async
{
_server = await ServerSocket.bind(_host, _port);
_server.listen((Socket socket) {
var client = ProtobufClient(socket);
client.addDisconnectListener(onDisconnectedClient);
client.addListener(onTestSocket);
_clientList.add(client);
});
}
void onDisconnectedClient(ProtobufClient client)
{
_clientList.remove(client);
client.dispose();
print('Client disconnected');
}
void onTestSocket(TemplateData data)
{
print(data.message);
var test = TemplateData();
test.index = 3125;
test.message = 'This message from flutter';
_clientList[0].send(test);
}
}