This mode allows you to stream data via gRPC from a server to a client continuously when connection has been established. A real world example would be a video streaming service.
Example
// todo.proto
syntax = "proto3";
package todo;
message NoParam {}
message TodoItem {
int32 id = 1;
string text = 2;
}
message TodoItems {
repeated TodoItem items = 1;
}
service Todo {
rpc readStream(NoParam) returns (stream TodoItem); // Server streaming
} // server.ts
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import { TodoItem, TodoHandlers } from './proto/todo'; // Import the necessary types
// Load the .proto file
const packageDefinition = protoLoader.loadSync('todo.proto', {
longs: String,
enums: String,
defaults: true,
oneofs: true,
});
const proto = grpc.loadPackageDefinition(packageDefinition) as any;
// Create in-memory storage for Todo items
const todos: TodoItem[] = [
{ id: 1, text: 'Learn gRPC' },
{ id: 2, text: 'Implement server streaming' },
{ id: 3, text: 'Test server-streaming RPC' },
];
// Typed server implementation
const todoService: TodoHandlers = {
readStream: (call) => {
let count = 0;
const intervalId = setInterval(() => {
if (count < todos.length) {
// Stream each TodoItem to the client
call.write(todos[count]);
count++;
} else {
// End the stream after all items are sent
clearInterval(intervalId);
call.end();
}
}, 1000); // Send a TodoItem every 1 second
},
};
// Create and start the gRPC server
const server = new grpc.Server();
server.addService(proto.todo.Todo.service, todoService);
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
console.log('gRPC server running on port 50051');
server.start();
});
// client.ts
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
// Load the .proto file
const packageDef = protoLoader.loadSync('todo.proto', {
longs: String,
enums: String,
defaults: true,
oneofs: true,
});
const grpcObject = grpc.loadPackageDefinition(packageDef) as any;
const todoPackage = grpcObject.todo.Todo;
const client = new todoPackage('localhost:50051', grpc.credentials.createInsecure());
// Call the readStream method
const call = client.readStream({});
call.on('data', (item) => {
console.log('Received Todo Item:', item);
});
call.on('end', () => {
console.log('Server has finished sending data');
});
call.on('error', (err) => {
console.error('Error:', err);
});