This gRPC mode allows you to stream data from a client to server which is useful for file uploads. During client-streaming RPC, the server processes the data as it arrives which is useful when dealing with large payloads.
syntax = "proto3";
package todo_service;
message NoParam {
}
message TodoItem {
int32 id = 1;
string text = 2;
}
message TodoItems {
// Repeated is an array
repeated TodoItem items = 1;
}
service Todo {
rpc createStream(stream TodoItem) returns (TodoItem);
} // server
import type { ProtoGrpcType } from '../proto/todo';
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import type { TodoHandlers } from '../proto/todo_service/Todo';
import type { TodoItem } from '../proto/todo_service/TodoItem';
const packageDefinition = protoLoader.loadSync('proto/todo.proto', {
longs: String,
enums: String,
defaults: true,
oneofs: true,
});
const proto = grpc.loadPackageDefinition(
packageDefinition
) as unknown as ProtoGrpcType;
// Typed service implementation
const todos = new Map<number, TodoItem>();
const todoService: TodoHandlers = {
createStream: (call, callback) => {
let counter = 0;
call.on('data', (item: TodoItem) => {
if (!item.text) {
return callback({
code: grpc.status.INVALID_ARGUMENT,
details: 'Missing text',
});
}
const newTodo = { id: todos.size + 1, text: item.text };
todos.set(newTodo.id, newTodo);
counter++;
});
call.on('end', () => console.log(`Steram ended. Added ${counter} item(s)`));
},
};
// Create and start gRPC server
const server = new grpc.Server();
server.addService(proto.todo_service.Todo.service, todoService);
server.bindAsync(
'0.0.0.0:50051',
grpc.ServerCredentials.createInsecure(),
() => {
console.log('gRPC server running on port 50051');
}
);
// client
import grpc from '@grpc/grpc-js';
import protoLoader from '@grpc/proto-loader';
import type { ProtoGrpcType } from './proto/todo';
const packageDef = protoLoader.loadSync('./proto/todo.proto', {
longs: String,
enums: String,
defaults: true,
oneofs: true,
});
const grpcObject = grpc.loadPackageDefinition(
packageDef
) as unknown as ProtoGrpcType;
const todoPackage = grpcObject.todo_service;
const client = new todoPackage.Todo(
'localhost:50051',
grpc.credentials.createInsecure()
);
const stream = client.createStream((error, res) => {
if (error) {
console.error(error.message);
}
console.log(res);
});
stream.write({
text: 'Task 1',
});
stream.write({
text: 'Task 2',
});
stream.write({
text: 'Task 3',
});
stream.write({
text: 'Task 4',
});
stream.write({
text: 'Task 5',
});