diff --git a/examples/health_check/README.md b/examples/health_check/README.md new file mode 100644 index 000000000..6328bccdd --- /dev/null +++ b/examples/health_check/README.md @@ -0,0 +1,41 @@ +# Health Check + +This example demonstrates how to set up standard gRPC Health Checks utilizing the unified [grpc-health-check](https://www.npmjs.com/package/grpc-health-check) library. + +## Overview + +The example uses the `grpc-health-check` package to: +- **Server**: Initialize a `HealthImplementation` and toggle the health status every 3 seconds. +- **Client**: Connect to the server and `watch` the health service for streamed status updates. + +## Start the server + +Run the server, which serves only the health checking API: + +``` +node server.js +``` + +## Run the client + +In another terminal, run the client which watches the server for health check variations: + +``` +node client.js +``` + +## Expected Output + +The client will begin to continuously receive state changes from the server: + +**Server Output:** +``` +Server running at http://0.0.0.0:50051 +``` + +**Client Output:** +``` +Health check status: SERVING +Health check status: NOT_SERVING +Health check status: SERVING +``` diff --git a/examples/health_check/client.js b/examples/health_check/client.js new file mode 100644 index 000000000..46c22e640 --- /dev/null +++ b/examples/health_check/client.js @@ -0,0 +1,51 @@ +/* + * + * Copyright 2026 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +const grpc = require('@grpc/grpc-js'); +const protoLoader = require('@grpc/proto-loader'); +const { protoPath: HEALTH_PROTO_PATH } = require('grpc-health-check'); + +const packageDefinition = protoLoader.loadSync( + HEALTH_PROTO_PATH, + {keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true + }); +const healthProto = grpc.loadPackageDefinition(packageDefinition).grpc.health.v1; + +function main() { + const healthClient = new healthProto.Health('localhost:50051', grpc.credentials.createInsecure()); + + const watchStream = healthClient.watch({ service: '' }); + + watchStream.on('data', function (response) { + console.log(`Health check status: ${response.status}`); + }); + + watchStream.on('error', function (error) { + console.error('Health check error:', error.message); + }); + + watchStream.on('end', function () { + console.log('Health check stream ended.'); + }); +} + +main(); diff --git a/examples/health_check/server.js b/examples/health_check/server.js new file mode 100644 index 000000000..b56fe3531 --- /dev/null +++ b/examples/health_check/server.js @@ -0,0 +1,47 @@ +/* + * + * Copyright 2026 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +const grpc = require('@grpc/grpc-js'); +const { HealthImplementation } = require('grpc-health-check'); + +/** + * Starts an RPC server that toggles health checks status. + */ +function main() { + const server = new grpc.Server(); + + // Set up the health check service + const statusMap = { + '': 'SERVING', + }; + const healthImpl = new HealthImplementation(statusMap); + healthImpl.addToServer(server); + + // Toggle the health status continuously + let nextStatus = 'NOT_SERVING'; + setInterval(() => { + healthImpl.setStatus('', nextStatus); + nextStatus = nextStatus === 'SERVING' ? 'NOT_SERVING' : 'SERVING'; + }, 3000); + + server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => { + console.log('Server running at http://0.0.0.0:50051'); + }); +} + +main(); diff --git a/examples/package.json b/examples/package.json index dc2cff79b..e843ec242 100644 --- a/examples/package.json +++ b/examples/package.json @@ -8,6 +8,7 @@ "@grpc/grpc-js": "^1.10.2", "@grpc/grpc-js-xds": "^1.10.0", "@grpc/reflection": "^1.0.0", + "grpc-health-check": "^2.1.0", "@q42philips/node-grpc-error-details": "^2.1.0", "lodash": "^4.6.1", "minimist": "^1.2.0"