No description
Find a file
2026-06-04 15:50:06 +09:00
.claude sync: agent-ops from agentic-framework v1.1.55 2026-05-25 21:16:54 +09:00
.vscode Update launch.json 2026-04-05 20:55:10 +09:00
agent-ops test(perf): 성능 기준선 검증 표준을 추가한다 2026-06-03 21:59:51 +09:00
agent-roadmap update performance-hotspot-optimization roadmap and add task archive 2026-06-04 15:50:06 +09:00
agent-task/archive/2026 update performance-hotspot-optimization roadmap and add task archive 2026-06-04 15:50:06 +09:00
dart chore: update stress test scripts and archive slow_mix task files 2026-06-03 13:10:48 +09:00
examples/go-module-consumer 기능: 브라우저 WebSocket 진입점을 추가한다 2026-05-20 07:30:53 +09:00
go feat: high-performance-parallel-operations milestone - gateway real path and cleanup 2026-06-03 18:05:34 +09:00
kotlin feat: high-performance-parallel-operations milestone - gateway real path and cleanup 2026-06-03 18:05:34 +09:00
proto update: crosstest coverage and proto restructure changes 2026-04-25 07:00:53 +09:00
python chore: update stress test scripts and archive slow_mix task files 2026-06-03 13:10:48 +09:00
tools update: crosstest coverage and proto restructure changes 2026-04-25 07:00:53 +09:00
typescript feat: high-performance-parallel-operations milestone - gateway real path and cleanup 2026-06-03 18:05:34 +09:00
.aiexclude sync: agent-ops from agentic-framework v1.1.75 2026-05-27 13:49:56 +09:00
.clineignore sync: agent-ops from agentic-framework v1.1.75 2026-05-27 13:49:56 +09:00
.clinerules sync: agent-ops from agentic-framework v1.1.113 2026-05-30 21:34:43 +09:00
.codex Update protocol and add WebSocket protobuf client/server implementations 2026-04-05 20:44:37 +09:00
.cursorignore sync: agent-ops from agentic-framework v1.1.75 2026-05-27 13:49:56 +09:00
.cursorrules sync: agent-ops from agentic-framework v1.1.113 2026-05-30 21:34:43 +09:00
.geminiignore sync: agent-ops from agentic-framework v1.1.75 2026-05-27 13:49:56 +09:00
.gitignore chore: make roadmap current local 2026-06-03 20:14:16 +09:00
AGENTS.md sync: agent-ops from agentic-framework v1.1.113 2026-05-30 21:34:43 +09:00
CLAUDE.md sync: agent-ops from agentic-framework v1.1.113 2026-05-30 21:34:43 +09:00
GEMINI.md sync: agent-ops from agentic-framework v1.1.113 2026-05-30 21:34:43 +09:00
opencode.json sync: agent-ops from agentic-framework v1.1.75 2026-05-27 13:49:56 +09:00
PORTING_GUIDE.md archive: gateway contract task files and update tests across languages 2026-06-02 08:52:17 +09:00
PROTOCOL.md archive: gateway contract task files and update tests across languages 2026-06-02 08:52:17 +09:00
README.md feat: implement inbound queue ordering across all language implementations 2026-06-02 05:36:52 +09:00
VERSIONING.md update docs and roadmap 2026-05-30 21:30:24 +09:00

Proto Socket

Proto Socket은 여러 언어와 플랫폼 사이에서 양방향 통신을 하기 위한 바이너리 소켓 프로토콜 라이브러리다.

Protocol Buffers 직렬화, TCP 4바이트 빅엔디안 길이 프리픽스 프레이밍, WebSocket 바이너리 프레임, 타입 기반 메시지 라우팅, 요청-응답 상관관계, 내장 하트비트를 제공한다.


현재 상태

현재 프로토콜 0.1의 사용 가능 호환 구현은 Dart, Go, Kotlin, Python, TypeScript다.

이 프로젝트는 안정화와 유지보수 단계에 있다. 현재 릴리즈 표준은 이 저장소를 Git ref/tag 기준으로 소비하는 방식이며, package registry 배포는 현재 목표가 아니다. C#과 Swift는 계획된 대상이지만, 실제 수요가 생기기 전까지 구현을 미룬다.

