Server TS


import path from "path";
import { Server, ServerCredentials, loadPackageDefinition } from "@grpc/grpc-js";
import { loadSync } from "@grpc/proto-loader";
import { ProtoGrpcType } from "./proto/random";
import { RandomHandlers } from "./proto/randomPackage/Random";

In this section, the script imports necessary modules and types. Here's what each import does:
  • path: The path module is used for working with file and directory paths.
  • Server and ServerCredentials from @grpc/grpc-js: These are classes provided by the @grpc/grpc-js library for creating a gRPC server and defining server credentials.
  • loadPackageDefinition from @grpc/grpc-js: This function is used to load gRPC service definitions.
  • loadSync from @grpc/proto-loader: This function is used to load Protocol Buffers (ProtoBuf) definitions from .proto files.
  • ProtoGrpcType and RandomHandlers: These are custom types imported from ProtoBuf-generated files. They define the types for gRPC services and handlers.

interface MainFunction {
(): void;
}

const main: MainFunction = () => {
// ...
}

Here, an interface MainFunction is defined to describe the structure of the main function. The main function is the entry point of the script, where the gRPC server is created and started.


const main: MainFunction = () => {
const server: Server = getServer();
server.bindAsync("0.0.0.0:9000", ServerCredentials.createInsecure(), (err) => {
if (err) {
console.error(err);
return;
}
console.log("Your server started on port 9000");
server.start();
});
};

The main function starts by creating an instance of the gRPC server using the getServer function. It then binds the server to a specific host and port (0.0.0.0:9000) and uses insecure server credentials (ServerCredentials.createInsecure()). When the server is successfully bound, it logs a message and starts the server.


interface GetServerFunction {
(): Server;
}

const getServer: GetServerFunction = () => {
const server: Server = new Server();
const packageDef: any = loadSync(path.resolve(__dirname, "./proto/random.proto"));
const grpcObj = loadPackageDefinition(packageDef) as unknown as ProtoGrpcType;
const randomPackage = grpcObj.randomPackage;

server.addService(randomPackage.Random.service, {
PingPong: (call, callback) => {
console.log(call.request);
callback(null, { message: "Pong" });
},
} as RandomHandlers);

return server;
};


The getServer function is responsible for creating and configuring the gRPC server. Here's what it does:

  • It creates an instance of the gRPC server using new Server().
  • It loads the gRPC service definition from a .proto file using loadSync and loadPackageDefinition. The ProtoGrpcType and randomPackage variables hold the generated service definitions.
  • It adds the PingPong method to the server. When a client calls this method, it logs the request and responds with a "Pong" message.
  • Finally, it returns the configured gRPC server.

The main function is called at the end of the script, which starts the gRPC server and binds it to the specified port.

In summary, this script sets up a basic gRPC server with a single PingPong method that logs incoming requests and responds with "Pong." It uses the @grpc/grpc-js and @grpc/proto-loader libraries for gRPC server setup and ProtoBuf definition loading. The gRPC server listens on port 9000 and starts when the script is executed.