Update to use @grpc/grpc-js node package, and update helloworld example

This commit is contained in:
Stanley Cheung 2020-06-11 14:23:46 -07:00 committed by Stanley Cheung
parent 6e632b4183
commit d32a30a5a6
12 changed files with 79 additions and 136 deletions

View File

@ -33,7 +33,7 @@ services:
context: ./ context: ./
dockerfile: ./net/grpc/gateway/docker/node_server/Dockerfile dockerfile: ./net/grpc/gateway/docker/node_server/Dockerfile
depends_on: depends_on:
- common - prereqs
image: grpcweb/node-server image: grpcweb/node-server
ports: ports:
- "9090:9090" - "9090:9090"

View File

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
FROM grpcweb/common FROM grpcweb/prereqs
WORKDIR /github/grpc-web/net/grpc/gateway/examples/echo/node-server WORKDIR /github/grpc-web/net/grpc/gateway/examples/echo/node-server

View File

@ -3,10 +3,10 @@
"version": "0.1.0", "version": "0.1.0",
"main": "server.js", "main": "server.js",
"dependencies": { "dependencies": {
"@grpc/grpc-js": "~1.0.5",
"@grpc/proto-loader": "~0.5.0", "@grpc/proto-loader": "~0.5.0",
"async": "~1.5.2", "async": "~1.5.2",
"google-protobuf": "~3.12.0", "google-protobuf": "~3.12.0",
"grpc": "~1.24.2",
"lodash": "~4.17.0" "lodash": "~4.17.0"
} }
} }

View File