프로토콜이나 구현을 바꿀 때는 아래 내부 로컬 검증 매트릭스를 안정성 gate로 사용한다. 현재 주 사용 방식은 Git 기반 소비이므로, CI/CD runner 연결은 기본 운영 모델이 아니며 이 프로젝트 규모와 배포 방식에서는 설계상 과하다. Coverage는 라인 수치가 아니라 프로토콜 계약의 모든 필수 시나리오가 매트릭스에 포함되어 PASS인지로 판단한다.

bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all

프로토콜 또는 공개 API 변경은 호환성 작업으로 다룬다. 관련 문서를 갱신하고, 필요한 경우 protobuf binding을 재생성하며, 전체 검증 매트릭스가 통과해야 한다.


설계 원칙

  • core transport layer는 얇고 안정적으로 유지한다.
  • 언어 간 통신에 필요한 최소 공통 기반만 제공한다.
  • framing, serialization, routing, request-response correlation, heartbeat를 표준화한다.
  • Protocol Buffers를 핵심 프로토콜 의존성으로 둔다. 다른 런타임 의존성은 native-first, 좁은 범위, 기능에 비례한 수준으로 유지한다.
  • 애플리케이션 의미를 프로토콜 core에 넣지 않는다.
  • auth, session, agent workflow, chat, game logic 같은 도메인 관심사는 상위 레이어 구현의 책임이다.
  • 수신 처리 계약(inbound queue 순서, receive coordinator, backpressure, close/drain/cancel 정책)은 PROTOCOL.mdReceive Ordering and Backpressure 섹션에 정의하고, 새 언어 구현 기준은 PORTING_GUIDE.md반드시 유지해야 하는 구조 표를 따른다.

프로토콜

전체 wire format 명세는 PROTOCOL.md를 본다.

[4-byte big-endian length] [PacketBase protobuf bytes]

WebSocket/WSS transport에서는 각 binary frame이 TCP length header 없이 PacketBase protobuf payload 하나를 담는다.

프로토콜 호환성은 언어별 package version과 분리해서 추적한다. 자세한 정책은 VERSIONING.md를 본다. 패키지를 아직 registry에 배포하지 않더라도, 저장소에 포함된 구현은 문서화된 프로토콜 계약을 지켜야 한다.


구현체

언어 상태 경로 사용처
Dart 사용 가능 dart/ Flutter, Dart server
Kotlin 사용 가능 kotlin/ Android, JVM
Go 사용 가능 go/ Server, tooling, scripting
TypeScript 사용 가능 typescript/ Browser, Node.js
Python 사용 가능 python/ Server, tooling, scripting
C# 계획 / 보류 csharp/ Unity, .NET
Swift 계획 / 보류 swift/ iOS, macOS

새 언어 구현은 PORTING_GUIDE.mdagent-ops/skills/project/add-proto-socket-crosstest-language/templates/의 템플릿에서 시작한다. 동일 언어 테스트와 크로스 언어 테스트가 통과한 뒤에만 구현 상태를 사용 가능으로 표시한다.

현재 구현 상태는 이 README를 공개 snapshot으로 본다. 현재 작업 맥락은 agent-roadmap/current.md에서 선택하고, 큰 로드맵 방향은 agent-roadmap/ROADMAP.md에 둔다.


주요 명령

목적 명령 비고
전체 로컬 검증 bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all proto sync, 동일 언어 테스트, 사용 가능 구현의 크로스 언어 검증을 실행한다.
Proto schema sync 확인 tools/check_proto_sync.sh 언어별 proto copy가 허용된 언어 옵션을 제외하고 proto/message_common.proto와 일치하는지 확인한다.
Protobuf binding 재생성 tools/generate_proto.sh canonical proto schema를 바꾼 뒤 실행한다.
Dart 테스트 cd dart && dart pub get && dart test && dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js Dart VM/IO 테스트와 web import compile 확인
Go 테스트 cd go && go test ./... Go 동일 언어 검증
Kotlin 테스트 cd kotlin && ./gradlew test Kotlin 동일 언어 검증
Python 테스트 cd python && python3 -m pytest -q Python 동일 언어 검증
TypeScript 확인 cd typescript && npm run check && npm test TypeScript type check와 테스트

저장소 구조

경로 역할
proto/ canonical protobuf schema 원본
dart/ Dart / Flutter 구현체와 테스트
go/ Go 구현체, 테스트, Go 주도 crosstest
kotlin/ Kotlin / JVM 구현체와 crosstest
python/ Python 구현체와 crosstest
typescript/ TypeScript 구현체와 crosstest
tools/ proto 생성과 sync helper
examples/ 소비자 지향 예제
agent-ops/ 프로젝트 규칙, 로드맵, 반복 agent workflow

