|  | 
|  | 1 | +/* | 
|  | 2 | + * | 
|  | 3 | + * Copyright 2024 gRPC authors. | 
|  | 4 | + * | 
|  | 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 6 | + * you may not use this file except in compliance with the License. | 
|  | 7 | + * You may obtain a copy of the License at | 
|  | 8 | + * | 
|  | 9 | + *     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 10 | + * | 
|  | 11 | + * Unless required by applicable law or agreed to in writing, software | 
|  | 12 | + * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 14 | + * See the License for the specific language governing permissions and | 
|  | 15 | + * limitations under the License. | 
|  | 16 | + * | 
|  | 17 | + */ | 
|  | 18 | + | 
|  | 19 | +const grpc = require('@grpc/grpc-js'); | 
|  | 20 | +const protoLoader = require('@grpc/proto-loader'); | 
|  | 21 | +const parseArgs = require('minimist'); | 
|  | 22 | + | 
|  | 23 | +const PROTO_PATH = __dirname + '/../protos/echo.proto'; | 
|  | 24 | + | 
|  | 25 | +const packageDefinition = protoLoader.loadSync( | 
|  | 26 | +  PROTO_PATH, | 
|  | 27 | +  {keepCase: true, | 
|  | 28 | +   longs: String, | 
|  | 29 | +   enums: String, | 
|  | 30 | +   defaults: true, | 
|  | 31 | +   oneofs: true | 
|  | 32 | +  }); | 
|  | 33 | +const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo; | 
|  | 34 | + | 
|  | 35 | +const keepaliveOptions = { | 
|  | 36 | +  // If a client is idle for 15 seconds, send a GOAWAY | 
|  | 37 | +  'grpc.max_connection_idle_ms': 15_000, | 
|  | 38 | +  // If any connection is alive for more than 30 seconds, send a GOAWAY | 
|  | 39 | +  'grpc.max_connection_age_ms': 30_000, | 
|  | 40 | +  // Allow 5 seconds for pending RPCs to complete before forcibly closing connections | 
|  | 41 | +  'grpc.max_connection_age_grace_ms': 5_000, | 
|  | 42 | +  // Ping the client every 5 seconds to ensure the connection is still active | 
|  | 43 | +  'grpc.keepalive_time_ms': 5_000, | 
|  | 44 | +  // Wait 1 second for the ping ack before assuming the connection is dead | 
|  | 45 | +  'grpc.keepalive_timeout_ms': 1_000 | 
|  | 46 | +} | 
|  | 47 | + | 
|  | 48 | +function unaryEcho(call, callback) { | 
|  | 49 | +  callback(null, call.request); | 
|  | 50 | +} | 
|  | 51 | + | 
|  | 52 | +const serviceImplementation = { | 
|  | 53 | +  unaryEcho | 
|  | 54 | +}; | 
|  | 55 | + | 
|  | 56 | +function main() { | 
|  | 57 | +  const argv = parseArgs(process.argv.slice(2), { | 
|  | 58 | +    string: 'port', | 
|  | 59 | +    default: {port: '50052'} | 
|  | 60 | +  }); | 
|  | 61 | +  const server = new grpc.Server(keepaliveOptions); | 
|  | 62 | +  server.addService(echoProto.Echo.service, serviceImplementation); | 
|  | 63 | +  server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), (err, port) => { | 
|  | 64 | +    if (err != null) { | 
|  | 65 | +      return console.error(err); | 
|  | 66 | +    } | 
|  | 67 | +    console.log(`gRPC listening on ${port}`) | 
|  | 68 | +  }); | 
|  | 69 | +} | 
|  | 70 | + | 
|  | 71 | +main(); | 
0 commit comments