Salta ai contenuti

Connettore gRPC

Il connettore gRPC permette a Meddle di invocare servizi gRPC sia come reader client (polling con chiamate unary) sia come writer (inoltrando payload come richieste gRPC). Utilizza HTTP/2 alla base e supporta TLS opzionale, rendendolo adatto all’integrazione con microservizi moderni, edge gateway e API industriali che espongono endpoint gRPC.

Tipi Connettore:

  • GrpcReader - Invoca periodicamente un metodo gRPC unary ed emette la risposta come payload Meddle
  • GrpcWriter - Invia ogni payload in ingresso come richiesta gRPC al servizio di destinazione
  • ✅ Trasporto HTTP/2 con crittografia TLS opzionale
  • ✅ Reader unary basato su polling con frequenza configurabile
  • ✅ Il writer inoltra i payload come richieste gRPC codificate in JSON
  • ✅ Corpo di richiesta statico per il polling in lettura
  • ✅ Flag di configurazione streaming-aware
  • ✅ Gestione e riutilizzo automatici della connessione
  • ✅ Timeout di sicurezza di 10 secondi per chiamata
{
"type": "GrpcReader",
"config": {
"address": "192.168.1.50:50051",
"service": "iot.SensorService",
"method": "GetReading",
"pollingRate": 1000,
"requestBody": "{\"sensorId\":\"sensor-1\"}"
}
}
{
"type": "GrpcWriter",
"config": {
"address": "192.168.1.50:50051",
"service": "iot.SensorService",
"method": "PushReading",
"tls": false
}
}

L’host e la porta del server gRPC.

{
"address": "192.168.1.50:50051"
}

Formato: host:port (senza prefisso di schema). Per endpoint TLS, imposta tls: true invece di codificarlo nell’indirizzo.

Il nome qualificato completo del servizio gRPC come definito nel tuo file .proto, incluso il prefisso del pacchetto.

{
"service": "iot.SensorService"
}

Formato: package.ServiceName. Internamente, il connettore compone il percorso completo del metodo come /{service}/{method}.

Il nome del metodo del servizio da invocare.

{
"method": "GetReading"
}

Deve corrispondere esattamente al nome del metodo dichiarato nella definizione proto (case-sensitive).

Abilita TLS per la connessione. Quando disabilitato, il connettore utilizza credenziali non sicure (plaintext).

{
"tls": true
}

Valori raccomandati:

  • false - Ambienti interni di rete fidata (LAN/PLC)
  • true - Endpoint pubblici, servizi cloud, qualsiasi cosa attraversi reti non fidate

Corpo JSON statico inviato come payload di richiesta su ogni polling.

{
"requestBody": "{\"sensorId\":\"sensor-1\",\"includeHistory\":false}"
}

Note:

  • Deve essere una stringa JSON valida. Esegui l’escape delle virgolette interne come mostrato
  • Se omesso, viene inviato un oggetto JSON vuoto {}
  • Il corpo della richiesta è trattato come json.RawMessage e inoltrato così com’è su ogni polling

Intervallo in millisecondi tra chiamate gRPC successive (solo reader).

{
"pollingRate": 1000
}

Valori raccomandati:

  • Veloce: 100-500ms
  • Normale: 1000ms (1 secondo)
  • Lento: 5000ms+ (5 secondi o più)

Flag per indicare che il metodo di destinazione usa semantica server-streaming.

{
"streaming": true
}

Quando impostato, il connettore emette comunque chiamate alla cadenza di polling ma marca la configurazione come streaming-aware affinché gli strumenti a valle possano adattare le aspettative. Usalo per metodi che restituiscono payload progressivamente più grandi o che mantengono un ciclo di vita della connessione più lungo.

Server gRPC → GrpcReader (invocazione unary) → risposta JSON → Payload Meddle

Esempio:

Configurazione del reader:

{
"address": "192.168.1.50:50051",
"service": "iot.SensorService",
"method": "GetReading",
"requestBody": "{\"sensorId\":\"sensor-1\"}",
"pollingRate": 1000
}

Risposta del server:

{
"temperature": 24.7,
"humidity": 58.3,
"battery": 0.91,
"timestamp": "2026-05-20T10:14:33Z"
}

Payload Meddle emesso:

{
"temperature": 24.7,
"humidity": 58.3,
"battery": 0.91,
"timestamp": "2026-05-20T10:14:33Z"
}
Payload Meddle → GrpcWriter (codifica JSON) → Server gRPC

Esempio:

Payload in ingresso:

{
"deviceId": "plc-line-1",
"setpoint": 75.0,
"mode": "auto"
}

Il writer codifica il payload in JSON e invoca /iot.SensorService/PushReading con esso come corpo della richiesta. Qualunque risposta dal server viene letta e scartata.

1. Polling di un’API di Telemetria di un Microservizio

Sezione intitolata “1. Polling di un’API di Telemetria di un Microservizio”