빠른 시작: Dart

import 'package:proto_socket/proto_socket.dart';

// 1. message_common.proto에 메시지를 정의하고 protoc로 생성한다.

// 2. client를 구현한다.
class MyClient extends ProtobufClient {
  MyClient(Socket socket) : super(socket, 30, 10, {
    MyMessage.getDefault().info_.qualifiedMessageName: MyMessage.fromBuffer,
  });
}

// 3. server를 구현한다.
class MyServer extends ProtobufServer {
  MyServer() : super('0.0.0.0', 9090, (socket) => MyClient(socket));

  @override
  void onClientConnected(ProtobufClient client) {
    client.addListener<MyMessage>((msg) => print('Received: ${msg}'));
  }
}

// 4. server를 시작한다.
final server = MyServer();
await server.start();

// 5. 연결하고 메시지를 보낸다.
final socket = await Socket.connect('localhost', 9090);
final client = MyClient(socket);
await client.send(MyMessage()..text = 'hello');

메시지 타입 추가

canonical proto인 proto/message_common.proto를 수정한 뒤, 저장소에 포함된 모든 binding을 재생성한다.

tools/generate_proto.sh
tools/check_proto_sync.sh

Go와 Kotlin proto copy에는 option go_package, Java package/class option 같은 언어별 옵션만 추가로 허용한다. 메시지 schema가 proto/message_common.proto와 달라지면 tools/check_proto_sync.sh가 diff와 함께 실패한다.


빠른 시작: Go

package main

import (
	"context"
	"net"
	"time"

	"google.golang.org/protobuf/proto"

	protoSocket "git.toki-labs.com/toki/proto-socket/go"
	"git.toki-labs.com/toki/proto-socket/go/packets"
)

func parserMap() protoSocket.ParserMap {
	return protoSocket.ParserMap{
		protoSocket.TypeNameOf(&packets.TestData{}): func(b []byte) (proto.Message, error) {
			m := &packets.TestData{}
			return m, proto.Unmarshal(b, m)
		},
	}
}

func main() {
	ctx := context.Background()

	server := protoSocket.NewTcpServer("127.0.0.1", 9090, func(conn net.Conn) *protoSocket.TcpClient {
		return protoSocket.NewTcpClient(conn, 30, 10, parserMap())
	})
	server.OnClientConnected = func(client *protoSocket.TcpClient) {
		protoSocket.AddRequestListenerTyped[*packets.TestData, *packets.TestData](
			&client.Communicator,
			func(req *packets.TestData) (*packets.TestData, error) {
				return &packets.TestData{Index: req.GetIndex(), Message: "echo: " + req.GetMessage()}, nil
			},
		)
	}
	if err := server.Start(ctx); err != nil {
		panic(err)
	}
	defer server.Stop()

	client, err := protoSocket.DialTcp(ctx, "127.0.0.1", 9090, 30, 10, parserMap())
	if err != nil {
		panic(err)
	}
	defer client.Close()

	res, err := protoSocket.SendRequestTyped[*packets.TestData, *packets.TestData](
		&client.Communicator,
		&packets.TestData{Index: 1, Message: "hello"},
		2*time.Second,
	)
	if err != nil {
		panic(err)
	}
	println(res.GetMessage())
}

Go 구현체는 다음 표면도 제공한다.

  • TCP: NewTcpServer, DialTcp, NewTcpServerTLS, DialTcpTLS
  • WebSocket: NewWsServer, NewWsServerWithOptions, DialWs, NewWsServerTLS, NewWsServerTLSWithOptions, DialWss
  • Shared helpers: Send, SendRequest, AddListenerTyped, AddRequestListenerTyped, Broadcast

다른 저장소에서 이 모듈을 사용하는 복사 가능한 scaffold가 필요하면 examples/go-module-consumer/를 본다.


테스트 실행

개발과 문제 재현을 위한 로컬 명령은 이 문서에 정리한다. 반복 가능한 저장소 로컬 검증 진입점은 다음 명령이다.

bash agent-ops/skills/project/run-proto-socket-test-matrix/scripts/run_matrix.sh --all

