KProto протокол мессенджера DCC

KProto — это бинарный протокол прикладного уровня на базе Protocol Buffers (proto3), предназначенный для обмена сообщениями в реальном времени внутри экосистемы DCC.

Ключевые принципы

Система идентификаторов

Протокол оперирует тремя уровнями адресации:

Transport (WebSocket / TCP) Also transport level encryption make possibility inside protocol to handle E2EE
        ↓
KProto (version, ids, kind)
        ↓
Protocol Layer:
    - Auth
    - Presence
    - Contacts
    - Conversations
    - Messaging
        ↓
Extensions:
    - Voice (UDP/WebRTC) KProto as signaling layer
    - Files (Second socket) Chunking and retrying
    - Streams (UDP/WebRTC) KProto as signaling layer
    - etc.

Структура файлов протокола

main.kproto

syntax = "proto3";
package kproto;

message KProtoPacket {
  // Заголовок контекста
  fixed64 user_id = 1;
  fixed64 device_id = 2;
  fixed64 session_id = 3;

  // Безопасный контейнер
  oneof payload {
    NoiseHandshake handshake = 4; // Этап обмена ключами
    NoiseTransport transport = 5; // Зашифрованные данные (message.proto)
  }
}

message NoiseHandshake {
  bytes handshake_message = 1; // e, s, ee, se компоненты
  uint32 version = 2;          // Версия протокола
}

message NoiseTransport {
  bytes encrypted_data = 1;    // Зашифрованный Protobuf-пакет + MAC
  fixed64 sequence_number = 2; // Порядковый номер (для защиты от повторов)
}

auth.proto

// action: auth.hello
// kind: REQUEST
message Hello {
  string device_id = 1;         // UUID (генерится и хранится)
  string client_version = 2;

  repeated string capabilities = 3;
}

message HelloAck {
  string server_version = 1;
  repeated string capabilities = 2;

  string connection_id = 3; // опционально
}

// только при условии что нет oidc
// action: auth.login
// kind: REQUEST
message Login {
  string login = 1;     // username/email
  string password = 2;  // позже → hash/token
}

// на oidc это скипается и переход сразу к установке сессии
message LoginSuccess {
  string user_id = 1;

  string access_token = 2;
  string refresh_token = 3;

  int64 expires_at = 4;
}

message SessionStart {
  string access_token = 1;
  string device_id = 2;
}

message SessionStarted {
  string session_id = 1;
  string user_id = 2;

  int64 server_time = 3;
}


//Восстановление сессии
message SessionResume {
  string session_id = 1;
  string access_token = 2;
}

message SessionResumed {
  string session_id = 1;
}

// При невалид сессии закрытие соедиение с отправленным пустым KProto пакетом
// action: auth.session.invalid

message Refresh {
  string refresh_token = 1;
}

message RefreshSuccess {
  string access_token = 1;
  int64 expires_at = 2;
}

KPR-1 Conversations + Messaging

SendMessage (REQUEST)
    ↓
SendMessageAck (RESPONSE)
    ↓
MessageEvent (EVENT всем участникам)
    ↓
ACK (опционально)

message.proto

message Message {
  string message_id = 1;

  string conversation_id = 2;
  string sender_id = 3;

  int64 timestamp = 4;

  MessageContent content = 5;

  MessageMeta meta = 6;
  
  uint64 seq = 7;
}

message MessageContent {
  oneof type {
    TextContent text = 1;
    FileContent file = 2;
    SystemContent system = 3;

    // future
    bytes encrypted = 10;
  }
}

message TextContent {
  string text = 1;
}

message FileContent {
  string file_id = 1;
  string filename = 2;
}

message SystemContent {
  string type = 1; // "user_joined", "title_changed"
  map<string, string> data = 2;
}

message MessageMeta {
  string client_msg_id = 1;

  bool edited = 2;
  bool deleted = 3;

  string reply_to = 4;
}

// action: chat.send
// kind: REQUEST
message SendMessage {
  string conversation_id = 1;
  MessageContent content = 2;

  string client_msg_id = 3;
}

// kind: RESPONSE
message SendMessageAck {
  string message_id = 1;
  string client_msg_id = 2;
  int64 timestamp = 3;
}

// action: chat.message
// kind: EVENT
message MessageEvent {
  Message message = 1;
}


// kind: ACK
// correlation_id: message_id

// action: chat.read
message MessageRead {
  string conversation_id = 1;
  string message_id = 2;
}


message GetHistory {
  string conversation_id = 1;

  int32 limit = 2;
  string before_message_id = 3;
}

message History {
  repeated Message messages = 1;
}