This article was originally published on AI Study Room. For the full version with working code examples and related articles, visit the original post.
Introduction
Real-time communication is essential for modern applications--from chat and live dashboards to multiplayer gaming and financial trading platforms. gRPC and WebSocket represent two fundamentally different approaches to bidirectional streaming. gRPC builds on HTTP/2 with Protocol Buffers for typed, efficient RPCs. WebSocket provides a message-oriented protocol over a single TCP connection. This article compares them across the dimensions that matter for real-time application design.
Protocol Fundamentals
gRPC: HTTP/2 + Protocol Buffers
gRPC leverages HTTP/2 multiplexing and Protocol Buffers for typed, efficient communication:
// order.proto
syntax = "proto3";
package order;
service OrderService {
// Unary RPC (request-response)
rpc CreateOrder(CreateOrderRequest) returns (Order);
// Server streaming (push events to client)
rpc SubscribeOrders(OrderFilter) returns (stream Order);
// Client streaming (upload batch)
rpc BulkCreateOrders(stream CreateOrderRequest) returns (BulkResponse);
// Bidirectional streaming (full duplex)
rpc ProcessOrders(stream OrderAction) returns (stream OrderResult);
}
message Order {
string id = 1;
string user_id = 2;
repeated LineItem items = 3;
double total = 4;
OrderStatus status = 5;
google.protobuf.Timestamp created_at = 6;
}
message CreateOrderRequest {
string user_id = 1;
repeated LineItem items = 2;
}
message OrderFilter {
repeated string statuses = 1;
}
message LineItem {
string product_id = 1;
int32 quantity = 2;
double price = 3;
}
enum OrderStatus {
PENDING = 0;
CONFIRMED = 1;
PROCESSING = 2;
SHIPPED = 3;
DELIVERED = 4;
CANCELLED = 5;
}
Server implementation in Go:
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
pb "path/to/proto/order"
)
type orderServer struct {
pb.UnimplementedOrderServiceServer
}
// Bidirectional streaming
func (s *orderServer) ProcessOrders(
stream pb.OrderService_ProcessOrdersServer,
) error {
for {
action, err := stream.Recv()
if err != nil {
return err
}
// Process order action
result := &pb.OrderResult{
OrderId: action.OrderId,
Status: pb.OrderStatus_PROCESSING,
Message: "Order received and processing",
}
if err := stream.Send(result); err != nil {
return err
}
}
}
func main() {
lis, _ := net.Listen("tcp", ":50051")
s := grpc.NewServer(
grpc.MaxRecvMsgSize(4 * 1024 * 1024), // 4MB
grpc.MaxSendMsgSize(4 * 1024 * 1024), // 4MB
grpc.InitialWindowSize(1<<31 - 1), // Flow control
grpc.InitialConnWindowSize(1<<31 - 1),
)
pb.RegisterOrderServiceServer(s, &orderServer{})
log.Fatal(s.Serve(lis))
}
Client in Python:
import grpc
import order_pb2
import order_pb2_grpc
async def process_orders():
async with grpc.aio.insecure_channel('localhost:50051') as channel:
stub = order_pb2_grpc.OrderServiceStub(channel)
async def generate_actions():
for i in range(100):
yield order_pb2.OrderAction(
order_id=f"ord-{i}",
action="process",
payload=b"{}",
)
async for result in stub.ProcessOrders(generate_actions()):
print(f"Order {result.order_id}: {result.status}")
WebSocket: Message-Based Protocol
WebSocket provides a simpler, message-oriented protocol over TCP:
// WebSocket client (browser)
const ws = new WebSocket('wss://api.example.com/orders');
// Connection lifecycle
ws.onopen = () => {
console.log('Connected to order service');
ws.send(JSON.stringify({
type: 'subscribe',
channels: ['orders.created', 'orders.status'],
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'order.created':
displayNewOrder(message.data);
break;
case 'order.status':
updateOrderStatus(message.data);
break;
case 'error':
handleError(message.error);
break;
}
};
ws.onclose = (event) => {
if (event.code !== 1000) {
// Unexpected close, reconnect with exponential backoff
scheduleReconnect(event.code);
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
// Send action
function processOrder(orderId) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({
type: 'process_order',
order_id: orderId,
timestamp: Date.now(),
}));
}
}
Server in Node.js:
javascript
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({
port: 8080,
maxPayload: 1024 * 1024, // 1MB
---
**Read the full article on [AI Study Room](https://dingjiu1989-hue.github.io/en/compare/grpc-vs-websocket.html)** for complete code examples, comparison tables, and related resources.
*Found this useful? Check out more [developer guides and tool comparisons](https://dingjiu1989-hue.github.io/en/) on AI Study Room.*
Top comments (0)