이 명령은 proto schema sync, 동일 언어 테스트, 크로스 언어 검증을 실행하고, 실패가 있으면 재현 명령과 함께 PASS/FAIL 표를 출력한다. 더 작은 범위만 확인하려면 --proto, --unit, --cross를 사용한다.

외부 CI runner 연동은 이 저장소의 기본 운영 목표가 아니다. 현재 주 사용 방식은 Git 기반 소비와 내부 로컬 매트릭스 결과 확인이며, 이 범위에서는 별도 CI/CD runner 연결을 요구하지 않는다.

Proto schema sync:

tools/check_proto_sync.sh

동일 언어 검증:

cd dart
dart pub get
dart test
dart compile js test/browser_ws_import_compile.dart -o /tmp/proto_socket_browser_ws_import_compile.js
cd go
go test ./...
cd kotlin
./gradlew test
cd python
python3 -m pytest -q
cd typescript
npm run check
npm test

크로스 언어 검증:

cd go
go run ./crosstest/go_dart.go
go run ./crosstest/go_kotlin.go
go run ./crosstest/go_python.go
go run ./crosstest/go_typescript.go
cd dart
dart run crosstest/dart_go.dart
dart run crosstest/dart_kotlin.dart
dart run crosstest/dart_python.dart
dart run crosstest/dart_typescript.dart
cd kotlin
./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinDartKt
./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinGoKt
./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinPythonKt
./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinTypescriptKt
cd python
python3 crosstest/python_dart.py
python3 crosstest/python_go.py
python3 crosstest/python_kotlin.py
python3 crosstest/python_typescript.py
cd typescript
./node_modules/.bin/tsx crosstest/typescript_dart.ts
./node_modules/.bin/tsx crosstest/typescript_go.ts
./node_modules/.bin/tsx crosstest/typescript_kotlin.ts
./node_modules/.bin/tsx crosstest/typescript_python.ts

Dart.io와 Dart.web E2E 매트릭스

위 표의 Dart 열은 Dart VM/IO client를 뜻한다. Dart.web은 별도 축이다. 브라우저 WS/WSS client만 가능하며, 브라우저에서는 TCP와 server 역할이 불가능하므로 해당 cell은 N/A다. Dart.web WSS는 테스트용 self-signed certificate의 SPKI를 허용하는 Chrome 실행 wrapper로 local/remote 브라우저 검증에 포함한다.

Server Dart.io TCP Dart.io WS Dart.io TLS TCP Dart.io WSS Dart.web WS Dart.web WSS Dart.web TCP
Dart.io Covered Covered Covered Covered Covered Covered N/A
Go Covered Covered Covered Covered Covered Covered N/A
Kotlin Covered Covered Covered Covered Covered Covered N/A
Python Covered Covered Covered Covered Covered Covered N/A
TypeScript Covered Covered Covered Covered Covered Covered N/A

각 Dart.web cell은 server-language runner가 WS와 WSS server를 함께 띄우고, matching browser test file에 대해 dart test -p chrome을 실행하며, WS send-push/request-response와 WSS send-push/request-response 4개 시나리오를 검증한다.

cd dart && dart run crosstest/dart_web.dart
cd go && go run ./crosstest/go_dart_web.go
cd kotlin && ./gradlew run -PmainClass=com.tokilabs.proto_socket.crosstest.KotlinDartWebKt
cd python && python3 crosstest/python_dart_web.py
cd typescript && ./node_modules/.bin/tsx crosstest/typescript_dart_web.ts

작업 맥락

코드나 프로토콜을 변경하기 전에 agent-ops/rules/project/rules.md의 프로젝트 규칙과 해당 경로의 domain rule을 확인한다. 활성 로드맵 창은 agent-roadmap/current.md에 있다.

안정화 경계는 다음과 같다.

  • 명시적인 호환성 작업 요청이 없으면 프로토콜 0.1 동작을 안정적으로 유지한다.
  • 유지보수 모드 작업에는 bug fix, 문서 정정, 테스트 강화, 호환성을 유지하는 구현 수정이 포함될 수 있다.
  • C#/Swift, package registry release, protocol/API 변경 작업은 구체적인 소비자 수요, 호환성 계획, 전체 검증 매트릭스 통과 조건이 있을 때 별도 작업으로 재개한다. 현재 릴리즈 표준은 Git ref/tag 기준이다.
  • 상위 ../oto workflow가 결정되기 전까지 이 저장소에서 외부 CI/CD runner를 직접 연결하지 않는다.