@ -21,7 +21,7 @@ var PROTO_PATH = __dirname + '/../echo.proto';
var assert = require('assert'); var assert = require('assert');
var async = require('async'); var async = require('async');
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('grpc'); var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader'); var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync( var packageDefinition = protoLoader.loadSync(
PROTO_PATH, PROTO_PATH,
@ -105,7 +105,6 @@ function getServer() {
} }
if (require.main === module) { if (require.main === module) {
// If this is run as a script, start a server on an unused port
var echoServer = getServer(); var echoServer = getServer();
echoServer.bindAsync( echoServer.bindAsync(
'0.0.0.0:9090', grpc.ServerCredentials.createInsecure(), (err, port) => { '0.0.0.0:9090', grpc.ServerCredentials.createInsecure(), (err, port) => {

View File

@ -45,7 +45,7 @@ a nice response and send it back to the client via `callback(null, response)`.
```js ```js
var PROTO_PATH = __dirname + '/helloworld.proto'; var PROTO_PATH = __dirname + '/helloworld.proto';
var grpc = require('grpc'); var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader'); var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync( var packageDefinition = protoLoader.loadSync(
PROTO_PATH, PROTO_PATH,
@ -74,8 +74,11 @@ function getServer() {
if (require.main === module) { if (require.main === module) {
var server = getServer(); var server = getServer();
server.bind('0.0.0.0:9090', grpc.ServerCredentials.createInsecure()); server.bindAsync(
'0.0.0.0:9090', grpc.ServerCredentials.createInsecure(), (err, port) => {
assert.ifError(err);
server.start(); server.start();
});
} }
exports.getServer = getServer; exports.getServer = getServer;
@ -89,11 +92,6 @@ Envoy to listen at port `:8080`, and forward any gRPC-Web requests to a
cluster at port `:9090`. cluster at port `:9090`.
```yaml ```yaml
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources: static_resources:
listeners: listeners:
- name: listener_0 - name: listener_0
@ -132,32 +130,23 @@ static_resources:
type: logical_dns type: logical_dns
http2_protocol_options: {} http2_protocol_options: {}
lb_policy: round_robin lb_policy: round_robin
hosts: [{ socket_address: { address: localhost, port_value: 9090 }}] hosts: [{ socket_address: { address: 0.0.0.0, port_value: 9090 }}]
``` ```
NOTE: As per [this issue](https://github.com/grpc/grpc-web/issues/436): if > NOTE: As per [this issue](https://github.com/grpc/grpc-web/issues/436): if
you are running Docker on Mac/Windows, change the last line to > you are running Docker on Mac/Windows, change the last line to
>
```yaml > ```yaml
... > ...
hosts: [{ socket_address: { address: host.docker.internal, port_value: 9090 }}] > hosts: [{ socket_address: { address: host.docker.internal, port_value: 9090 }}]
``` > ```
>
or if your version of Docker on Mac older then v18.03.0, change it to: > or if your version of Docker on Mac older then v18.03.0, change it to:
>
```yaml > ```yaml
... > ...
hosts: [{ socket_address: { address: docker.for.mac.localhost, port_value: 9090 }}] > hosts: [{ socket_address: { address: docker.for.mac.localhost, port_value: 9090 }}]
``` > ```
To run Envoy (for later), you will need a simple Dockerfile. Put this in a
`envoy.Dockerfile`.
```dockerfile
FROM envoyproxy/envoy:v1.14.1
COPY ./envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml
```
## Write Client Code ## Write Client Code
@ -194,11 +183,12 @@ the `client.js` files.
"name": "grpc-web-simple-example", "name": "grpc-web-simple-example",
"version": "0.1.0", "version": "0.1.0",
"description": "gRPC-Web simple example", "description": "gRPC-Web simple example",
"main": "server.js",
"devDependencies": { "devDependencies": {
"@grpc/grpc-js": "~1.0.5",
"@grpc/proto-loader": "~0.5.4", "@grpc/proto-loader": "~0.5.4",
"async": "~1.5.2", "async": "~1.5.2",
"google-protobuf": "~3.12.0", "google-protobuf": "~3.12.0",
"grpc": "~1.24.2",
"grpc-web": "~1.1.0", "grpc-web": "~1.1.0",
"lodash": "~4.17.0", "lodash": "~4.17.0",
"webpack": "~4.43.0", "webpack": "~4.43.0",
@ -232,24 +222,26 @@ And that's it! We have all the code ready. Let's run the example!
## Generate Protobuf Messages and Client Service Stub ## Generate Protobuf Messages and Client Service Stub
To generate the protobuf messages and client service stub class from your To generate the protobuf messages and client service stub class from your
`.proto` definitions, we need the `protoc` binary and the `.proto` definitions, we need:
`protoc-gen-grpc-web` plugin. - the `protoc` binary, _and_
- the `protoc-gen-grpc-web` plugin.
You can download the `protoc-gen-grpc-web` protoc plugin from our > You can download the `protoc-gen-grpc-web` protoc plugin from our
[release](https://github.com/grpc/grpc-web/releases) page: > [release](https://github.com/grpc/grpc-web/releases) page.
>
> If you don't already have `protoc` installed, you will have to download it
> first from [here](https://github.com/protocolbuffers/protobuf/releases).
>
> Make sure they are both executable and are discoverable from your PATH.
>
> For example, in MacOS, you can do:
>
> ```sh
> $ sudo mv ~/Downloads/protoc-gen-grpc-web-1.1.0-darwin-x86_64 \
> /usr/local/bin/protoc-gen-grpc-web
> $ sudo chmod +x /usr/local/bin/protoc-gen-grpc-web
> ```
If you don't already have `protoc` installed, you will have to download it
first from [here](https://github.com/protocolbuffers/protobuf/releases).
Make sure they are both executable and are discoverable from your PATH.
For example, in MacOS, you can do:
```
$ sudo mv ~/Downloads/protoc-gen-grpc-web-1.1.0-darwin-x86_64 \
/usr/local/bin/protoc-gen-grpc-web
$ chmod +x /usr/local/bin/protoc-gen-grpc-web
```
When you have both `protoc` and `protoc-gen-grpc-web` installed, you can now When you have both `protoc` and `protoc-gen-grpc-web` installed, you can now
run this command: run this command:
@ -301,27 +293,21 @@ run the 3 processes all in the background.
above). above).
```sh ```sh
$ docker build -t helloworld/envoy -f ./envoy.Dockerfile . $ docker run -d -v "$(pwd)"/envoy.yaml:/etc/envoy/envoy.yaml:ro \
$ docker run -d -p 8080:8080 -p 9901:9901 --network=host helloworld/envoy --network=host envoyproxy/envoy:v1.14.1
``` ```
NOTE: As per [this issue](https://github.com/grpc/grpc-web/issues/436): > NOTE: As per [this issue](https://github.com/grpc/grpc-web/issues/436):
if you are running Docker on Mac/Windows, remove the `--network=host` option: > if you are running Docker on Mac/Windows, remove the `--network=host` option:
>
```sh > ```sh
... > $ docker run -d -v "$(pwd)"/envoy.yaml:/etc/envoy/envoy.yaml:ro \
$ docker run -d -p 8080:8080 -p 9901:9901 helloworld/envoy > envoyproxy/envoy:v1.14.1
``` > ```
3. Run the simple Web Server. This hosts the static file `index.html` and 3. Run the simple Web Server. This hosts the static file `index.html` and
`dist/main.js` we generated earlier. `dist/main.js` we generated earlier.
```sh
$ python2 -m SimpleHTTPServer 8081 &
```
or for Python 3.x
```sh ```sh
$ python3 -m http.server 8081 & $ python3 -m http.server 8081 &
``` ```
@ -337,8 +323,3 @@ Open up the developer console and you should see the following printed out:
``` ```
Hello! World Hello! World
``` ```
You can also browse to the envoy admin via
```
localhost:9901
```

View File

@ -28,7 +28,12 @@ var request = new HelloRequest();
request.setName('World'); request.setName('World');
client.sayHello(request, {}, (err, response) => { client.sayHello(request, {}, (err, response) => {
if (err) {
console.log(`Unexpected error for sayHello: code = ${err.code}` +
`, message = "${err.message}"`);
} else {
console.log(response.getMessage()); console.log(response.getMessage());
}
}); });
@ -41,14 +46,7 @@ var stream = client.sayRepeatHello(streamRequest, {});
stream.on('data', (response) => { stream.on('data', (response) => {
console.log(response.getMessage()); console.log(response.getMessage());
}); });
stream.on('error', (err) => {
console.log(`Unexpected stream error: code = ${err.code}` +
// deadline exceeded `, message = "${err.message}"`);
var deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 1);
client.sayHelloAfterDelay(request, {deadline: deadline.getTime()},
(err, response) => {
console.log('Got error, code = ' + err.code +
', message = ' + err.message);
}); });

View File

@ -1,19 +0,0 @@
# Copyright 2018 Google LLC
#
# 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
#
# https://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.
FROM envoyproxy/envoy:v1.14.1
COPY ./envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml

View File

@ -42,4 +42,4 @@ static_resources:
http2_protocol_options: {} http2_protocol_options: {}
lb_policy: round_robin lb_policy: round_robin
# win/mac hosts: Use address: host.docker.internal instead of address: localhost in the line below # win/mac hosts: Use address: host.docker.internal instead of address: localhost in the line below
hosts: [{ socket_address: { address: localhost, port_value: 9090 }}] hosts: [{ socket_address: { address: 0.0.0.0, port_value: 9090 }}]

View File

@ -21,8 +21,6 @@ service Greeter {
rpc SayHello(HelloRequest) returns (HelloReply); rpc SayHello(HelloRequest) returns (HelloReply);
// server streaming call // server streaming call
rpc SayRepeatHello(RepeatHelloRequest) returns (stream HelloReply); rpc SayRepeatHello(RepeatHelloRequest) returns (stream HelloReply);
// unary call - response after a length delay
rpc SayHelloAfterDelay(HelloRequest) returns (HelloReply);
} }
message HelloRequest { message HelloRequest {

View File

@ -1,7 +1,7 @@
var PROTO_PATH = __dirname + '/helloworld.proto'; var PROTO_PATH = __dirname + '/helloworld.proto';
var async = require('async'); var async = require('async');
var grpc = require('grpc'); var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader'); var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync( var packageDefinition = protoLoader.loadSync(
PROTO_PATH, PROTO_PATH,

View File

@ -4,10 +4,10 @@
"description": "gRPC-Web simple example", "description": "gRPC-Web simple example",
"main": "server.js", "main": "server.js",
"devDependencies": { "devDependencies": {
"@grpc/grpc-js": "~1.0.5",
"@grpc/proto-loader": "~0.5.4", "@grpc/proto-loader": "~0.5.4",
"async": "~1.5.2", "async": "~1.5.2",
"google-protobuf": "~3.12.0", "google-protobuf": "~3.12.0",
"grpc": "~1.24.2",
"grpc-web": "~1.1.0", "grpc-web": "~1.1.0",
"lodash": "~4.17.0", "lodash": "~4.17.0",
"webpack": "~4.43.0", "webpack": "~4.43.0",

View File

@ -18,9 +18,10 @@
var PROTO_PATH = __dirname + '/helloworld.proto'; var PROTO_PATH = __dirname + '/helloworld.proto';
var grpc = require('grpc'); var assert = require('assert');
var _ = require('lodash');
var async = require('async'); var async = require('async');
var _ = require('lodash');
var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader'); var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync( var packageDefinition = protoLoader.loadSync(
PROTO_PATH, PROTO_PATH,
@ -62,23 +63,6 @@ function doSayRepeatHello(call) {
}); });
} }
/**
* @param {!Object} call
* @param {function():?} callback
*/
function doSayHelloAfterDelay(call, callback) {
function dummy() {
return (cb) => {
_.delay(cb, 5000);
};
}
async.series([dummy()], () => {
callback(null, {
message: 'Hello! '+call.request.name
});
});
}
/** /**
* @return {!Object} gRPC server * @return {!Object} gRPC server
*/ */
@ -87,15 +71,17 @@ function getServer() {
server.addService(helloworld.Greeter.service, { server.addService(helloworld.Greeter.service, {
sayHello: doSayHello, sayHello: doSayHello,
sayRepeatHello: doSayRepeatHello, sayRepeatHello: doSayRepeatHello,
sayHelloAfterDelay: doSayHelloAfterDelay
}); });
return server; return server;
} }
if (require.main === module) { if (require.main === module) {
var server = getServer(); var server = getServer();
server.bind('0.0.0.0:9090', grpc.ServerCredentials.createInsecure()); server.bindAsync(
'0.0.0.0:9090', grpc.ServerCredentials.createInsecure(), (err, port) => {
assert.ifError(err);
server.start(); server.start();
});
} }
exports.getServer = getServer; exports.getServer = getServer;