gRPC Connector
Overview
Section titled “Overview”The gRPC connector enables Meddle to invoke gRPC services as both a client reader (polling unary calls) and a writer (forwarding payloads as gRPC requests). It uses HTTP/2 under the hood and supports optional TLS, making it suitable for integrating with modern microservices, edge gateways, and industrial APIs that expose gRPC endpoints.
Connector Types:
GrpcReader- Periodically invokes a unary gRPC method and emits the response as a Meddle payloadGrpcWriter- Sends each incoming payload as a gRPC request to the target service
Features
Section titled “Features”- ✅ HTTP/2 transport with optional TLS encryption
- ✅ Polling-based unary reader with configurable rate
- ✅ Writer forwards payloads as JSON-encoded gRPC requests
- ✅ Static request body for read polling
- ✅ Streaming-aware configuration flag
- ✅ Automatic connection management and reuse
- ✅ Per-call 10-second timeout for safety
Basic Configuration
Section titled “Basic Configuration”gRPC Reader
Section titled “gRPC Reader”{ "type": "GrpcReader", "config": { "address": "192.168.1.50:50051", "service": "iot.SensorService", "method": "GetReading", "pollingRate": 1000, "requestBody": "{\"sensorId\":\"sensor-1\"}" }}{ "type": "GrpcReader", "config": { "address": "edge.example.com:443", "service": "iot.SensorService", "method": "GetReading", "tls": true, "pollingRate": 5000, "requestBody": "{\"sensorId\":\"sensor-1\"}" }}{ "type": "GrpcReader", "config": { "address": "192.168.1.50:50051", "service": "iot.TelemetryService", "method": "Subscribe", "streaming": true, "pollingRate": 1000, "requestBody": "{\"deviceId\":\"plc-line-1\"}" }}gRPC Writer
Section titled “gRPC Writer”{ "type": "GrpcWriter", "config": { "address": "192.168.1.50:50051", "service": "iot.SensorService", "method": "PushReading", "tls": false }}Configuration Parameters
Section titled “Configuration Parameters”Address
Section titled “Address”The host and port of the gRPC server.
{ "address": "192.168.1.50:50051"}Format: host:port (no scheme prefix). For TLS endpoints, set tls: true rather than encoding it in the address.
Service
Section titled “Service”The fully qualified gRPC service name as defined in your .proto file, including the package prefix.
{ "service": "iot.SensorService"}Format: package.ServiceName. The connector composes the full method path as /{service}/{method} internally.
Method
Section titled “Method”The method name on the service to invoke.
{ "method": "GetReading"}This must match the method name exactly as declared in the proto definition (case-sensitive).
Enables TLS for the connection. When disabled, the connector uses insecure (plaintext) credentials.
{ "tls": true}Recommended values:
false- In-network, trusted environments (LAN/PLC)true- Public endpoints, cloud services, anything crossing untrusted networks
Request Body
Section titled “Request Body”Static JSON body sent as the request payload on every poll.
{ "requestBody": "{\"sensorId\":\"sensor-1\",\"includeHistory\":false}"}Notes:
- Must be a valid JSON string. Escape inner quotes as shown
- If omitted, an empty JSON object
{}is sent - The request body is treated as a
json.RawMessageand forwarded as-is on every poll
Polling Rate
Section titled “Polling Rate”Interval in milliseconds between successive gRPC calls (reader only).
{ "pollingRate": 1000}Recommended values:
- Fast: 100-500ms
- Normal: 1000ms (1 second)
- Slow: 5000ms+ (5 seconds or more)
Streaming
Section titled “Streaming”Flag to indicate the target method uses server-streaming semantics.
{ "streaming": true}When set, the connector still issues calls on the polling cadence but tags the configuration as streaming-aware so downstream tooling can adapt expectations. Use this for methods that return progressively larger payloads or maintain a longer connection lifecycle.
Data Flow
Section titled “Data Flow”Reader Data Flow
Section titled “Reader Data Flow”gRPC Server → GrpcReader (unary invoke) → JSON response → Meddle PayloadExample:
Reader configuration:
{ "address": "192.168.1.50:50051", "service": "iot.SensorService", "method": "GetReading", "requestBody": "{\"sensorId\":\"sensor-1\"}", "pollingRate": 1000}Server response:
{ "temperature": 24.7, "humidity": 58.3, "battery": 0.91, "timestamp": "2026-05-20T10:14:33Z"}Emitted Meddle payload:
{ "temperature": 24.7, "humidity": 58.3, "battery": 0.91, "timestamp": "2026-05-20T10:14:33Z"}Writer Data Flow
Section titled “Writer Data Flow”Meddle Payload → GrpcWriter (JSON encode) → gRPC ServerExample:
Incoming payload:
{ "deviceId": "plc-line-1", "setpoint": 75.0, "mode": "auto"}The writer JSON-encodes the payload and invokes /iot.SensorService/PushReading with it as the request body. Any response from the server is read and discarded.
Common Use Cases
Section titled “Common Use Cases”1. Polling a Microservice Telemetry API
Section titled “1. Polling a Microservice Telemetry API”Read sensor data from an internal microservice over the LAN:
{ "type": "GrpcReader", "config": { "address": "telemetry.internal:50051", "service": "telemetry.DeviceService", "method": "GetMetrics", "pollingRate": 2000, "requestBody": "{\"deviceId\":\"compressor-3\"}" }}2. Pushing Aggregated Data to a Cloud gRPC Endpoint
Section titled “2. Pushing Aggregated Data to a Cloud gRPC Endpoint”Forward processed payloads to a cloud service over TLS:
{ "type": "GrpcWriter", "config": { "address": "api.example.cloud:443", "service": "ingest.MetricsService", "method": "Push", "tls": true }}3. Edge-to-Edge Communication Between Meddle Instances
Section titled “3. Edge-to-Edge Communication Between Meddle Instances”Bridge two Meddle deployments using gRPC as the transport:
{ "type": "GrpcWriter", "config": { "address": "edge-aggregator.local:50052", "service": "meddle.BridgeService", "method": "Forward", "tls": false }}Troubleshooting
Section titled “Troubleshooting”Connection Refused
Section titled “Connection Refused”Problem: connection refused or transport: error while dialing
Solutions:
- Verify the address and port are correct
- Confirm the gRPC server is running and listening
- Check firewall rules (
telnet host portfor a quick reachability test) - If the server requires TLS, set
tls: true
Method Not Found
Section titled “Method Not Found”Problem: rpc error: code = Unimplemented or unknown method
Solutions:
- Verify the
serviceis the fully qualified name including the package (e.g.iot.SensorService, not justSensorService) - Confirm the
methodmatches the proto declaration exactly (case-sensitive) - Use a tool like
grpcurlto list services on the endpoint:Terminal window grpcurl -plaintext 192.168.1.50:50051 list
Invalid Request Body
Section titled “Invalid Request Body”Problem: Deserialization error on the server
Solutions:
- Validate that
requestBodyis well-formed JSON - Ensure the field names match the proto field names exactly (gRPC-JSON transcoding is case-sensitive)
- If your server expects protobuf binary, gRPC-JSON transcoding (or grpc-gateway) must be enabled server-side
TLS Handshake Failures
Section titled “TLS Handshake Failures”Problem: TLS handshake or certificate errors
Solutions:
- Confirm the server certificate is valid and trusted
- Ensure the address hostname matches the certificate’s SAN
- For self-signed certificates, install the CA into the trust store of the Meddle host
Timeouts
Section titled “Timeouts”Problem: Repeated 10-second timeouts on every call
Solutions:
- Investigate server-side latency
- If the response is consistently slow, the unary 10s timeout is a hard ceiling — consider a streaming method or a different transport
- Reduce
pollingRateto avoid stacking calls behind slow responses
Best Practices
Section titled “Best Practices”1. Always Use TLS Outside Trusted Networks
Section titled “1. Always Use TLS Outside Trusted Networks”Never leave tls: false for endpoints that traverse the public internet:
{ "tls": true}2. Keep Polling Rates Honest
Section titled “2. Keep Polling Rates Honest”A 100ms poll against a remote gRPC server can saturate downstream rate limits. Start at 1000ms and tighten only when justified.
3. Use Stable, Well-Known Services
Section titled “3. Use Stable, Well-Known Services”Prefer services with explicit .proto contracts and versioned packages (e.g. iot.v1.SensorService) so reader configs don’t break on server upgrades.
4. Encode Request Bodies Deliberately
Section titled “4. Encode Request Bodies Deliberately”Inline requestBody is great for static parameters but a poor fit for dynamic values. For dynamic request bodies, pair an upstream Reshape or Transform connector with a GrpcWriter instead of a reader.
5. Pair with Validation
Section titled “5. Pair with Validation”Always feed gRPC responses through a Validation connector before downstream writers, since server schemas may evolve faster than your Meddle pipeline.
Example Workflows
Section titled “Example Workflows”Reader → Storage Pipeline
Section titled “Reader → Storage Pipeline”GrpcReader → Validation → Reshape → InfluxDb2Writer- GrpcReader: Polls
/iot.SensorService/GetReadingevery second - Validation: Ensures required keys are present and numeric
- Reshape: Adds tags such as
location,device_type - InfluxDb2Writer: Stores in a time-series database
PLC → Cloud Bridge
Section titled “PLC → Cloud Bridge”ModbusReader → Filter → GrpcWriter (cloud ingest)- ModbusReader: Pulls register values from a PLC at 1s cadence
- Filter: Keeps only the keys to forward
- GrpcWriter: Pushes the filtered payload to a cloud
ingest.MetricsService.Pushmethod over TLS
Related Connectors
Section titled “Related Connectors”- HTTP Client - Alternative for REST/HTTP services
- MQTTv5 - Asynchronous broker-based integration
- Kafka - High-throughput streaming alternative
- Validation - Validate gRPC response payloads
- Reshape - Rename and enrich fields from gRPC responses
Additional Resources
Section titled “Additional Resources”- gRPC Official Site
- gRPC Protocol Documentation
- Protocol Buffers Reference
- grpcurl - Command-line gRPC client for testing endpoints
- gRPC Status Codes