mirror of https://github.com/grpc/grpc-web.git
Added multiple proxies interoperability
This commit is contained in:
parent
712d78461e
commit
a9aa7dffb0
3
Makefile
3
Makefile
|
@ -93,6 +93,9 @@ plugin:
|
|||
example: plugin
|
||||
cd "$(ROOT_DIR)"/net/grpc/gateway/examples/echo && make
|
||||
|
||||
standalone-proxy: package
|
||||
cd "$(ROOT_DIR)"/net/grpc/gateway/examples/echo && make standalone-proxy
|
||||
|
||||
echo_server:
|
||||
cd "$(ROOT_DIR)"/net/grpc/gateway/examples/echo && make echo_server
|
||||
|
||||
|
|
25
README.md
25
README.md
|
@ -28,13 +28,13 @@ Try gRPC-Web and run a quick Echo example from the browser!
|
|||
From the repo root directory:
|
||||
|
||||
```sh
|
||||
$ docker-compose up
|
||||
$ docker-compose up echo-server envoy commonjs-client-example
|
||||
```
|
||||
|
||||
Open a browser tab, and inspect
|
||||
|
||||
```
|
||||
http://localhost/net/grpc/gateway/examples/echo/echotest.html
|
||||
http://localhost:8081/echo_commonjs_test.html
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
@ -99,3 +99,24 @@ stream.on('data', function(response) {
|
|||
console.log(response.getMessage());
|
||||
});
|
||||
```
|
||||
|
||||
## Proxy interoperability
|
||||
|
||||
Multiple proxies supports the gRPC-Web protocol. Currently, the default proxy
|
||||
is [Envoy](https://www.envoyproxy.io).
|
||||
|
||||
```
|
||||
$ docker-compose up echo-server envoy commonjs-client-example
|
||||
```
|
||||
|
||||
An alternative is to build Nginx that comes with this repository.
|
||||
|
||||
```
|
||||
$ docker-compose up echo-server nginx commonjs-client-example
|
||||
```
|
||||
|
||||
Finally, you can also try this [gRPC-Web Go Proxy](https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy).
|
||||
|
||||
```
|
||||
$ docker-compose up echo-server grpcwebproxy binary-client-example
|
||||
```
|
||||
|
|
|
@ -23,6 +23,24 @@ services:
|
|||
- "8080:8080"
|
||||
links:
|
||||
- echo-server
|
||||
grpcwebproxy:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./net/grpc/gateway/docker/grpcwebproxy/Dockerfile
|
||||
image: grpc-web:grpcwebproxy
|
||||
ports:
|
||||
- "8080:8080"
|
||||
links:
|
||||
- echo-server
|
||||
nginx:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./net/grpc/gateway/docker/nginx/Dockerfile
|
||||
image: grpc-web:nginx
|
||||
ports:
|
||||
- "8080:8080"
|
||||
links:
|
||||
- echo-server
|
||||
static-assets:
|
||||
build:
|
||||
context: ./
|
||||
|
@ -41,3 +59,12 @@ services:
|
|||
image: grpc-web:commonjs-client-example
|
||||
ports:
|
||||
- "8081:8081"
|
||||
binary-client-example:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: ./net/grpc/gateway/docker/binary_client_example/Dockerfile
|
||||
depends_on:
|
||||
- prereqs
|
||||
image: grpc-web:binary-client-example
|
||||
ports:
|
||||
- "8081:8081"
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC9jCCAd4CCQCfXxHXagE8mjANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQGEwJV
|
||||
UzELMAkGA1UECAwCQ0ExITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
|
||||
ZDAeFw0xODA4MDMyMTE2NDdaFw0yMTA1MjMyMTE2NDdaMD0xCzAJBgNVBAYTAlVT
|
||||
MQswCQYDVQQIDAJDQTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/MlKj+OtIgJm/7DywOR
|
||||
POypfvGHXqHTpg/ZbZgflx2vMwgoAhdun2e//AlssouStadnkevPEr+uFfxkEzH3
|
||||
80iYDtcZKXY8E6692hFrp7hKnA7gcBbb7ZQ1FwG/SfKLtLcderLcQb51P7IsQkfh
|
||||
nB8hSosV9nHhdfVtsMW7L/caqB5lUHIbRsHhSw3+hzg0r0HuKxXd5HlyRXzf9cQX
|
||||
4xc5B8Ldxo3QmXDOUHDw9quuxvUn5VWppWCGn2J+f9L/5iwgciApbiMBv/CkiVrt
|
||||
iYwZY+TZY5u8lmL4FtLd2tj2vNXl5ESWcL1SRGSiaYmxX1B5rg4fSAAXmcNOzZHo
|
||||
8wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCHko8eFag++9knWV8KlRRi+IdGeatU
|
||||
TejdBVnCPFc7sJf1lkUQSb0mZMv0QEO51aXGVvU46pIjTAwtzcVgPc6ZHqcZY4r3
|
||||
xscrmECThbhsEQCHqDD55OB2a06bx+ylfbBnLh+F18W+/rI+HlRxSBGclyfVto1P
|
||||
aCuYvYc0qKK90Ft1joZh1tXpho/D52B4CTa0Ax/5UqSVjTt0uPDhkCZJKnoENVgh
|
||||
6hF8ehYTC6Kf6ZtbB6+GuaLXf6F96CROLifW219qxrKmGbMyJXolOxLatufnWwwv
|
||||
Hw7z1FUzulJUkSRmgPJ9hFeyTjCS1BJ18glFjleLykYOtQi8kvnpFm6C
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA2/MlKj+OtIgJm/7DywORPOypfvGHXqHTpg/ZbZgflx2vMwgo
|
||||
Ahdun2e//AlssouStadnkevPEr+uFfxkEzH380iYDtcZKXY8E6692hFrp7hKnA7g
|
||||
cBbb7ZQ1FwG/SfKLtLcderLcQb51P7IsQkfhnB8hSosV9nHhdfVtsMW7L/caqB5l
|
||||
UHIbRsHhSw3+hzg0r0HuKxXd5HlyRXzf9cQX4xc5B8Ldxo3QmXDOUHDw9quuxvUn
|
||||
5VWppWCGn2J+f9L/5iwgciApbiMBv/CkiVrtiYwZY+TZY5u8lmL4FtLd2tj2vNXl
|
||||
5ESWcL1SRGSiaYmxX1B5rg4fSAAXmcNOzZHo8wIDAQABAoIBAFPnJL5BEIb9fezr
|
||||
+nRvH/BFt0KdkC4hPUOTuDV+Wk6jHDozWk+x8JkOUsYqMjTJ2WVCPtgDRDK6vAXX
|
||||
CbXo0dUUVC0VEJwoZjJ77iBJlO+d9ZgidKtNjQfMCZSFLhtfUrvVPoGXyT2rEb8C
|
||||
kK+YDBAqL+DnvbENMBx3SyirxQQ+YetAUSxiZagtjKlax1bhXF/JCj816ezDqOzR
|
||||
ZVx4MJiJg3oD+zKlwP+IaFlANIuW2W7+LbNzPpdXER4gafRzyjRy5ksO9NFO11Bu
|
||||
2srJbAMZEr0MCEBjf5rD7CPuvhTTEcgk6CNPsIEt8zzMSZUMeS0xaIv0W1FKiw+R
|
||||
BENntsECgYEA84fSMRApKaweeBrthPKR1ucnv3EHxn1l1mz45bp+2euHB6jUul9D
|
||||
629mMv8J9PVdcPF5ck7YpCjslWm6oOhtKMemuwJm61cRF44Lz7jtLm3zNJMGhpbh
|
||||
6Q0GoIVcyMrW79BODbEIU5SlWp0Usyjo/4CZEP5adho1JNTDHCyvEVUCgYEA5zY6
|
||||
tbfu+YYgICBnaRkGgdCRBxMurxdPrgbwvrKSMerYE9fufpgvZc5wwx02rJX0psuo
|
||||
JNGLAkPJyimZCYhY/hxWwXQX8X4BhkKK2aFyBMaDIBA0h+unOwTxHrebQNprot3h
|
||||
YVT8+tfZf8bGPl+dBs3Qf+WOESjRSyO9jr5BMScCgYBfI4mPF1Qtbot8unBeRvGI
|
||||
tkeF999kwOp/CZV3EhOqiOP4rxFkOgFrwdp4Q8CdDRpTHFMov/rMrxw2BtcdM5Ap
|
||||
pU3Ss06H1DzeKeUdYo5uXA/uUx3yiJF7HVagcVldLDkp+QP1P1sUY/bxXnqOv4W/
|
||||
A3tI80Vd7EEkwWXz5NUD/QKBgGXhYXFdQTI2RcWiQa7v1gwxqRYi/7krXnLioAaH
|
||||
jR/tyZTE21RxHsGPe+Sd5M+brBgrOUYwBz7SPAKW3dZzfDNMrXXFAB/rVCSjAafw
|
||||
Gdu81V61hVA3KJM7FDxiz0h+dltnxb4rwuWNY0uIfSZS31B2NF+G+VjaUY74irhx
|
||||
YSyVAoGANrn70s5+cJDWcmDhaFNU/J/X2Q8GgTyBRd02FIvuv7BXgd9TZ7bUVTws
|
||||
1nsQCCEVJqj4ksddVRq33NvsnjrgetGYe1LGl3uLakqaXd7iJXFCice3ZuFFrp9o
|
||||
Iq2sUgG+9K8WFqNhANRKBVd32IpQzjIMAAJSbuG3EFZDLZJqxDs=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -165,7 +165,7 @@ void PrintFileHeader(Printer* printer, const std::map<string, string>& vars) {
|
|||
}
|
||||
|
||||
void PrintServiceConstructor(Printer* printer,
|
||||
const std::map<string, string>& vars) {
|
||||
std::map<string, string>& vars) {
|
||||
printer->Print(
|
||||
vars,
|
||||
"/**\n"
|
||||
|
@ -181,6 +181,14 @@ void PrintServiceConstructor(Printer* printer,
|
|||
" /**\n"
|
||||
" * @private @const {!grpc.web.$mode$ClientBase} The client\n"
|
||||
" */\n"
|
||||
" if (!options) options = {};\n");
|
||||
if (vars["mode"] == GetModeVar(Mode::GRPCWEB)) {
|
||||
printer->Print(
|
||||
vars,
|
||||
" options['format'] = '$format$';\n\n");
|
||||
}
|
||||
printer->Print(
|
||||
vars,
|
||||
" this.client_ = new grpc.web.$mode$ClientBase(options);\n\n"
|
||||
" /**\n"
|
||||
" * @private @const {string} The hostname\n"
|
||||
|
@ -357,8 +365,9 @@ class GrpcCodeGenerator : public CodeGenerator {
|
|||
vars["mode"] = GetModeVar(Mode::OP);
|
||||
} else if (mode == "base64") {
|
||||
vars["mode"] = GetModeVar(Mode::GATEWAY);
|
||||
} else if (mode == "grpcweb") {
|
||||
} else if (mode == "grpcweb" || mode == "grpcwebtext") {
|
||||
vars["mode"] = GetModeVar(Mode::GRPCWEB);
|
||||
vars["format"] = (mode == "grpcweb") ? "binary" : "text";
|
||||
} else if (mode == "jspb") {
|
||||
vars["mode"] = GetModeVar(Mode::OPJSPB);
|
||||
} else if (mode == "frameworks") {
|
||||
|
|
|
@ -43,6 +43,13 @@ const googCrypt = goog.require('goog.crypt.base64');
|
|||
* @implements {AbstractClientBase}
|
||||
*/
|
||||
const GrpcWebClientBase = function(opt_options) {
|
||||
/**
|
||||
* @const
|
||||
* @private {string}
|
||||
*/
|
||||
this.format_ =
|
||||
goog.getObjectByName('format', opt_options) || "text";
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @private {boolean}
|
||||
|
@ -58,8 +65,6 @@ const GrpcWebClientBase = function(opt_options) {
|
|||
GrpcWebClientBase.prototype.rpcCall = function(
|
||||
method, request, metadata, methodInfo, callback) {
|
||||
var xhr = this.newXhr_();
|
||||
var serialized = methodInfo.requestSerializeFn(request);
|
||||
xhr.headers.addAll(metadata);
|
||||
|
||||
var genericTransportInterface = {
|
||||
xhr: xhr,
|
||||
|
@ -89,18 +94,28 @@ GrpcWebClientBase.prototype.rpcCall = function(
|
|||
}
|
||||
});
|
||||
|
||||
xhr.headers.addAll(metadata);
|
||||
if (this.format_ == "text") {
|
||||
xhr.headers.set('Content-Type', 'application/grpc-web-text');
|
||||
xhr.headers.set('X-User-Agent', 'grpc-web-javascript/0.1');
|
||||
xhr.headers.set('Accept', 'application/grpc-web-text');
|
||||
|
||||
var payload = this.encodeRequest_(serialized);
|
||||
payload = googCrypt.encodeByteArray(payload);
|
||||
|
||||
} else {
|
||||
xhr.headers.set('Content-Type', 'application/grpc-web+proto');
|
||||
}
|
||||
xhr.headers.set('X-User-Agent', 'grpc-web-javascript/0.1');
|
||||
xhr.headers.set('X-Grpc-Web', '1');
|
||||
if (this.suppressCorsPreflight_) {
|
||||
var headerObject = xhr.headers.toObject();
|
||||
xhr.headers.clear();
|
||||
method = GrpcWebClientBase.setCorsOverride_(method, headerObject);
|
||||
}
|
||||
|
||||
var serialized = methodInfo.requestSerializeFn(request);
|
||||
var payload = this.encodeRequest_(serialized);
|
||||
if (this.format_ == "text") {
|
||||
payload = googCrypt.encodeByteArray(payload);
|
||||
} else if (this.format_ == "binary") {
|
||||
xhr.setResponseType(XhrIo.ResponseType.ARRAY_BUFFER);
|
||||
}
|
||||
xhr.send(method, 'POST', payload);
|
||||
return;
|
||||
};
|
||||
|
@ -112,8 +127,6 @@ GrpcWebClientBase.prototype.rpcCall = function(
|
|||
GrpcWebClientBase.prototype.serverStreaming = function(
|
||||
method, request, metadata, methodInfo) {
|
||||
var xhr = this.newXhr_();
|
||||
var serialized = methodInfo.requestSerializeFn(request);
|
||||
xhr.headers.addAll(metadata);
|
||||
|
||||
var genericTransportInterface = {
|
||||
xhr: xhr,
|
||||
|
@ -121,18 +134,28 @@ GrpcWebClientBase.prototype.serverStreaming = function(
|
|||
var stream = new GrpcWebClientReadableStream(genericTransportInterface);
|
||||
stream.setResponseDeserializeFn(methodInfo.responseDeserializeFn);
|
||||
|
||||
xhr.headers.addAll(metadata);
|
||||
if (this.format_ == "text") {
|
||||
xhr.headers.set('Content-Type', 'application/grpc-web-text');
|
||||
xhr.headers.set('X-User-Agent', 'grpc-web-javascript/0.1');
|
||||
xhr.headers.set('Accept', 'application/grpc-web-text');
|
||||
|
||||
var payload = this.encodeRequest_(serialized);
|
||||
payload = googCrypt.encodeByteArray(payload);
|
||||
|
||||
} else {
|
||||
xhr.headers.set('Content-Type', 'application/grpc-web+proto');
|
||||
}
|
||||
xhr.headers.set('X-User-Agent', 'grpc-web-javascript/0.1');
|
||||
xhr.headers.set('X-Grpc-Web', '1');
|
||||
if (this.suppressCorsPreflight_) {
|
||||
var headerObject = xhr.headers.toObject();
|
||||
xhr.headers.clear();
|
||||
method = GrpcWebClientBase.setCorsOverride_(method, headerObject);
|
||||
}
|
||||
|
||||
var serialized = methodInfo.requestSerializeFn(request);
|
||||
var payload = this.encodeRequest_(serialized);
|
||||
if (this.format_ == "text") {
|
||||
payload = googCrypt.encodeByteArray(payload);
|
||||
} else if (this.format_ == "binary") {
|
||||
xhr.setResponseType(XhrIo.ResponseType.ARRAY_BUFFER);
|
||||
}
|
||||
xhr.send(method, 'POST', payload);
|
||||
|
||||
return stream;
|
||||
|
|
|
@ -40,6 +40,7 @@ const XhrIo = goog.require('goog.net.XhrIo');
|
|||
const XmlHttp = goog.require('goog.net.XmlHttp');
|
||||
const events = goog.require('goog.events');
|
||||
const googCrypt = goog.require('goog.crypt.base64');
|
||||
const googString = goog.require('goog.string');
|
||||
const {GenericTransportInterface} = goog.require('grpc.web.GenericTransportInterface');
|
||||
const {Status} = goog.require('grpc.web.Status');
|
||||
|
||||
|
@ -114,18 +115,26 @@ const GrpcWebClientReadableStream = function(genericTransportInterface) {
|
|||
var self = this;
|
||||
events.listen(this.xhr_, EventType.READY_STATE_CHANGE,
|
||||
function(e) {
|
||||
var FrameType = GrpcWebStreamParser.FrameType;
|
||||
var contentType = self.xhr_.getStreamingResponseHeader('Content-Type');
|
||||
if (!contentType) return;
|
||||
contentType = contentType.toLowerCase();
|
||||
|
||||
if (googString.startsWith(contentType, 'application/grpc-web-text')) {
|
||||
var responseText = self.xhr_.getResponseText();
|
||||
var newPos = responseText.length - responseText.length % 4;
|
||||
var newData = responseText.substr(self.pos_, newPos - self.pos_);
|
||||
if (newData.length == 0) return;
|
||||
self.pos_ = newPos;
|
||||
|
||||
var byteSource = googCrypt.decodeStringToUint8Array(newData);
|
||||
} else if (googString.startsWith(contentType, 'application/grpc')) {
|
||||
var byteSource = new Uint8Array(self.xhr_.getResponse());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
var messages = self.parser_.parse([].slice.call(byteSource));
|
||||
if (!messages) return;
|
||||
|
||||
var FrameType = GrpcWebStreamParser.FrameType;
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (FrameType.DATA in messages[i]) {
|
||||
var data = messages[i][FrameType.DATA];
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# 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 grpc-web:prereqs
|
||||
|
||||
ARG EXAMPLE_DIR=/github/grpc-web/net/grpc/gateway/examples/echo
|
||||
|
||||
RUN cd /github/grpc-web/packages/grpc-web && \
|
||||
rm -rf node_modules && \
|
||||
npm install && \
|
||||
npm run build && \
|
||||
npm link
|
||||
|
||||
RUN protoc -I=$EXAMPLE_DIR echo.proto \
|
||||
--plugin=protoc-gen-grpc-web=\
|
||||
/github/grpc-web/javascript/net/grpc/web/protoc-gen-grpc-web \
|
||||
--js_out=import_style=commonjs:\
|
||||
$EXAMPLE_DIR/commonjs-example \
|
||||
--grpc-web_out=import_style=commonjs,mode=grpcweb,out=echo_grpc_pb.js:\
|
||||
$EXAMPLE_DIR/commonjs-example
|
||||
|
||||
RUN cd $EXAMPLE_DIR/commonjs-example && \
|
||||
rm -rf node_modules && \
|
||||
npm install && \
|
||||
npm link grpc-web && \
|
||||
./node_modules/.bin/browserify client.js > out.js
|
||||
|
||||
EXPOSE 8081
|
||||
CMD ["nginx"]
|
|
@ -16,17 +16,24 @@ FROM grpc-web:prereqs
|
|||
|
||||
ARG EXAMPLE_DIR=/github/grpc-web/net/grpc/gateway/examples/echo
|
||||
|
||||
RUN cd /github/grpc-web/packages/grpc-web && \
|
||||
rm -rf node_modules && \
|
||||
npm install && \
|
||||
npm run build && \
|
||||
npm link
|
||||
|
||||
RUN protoc -I=$EXAMPLE_DIR echo.proto \
|
||||
--plugin=protoc-gen-grpc-web=\
|
||||
/github/grpc-web/javascript/net/grpc/web/protoc-gen-grpc-web \
|
||||
--js_out=import_style=commonjs:\
|
||||
$EXAMPLE_DIR/commonjs-example \
|
||||
--grpc-web_out=import_style=commonjs,mode=grpcweb,out=echo_grpc_pb.js:\
|
||||
--grpc-web_out=import_style=commonjs,mode=grpcwebtext,out=echo_grpc_pb.js:\
|
||||
$EXAMPLE_DIR/commonjs-example
|
||||
|
||||
RUN cd $EXAMPLE_DIR/commonjs-example && \
|
||||
rm -rf node_modules && \
|
||||
npm install && \
|
||||
npm link grpc-web && \
|
||||
./node_modules/.bin/browserify client.js > out.js
|
||||
|
||||
EXPOSE 8081
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
FROM golang:alpine
|
||||
|
||||
RUN apk add --no-cache git ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN go get -v -u github.com/golang/dep/cmd/dep
|
||||
RUN go get -v github.com/improbable-eng/grpc-web/go/grpcwebproxy ; exit 0
|
||||
RUN cd src/github.com/improbable-eng/grpc-web && dep ensure
|
||||
RUN go get -v -u github.com/improbable-eng/grpc-web/go/grpcwebproxy
|
||||
|
||||
ADD ./etc/localhost.crt /etc
|
||||
ADD ./etc/localhost.key /etc
|
||||
|
||||
ENTRYPOINT [ "/bin/sh", "-c", "exec /go/bin/grpcwebproxy \
|
||||
--backend_addr=echo-server:9090 \
|
||||
--server_bind_address=0.0.0.0 \
|
||||
--server_http_debug_port=8080 \
|
||||
--run_http_server=true \
|
||||
--server_tls_cert_file=/etc/localhost.crt \
|
||||
--server_tls_key_file=/etc/localhost.key " ]
|
|
@ -0,0 +1,21 @@
|
|||
# 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 grpc-web:prereqs
|
||||
|
||||
RUN cd /github/grpc-web && \
|
||||
make standalone-proxy
|
||||
|
||||
EXPOSE 8080
|
||||
CMD ["/github/grpc-web/gConnector/nginx.sh"]
|
|
@ -25,6 +25,7 @@ RUN apt-get update && apt-get install -y \
|
|||
default-jdk \
|
||||
default-jre \
|
||||
libtool \
|
||||
libpcre3-dev \
|
||||
libssl-dev \
|
||||
make \
|
||||
nginx \
|
||||
|
@ -33,9 +34,11 @@ RUN apt-get update && apt-get install -y \
|
|||
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
|
||||
apt-get install -y nodejs
|
||||
|
||||
RUN git clone https://github.com/grpc/grpc-web /github/grpc-web
|
||||
COPY . /github/grpc-web
|
||||
|
||||
RUN cd /github/grpc-web && \
|
||||
rm -rf third_party && \
|
||||
git checkout third_party && \
|
||||
./scripts/init_submodules.sh
|
||||
|
||||
RUN cd /github/grpc-web/third_party/grpc && \
|
||||
|
|
|
@ -41,6 +41,11 @@ package:
|
|||
cp run_example.sh $(ROOT_DIR)/gConnector
|
||||
zip -r $(ROOT_DIR)/gConnector.zip $(ROOT_DIR)/gConnector/*
|
||||
|
||||
standalone-proxy:
|
||||
mkdir -p $(ROOT_DIR)/gConnector/$(EXAMPLES_PATH)
|
||||
cp nginx.conf $(ROOT_DIR)/gConnector/conf
|
||||
zip -r $(ROOT_DIR)/gConnector.zip $(ROOT_DIR)/gConnector/*
|
||||
|
||||
echo_server: echo.pb.o echo.grpc.pb.o echo_server.o echo_service_impl.o
|
||||
$(CXX) $^ $(LDFLAGS) -o $@
|
||||
|
||||
|
@ -86,7 +91,7 @@ proto-js:
|
|||
$(PROTOS_PATH)/protos/pair.proto
|
||||
$(PROTOC) -I=. --js_out=$(JS_IMPORT_STYLE):$(OUT_DIR) ./echo.proto
|
||||
$(PROTOC) -I=. --plugin=protoc-gen-grpc-web=$(GRPC_WEB_PLUGIN_PATH) \
|
||||
--grpc-web_out=out=$(OUT_DIR)/echo.grpc.pb.js,mode=grpcweb:. ./echo.proto
|
||||
--grpc-web_out=out=$(OUT_DIR)/echo.grpc.pb.js,mode=grpcwebtext:. ./echo.proto
|
||||
|
||||
install:
|
||||
mkdir -p $(HTML_DIR)/$(EXAMPLES_PATH)
|
||||
|
|
|
@ -21,11 +21,11 @@ http {
|
|||
root /var/www/html;
|
||||
}
|
||||
location / {
|
||||
grpc_pass localhost:9090;
|
||||
grpc_pass echo-server:9090;
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web';
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
|
@ -34,7 +34,7 @@ http {
|
|||
if ($request_method = 'POST') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Transfer-Encoding,Custom-Header-1,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Transfer-Encoding';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,13 +99,13 @@ To generate the client stub JS file, now run this command:
|
|||
|
||||
```sh
|
||||
$ protoc -I=. --plugin=protoc-gen-grpc-web=<path to plugin> \
|
||||
--grpc-web_out=out=echo.grpc.pb.js,mode=grpcweb:. ./echo.proto
|
||||
--grpc-web_out=out=echo.grpc.pb.js,mode=grpcwebtext:. ./echo.proto
|
||||
```
|
||||
|
||||
The format for the `--grpc-web_out` param is
|
||||
|
||||
```sh
|
||||
--grpc-web_out=out=<filename>,mode=grpcweb:<output dir>
|
||||
--grpc-web_out=out=<filename>,mode=grpcwebtext:<output dir>
|
||||
```
|
||||
|
||||
Our command generates the client stub in the file `echo.grpc.pb.js`.
|
||||
|
|
|
@ -38,7 +38,7 @@ This example is using the `echo.proto` file from the [Echo Example](https://gith
|
|||
2. Generate your client with `protoc` and the `protoc-gen-grpc-web` plugin. Make sure you set the import_style for both `js_out` and `grpc-web_out` to **commonjs**. It is also important that both your js and grpc-web output to the same directory.
|
||||
|
||||
```shell
|
||||
protoc echo.proto --js_out=import_style=commonjs:generated --grpc-web_out=import_style=commonjs,mode=grpcweb,out=echo_grpc_pb.js:generated
|
||||
protoc echo.proto --js_out=import_style=commonjs:generated --grpc-web_out=import_style=commonjs,mode=grpcwebtext,out=echo_grpc_pb.js:generated
|
||||
```
|
||||
|
||||
3. Start using your generated client!
|
||||
|
|
Loading…
Reference in New Issue