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: ./
dockerfile: ./net/grpc/gateway/docker/node_server/Dockerfile
depends_on:
- common
- prereqs
image: grpcweb/node-server
ports:
- "9090:9090"

View File

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

View File

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

View File

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

View File

@ -45,7 +45,7 @@ a nice response and send it back to the client via `callback(null, response)`.
```js
var PROTO_PATH = __dirname + '/helloworld.proto';
var grpc = require('grpc');
var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
@ -74,8 +74,11 @@ function getServer() {
if (require.main === module) {
var server = getServer();
server.bind('0.0.0.0:9090', grpc.ServerCredentials.createInsecure());
server.start();
server.bindAsync(
'0.0.0.0:9090', grpc.ServerCredentials.createInsecure(), (err, port) => {
assert.ifError(err);
server.start();
});
}
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`.
```yaml
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
@ -132,32 +130,23 @@ static_resources:
type: logical_dns
http2_protocol_options: {}
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
you are running Docker on Mac/Windows, change the last line to
```yaml
...
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:
```yaml
...
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
```
> 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
>
> ```yaml
> ...
> 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:
>
> ```yaml
> ...
> hosts: [{ socket_address: { address: docker.for.mac.localhost, port_value: 9090 }}]
> ```
## Write Client Code
@ -194,11 +183,12 @@ the `client.js` files.
"name": "grpc-web-simple-example",
"version": "0.1.0",
"description": "gRPC-Web simple example",
"main": "server.js",
"devDependencies": {
"@grpc/grpc-js": "~1.0.5",
"@grpc/proto-loader": "~0.5.4",
"async": "~1.5.2",
"google-protobuf": "~3.12.0",
"grpc": "~1.24.2",
"grpc-web": "~1.1.0",
"lodash": "~4.17.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
To generate the protobuf messages and client service stub class from your
`.proto` definitions, we need the `protoc` binary and the
`protoc-gen-grpc-web` plugin.
`.proto` definitions, we need:
- the `protoc` binary, _and_
- the `protoc-gen-grpc-web` plugin.
You can download the `protoc-gen-grpc-web` protoc plugin from our
[release](https://github.com/grpc/grpc-web/releases) page:
> You can download the `protoc-gen-grpc-web` protoc plugin from our
> [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
run this command:
@ -301,27 +293,21 @@ run the 3 processes all in the background.
above).
```sh
$ docker build -t helloworld/envoy -f ./envoy.Dockerfile .
$ docker run -d -p 8080:8080 -p 9901:9901 --network=host helloworld/envoy
$ docker run -d -v "$(pwd)"/envoy.yaml:/etc/envoy/envoy.yaml:ro \
--network=host envoyproxy/envoy:v1.14.1
```
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:
```sh
...
$ docker run -d -p 8080:8080 -p 9901:9901 helloworld/envoy
```
> 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:
>
> ```sh
> $ docker run -d -v "$(pwd)"/envoy.yaml:/etc/envoy/envoy.yaml:ro \
> envoyproxy/envoy:v1.14.1
> ```
3. Run the simple Web Server. This hosts the static file `index.html` and
`dist/main.js` we generated earlier.
```sh
$ python2 -m SimpleHTTPServer 8081 &
```
or for Python 3.x
```sh
$ python3 -m http.server 8081 &
```
@ -337,8 +323,3 @@ Open up the developer console and you should see the following printed out:
```
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');
client.sayHello(request, {}, (err, response) => {
console.log(response.getMessage());
if (err) {
console.log(`Unexpected error for sayHello: code = ${err.code}` +
`, message = "${err.message}"`);
} else {
console.log(response.getMessage());
}
});
@ -41,14 +46,7 @@ var stream = client.sayRepeatHello(streamRequest, {});
stream.on('data', (response) => {
console.log(response.getMessage());
});
// deadline exceeded
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);
});
stream.on('error', (err) => {
console.log(`Unexpected stream 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: {}
lb_policy: round_robin
# 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);
// server streaming call
rpc SayRepeatHello(RepeatHelloRequest) returns (stream HelloReply);
// unary call - response after a length delay
rpc SayHelloAfterDelay(HelloRequest) returns (HelloReply);
}
message HelloRequest {

View File

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

View File

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

View File

@ -18,9 +18,10 @@
var PROTO_PATH = __dirname + '/helloworld.proto';
var grpc = require('grpc');
var _ = require('lodash');
var assert = require('assert');
var async = require('async');
var _ = require('lodash');
var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
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
*/
@ -87,15 +71,17 @@ function getServer() {
server.addService(helloworld.Greeter.service, {
sayHello: doSayHello,
sayRepeatHello: doSayRepeatHello,
sayHelloAfterDelay: doSayHelloAfterDelay
});
return server;
}
if (require.main === module) {
var server = getServer();
server.bind('0.0.0.0:9090', grpc.ServerCredentials.createInsecure());
server.start();
server.bindAsync(
'0.0.0.0:9090', grpc.ServerCredentials.createInsecure(), (err, port) => {
assert.ifError(err);
server.start();
});
}
exports.getServer = getServer;