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);  
});