feat: protobuf input messaging (#165)

Replace json protocol by protobuf
generate protobuf files with `bun buf generate` or just `buf generate`

- [x]  Implement all datatypes with proto files

- [x] Map to ts types or use the generated proto types directly with:
   - [x] web frontend
   - [x] relay
   - [x] runner

- [ ] final performance test (to be done when CI builds new images)

---------

Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com>
This commit is contained in:
Philipp Neumann
2025-01-28 15:04:20 +01:00
committed by GitHub
parent 431733a0e8
commit fbaa8835a3
38 changed files with 2758 additions and 647 deletions

View File

@@ -1,6 +1,7 @@
package relay
import (
"encoding/json"
"github.com/gorilla/websocket"
"log"
"sync"
@@ -10,22 +11,22 @@ import (
type SafeWebSocket struct {
*websocket.Conn
sync.Mutex
closeCallback func() // OnClose callback
binaryCallbacks map[string]OnMessageCallback // MessageBase type -> callback
closeCallback func() // OnClose callback
callbacks map[string]OnMessageCallback // MessageBase type -> callback
}
// NewSafeWebSocket creates a new SafeWebSocket from *websocket.Conn
func NewSafeWebSocket(conn *websocket.Conn) *SafeWebSocket {
ws := &SafeWebSocket{
Conn: conn,
closeCallback: nil,
binaryCallbacks: make(map[string]OnMessageCallback),
Conn: conn,
closeCallback: nil,
callbacks: make(map[string]OnMessageCallback),
}
// Launch a goroutine to handle binary messages
// Launch a goroutine to handle messages
go func() {
for {
// Read binary message
// Read message
kind, data, err := ws.Conn.ReadMessage()
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure, websocket.CloseNoStatusReceived) {
// If unexpected close error, break
@@ -42,22 +43,23 @@ func NewSafeWebSocket(conn *websocket.Conn) *SafeWebSocket {
switch kind {
case websocket.TextMessage:
// Ignore, we use binary messages
continue
case websocket.BinaryMessage:
// Decode message
var msg MessageBase
if err = DecodeMessage(data, &msg); err != nil {
log.Printf("Failed to decode binary WebSocket message, reason: %s\n", err)
if err = json.Unmarshal(data, &msg); err != nil {
log.Printf("Failed to decode text WebSocket message, reason: %s\n", err)
continue
}
// Handle message type callback
if callback, ok := ws.binaryCallbacks[msg.PayloadType]; ok {
if callback, ok := ws.callbacks[msg.PayloadType]; ok {
callback(data)
} // TODO: Log unknown message type?
break
case websocket.BinaryMessage:
break
default:
log.Printf("Unknown WebSocket message type: %d\n", kind)
break
}
}
@@ -88,18 +90,18 @@ func (ws *SafeWebSocket) SendBinary(data []byte) error {
func (ws *SafeWebSocket) RegisterMessageCallback(msgType string, callback OnMessageCallback) {
ws.Lock()
defer ws.Unlock()
if ws.binaryCallbacks == nil {
ws.binaryCallbacks = make(map[string]OnMessageCallback)
if ws.callbacks == nil {
ws.callbacks = make(map[string]OnMessageCallback)
}
ws.binaryCallbacks[msgType] = callback
ws.callbacks[msgType] = callback
}
// UnregisterMessageCallback removes the callback for binary message of given type
func (ws *SafeWebSocket) UnregisterMessageCallback(msgType string) {
ws.Lock()
defer ws.Unlock()
if ws.binaryCallbacks != nil {
delete(ws.binaryCallbacks, msgType)
if ws.callbacks != nil {
delete(ws.callbacks, msgType)
}
}
@@ -108,7 +110,7 @@ func (ws *SafeWebSocket) RegisterOnClose(callback func()) {
ws.closeCallback = func() {
// Clear our callbacks
ws.Lock()
ws.binaryCallbacks = nil
ws.callbacks = nil
ws.Unlock()
// Call the callback
callback()