I have a nestjs + grpc-js service and a client. And this rpc is called very frequently. The question is: does it reuse the connection or starts a new one every time rpc is called? Or should I use streaming to avoid reconnect and save memory/reduce time?
rpc CreateMessage(CreateMessageRequest) returns (common.Message);`
This is how grpc client is implemented in my project:
// chat.service.ts
@Injectable()
export class ChatService implements OnModuleInit {
  private svc: ChatServiceClient;
  @Inject(CHAT_SERVICE_NAME)
  private readonly grpcChatClient: ClientGrpc;
  public onModuleInit(): void {
    this.svc = this.grpcChatClient.getService<ChatServiceClient>(
      CHAT_SERVICE_NAME,
    );
  }
  public createMessage(request: CreateMessageRequest): Promise<Message> {
    return firstValueFrom(this.svc.createMessage(request));
  }
}
// chat.module.ts
@Module({
  imports: [
    ClientsModule.registerAsync([
      {
        name: CHAT_SERVICE_NAME,
        useFactory: (configService: ConfigService) => {
          return configService.get('grpc.grpcChatOptions');
        },
        inject: [ConfigService],
      },
    ]),
    AuthModule
  ],
  providers: [ChatService, ChatGateway],
  controllers: [ChatController],
})
export class ChatModule {}
//grpc.options.ts
grpcChatOptions: {
    name: CHAT_SERVICE_NAME,
    transport: Transport.GRPC,
    options: {
      url: process.env.GRPC_CHAT_SERVICE_HOST || '127.0.0.1:50053',
      package: [
        HEALTH_CHECK_PACKAGE_NAME,
        CHAT_PACKAGE_NAME,
      ],
      protoPath: [
        resolve(__dirname, '../_proto/health-check.proto'),
        resolve(__dirname, '../_proto/chat.proto'),
      ],
      loader: {
        keepCase: true,
        longs: String,
        defaults: true,
        oneofs: true,
      },
    },
  } as ClientProviderOptions
Does this library reuse HTTP/2 connection internally? If not, should I do it myself (by implementing grpc stream)?
How to deal with rpc that should be called very often (like several times a second to send chat messages)?
 
                        
If you use the same client/channel object to make multiple requests, those requests will generally use the same connection. The gRPC client can easily handle several requests per second.
There is per-request overhead, so if streaming makes sense for your use case, it will probably increase performance.