Leggi dati dei sensori da un microservizio interno sulla LAN:

{
"type": "GrpcReader",
"config": {
"address": "telemetry.internal:50051",
"service": "telemetry.DeviceService",
"method": "GetMetrics",
"pollingRate": 2000,
"requestBody": "{\"deviceId\":\"compressor-3\"}"
}
}

2. Invio di Dati Aggregati a un Endpoint gRPC Cloud

Sezione intitolata “2. Invio di Dati Aggregati a un Endpoint gRPC Cloud”

Inoltra payload elaborati a un servizio cloud su TLS:

{
"type": "GrpcWriter",
"config": {
"address": "api.example.cloud:443",
"service": "ingest.MetricsService",
"method": "Push",
"tls": true
}
}

Collega due deployment Meddle utilizzando gRPC come trasporto:

{
"type": "GrpcWriter",
"config": {
"address": "edge-aggregator.local:50052",
"service": "meddle.BridgeService",
"method": "Forward",
"tls": false
}
}

Problema: connection refused o transport: error while dialing

Soluzioni:

  1. Verifica che indirizzo e porta siano corretti
  2. Conferma che il server gRPC sia in esecuzione e in ascolto
  3. Controlla le regole del firewall (telnet host port per un rapido test di raggiungibilità)
  4. Se il server richiede TLS, imposta tls: true

Problema: rpc error: code = Unimplemented o unknown method

Soluzioni:

  1. Verifica che service sia il nome qualificato completo incluso il pacchetto (es. iot.SensorService, non solo SensorService)
  2. Conferma che method corrisponda esattamente alla dichiarazione proto (case-sensitive)
  3. Usa uno strumento come grpcurl per elencare i servizi sull’endpoint:
    Terminal window
    grpcurl -plaintext 192.168.1.50:50051 list

Problema: Errore di deserializzazione sul server

Soluzioni:

  1. Valida che requestBody sia JSON ben formato
  2. Assicurati che i nomi dei campi corrispondano esattamente ai nomi dei campi proto (la transcodifica gRPC-JSON è case-sensitive)
  3. Se il tuo server si aspetta protobuf binario, la transcodifica gRPC-JSON (o grpc-gateway) deve essere abilitata lato server

Problema: Errori di handshake TLS o di certificato

Soluzioni:

  1. Conferma che il certificato del server sia valido e fidato
  2. Assicurati che l’hostname dell’indirizzo corrisponda al SAN del certificato
  3. Per certificati self-signed, installa la CA nel trust store dell’host Meddle

Problema: Timeout ripetuti di 10 secondi su ogni chiamata

Soluzioni:

  1. Investiga la latenza lato server
  2. Se la risposta è costantemente lenta, il timeout unary di 10s è un limite massimo — considera un metodo streaming o un trasporto diverso
  3. Riduci pollingRate per evitare di accumulare chiamate dietro risposte lente

Non lasciare mai tls: false per endpoint che attraversano internet pubblico:

{
"tls": true
}

Un polling di 100ms verso un server gRPC remoto può saturare i rate limit a valle. Inizia con 1000ms e riduci solo quando giustificato.

Preferisci servizi con contratti .proto espliciti e pacchetti versionati (es. iot.v1.SensorService) in modo che le configurazioni del reader non si rompano durante gli aggiornamenti del server.

4. Codifica i Corpi delle Richieste Deliberatamente

Sezione intitolata “4. Codifica i Corpi delle Richieste Deliberatamente”

Il requestBody inline è ottimo per parametri statici ma poco adatto a valori dinamici. Per corpi di richiesta dinamici, abbina un connettore Reshape o Transform a monte con un GrpcWriter invece di un reader.

Passa sempre le risposte gRPC attraverso un connettore Validation prima dei writer a valle, poiché gli schemi del server possono evolversi più velocemente della tua pipeline Meddle.

GrpcReader → Validation → Reshape → InfluxDb2Writer
  1. GrpcReader: Effettua polling su /iot.SensorService/GetReading ogni secondo
  2. Validation: Assicura che le chiavi richieste siano presenti e numeriche
  3. Reshape: Aggiunge tag come location, device_type
  4. InfluxDb2Writer: Archivia in un database time-series
ModbusReader → Filter → GrpcWriter (ingestione cloud)
  1. ModbusReader: Estrae valori dei registri da un PLC alla cadenza di 1s
  2. Filter: Mantiene solo le chiavi da inoltrare
  3. GrpcWriter: Invia il payload filtrato a un metodo cloud ingest.MetricsService.Push su TLS
  • HTTP Client - Alternativa per servizi REST/HTTP
  • MQTTv5 - Integrazione asincrona basata su broker
  • Kafka - Alternativa streaming ad alto throughput
  • Validation - Valida i payload di risposta gRPC
  • Reshape - Rinomina e arricchisci campi dalle risposte gRPC