Cách đưa một API do gRPC xác định vào trình duyệt web


78

Chúng tôi muốn xây dựng một gui Javascript / HTML cho gRPC-microservices của chúng tôi. Vì gRPC không được hỗ trợ ở phía trình duyệt, chúng tôi đã nghĩ đến việc sử dụng web-socket để kết nối với máy chủ node.js, máy chủ này gọi dịch vụ mục tiêu qua grpc. Chúng tôi đấu tranh để tìm ra một giải pháp thanh lịch để làm điều này. Đặc biệt, vì chúng tôi sử dụng các luồng gRPC để đẩy các sự kiện giữa các dịch vụ vi mô của chúng tôi. Có vẻ như chúng ta cần một hệ thống RPC thứ hai, chỉ để giao tiếp giữa giao diện người dùng và máy chủ node.js. Điều này dường như là rất nhiều chi phí và mã bổ sung phải được duy trì.

Có ai có kinh nghiệm làm điều gì đó như thế này hoặc có một ý tưởng làm thế nào điều này có thể được giải quyết?


Kiểm tra Wildcard API , một công cụ nhỏ cho phép bạn dễ dàng tạo một RPC API giữa giao diện người dùng và máy chủ Node.js của bạn. Nó giống như gRPC nhưng đơn giản hơn và dễ sử dụng hơn nhiều. Tiết lộ: Tôi là tác giả.
brillout

Câu trả lời:


40

Chỉnh sửa: Kể từ ngày 23 tháng 10 năm 2018, dự án gRPC-Web là GA , đây có thể là cách chính thức / tiêu chuẩn nhất để giải quyết vấn đề của bạn. (Ngay cả khi bây giờ đã là 2018 ...;))

Từ GA-Blog: "gRPC-Web, giống như gRPC, cho phép bạn xác định" hợp đồng "dịch vụ giữa các dịch vụ gRPC ứng dụng khách (web) và phụ trợ bằng cách sử dụng Bộ đệm giao thức. Sau đó, ứng dụng khách có thể được tạo tự động. [...]"

Gần đây, chúng tôi đã xây dựng gRPC-Web ( https://github.com/improbable-eng/grpc-web ) - một trình bao bọc máy khách và máy chủ trình duyệt tuân theo giao thức gRPC-Web được đề xuất. Ví dụ trong repo đó nên cung cấp một điểm khởi đầu tốt.

Nó yêu cầu proxy độc lập hoặc trình bao bọc cho máy chủ gRPC của bạn nếu bạn đang sử dụng Golang. Proxy / wrapper sửa đổi phản hồi để đóng gói các đoạn giới thiệu trong nội dung phản hồi để trình duyệt có thể đọc chúng.

Tiết lộ: Tôi là người bảo trì dự án.


4
Tính năng sát thủ bây giờ sẽ là khả năng tạo trang sân chơi HTML cho bất kỳ tệp proto nào tương tự như trang được thực hiện cho swagger. Bằng cách đó, bất kỳ dịch vụ gRPC nào cũng có thể được kiểm tra thông qua trình duyệt một cách dễ dàng.
Setheron

1
@Marcus, bạn nói nó tuân theo "Giao thức gRPC-Web được đề xuất". Đó có phải là cùng một giao thức được sử dụng bởi triển khai github.com/grpc/grpc-web chính thức (gần đây đã được công khai) và do đó, những triển khai này có tương thích không? Hay bạn đang đề cập đến giao thức được đề xuất của riêng bạn?
Matthijs Kooijman

@Setheron bạn có thể cho tôi liên kết đến ví dụ hoặc mô tả về tính năng giết người tương tự này không? Tôi chưa thể tìm thấy nó :( Tôi có ứng dụng gRPC-Web (node.js) với các thông báo nhị phân (base64) và Envoy Proxy như tại các tài liệu chính thức và tôi muốn có công cụ giống như swagger để kiểm tra ứng dụng của mình
razon

Dự án này có thể được kết nối với wordpress (php) không?
Raju yourPepe

16

Thật không may, vẫn chưa có câu trả lời nào tốt cho bạn.

Hỗ trợ phát trực tuyến RPC từ trình duyệt hoàn toàn yêu cầu các đoạn giới thiệu HTTP2 được trình duyệt hỗ trợ và tại thời điểm viết câu trả lời này, chúng không được như vậy.

Xem vấn đề này để thảo luận về chủ đề.

Nếu không, có, bạn sẽ yêu cầu một hệ thống dịch đầy đủ giữa WebSockets và gRPC. Có thể lấy cảm hứng từ grpc-gateway có thể là bước khởi đầu của một dự án như vậy, nhưng đó vẫn còn là một bước dài.


Cảm ơn câu trả lời của bạn! Tôi đã đọc về sự cố với đoạn giới thiệu http. Thậm chí còn có một bản vá mà ai đó đã làm để có thể sử dụng grpc trong trình duyệt mà không cần tính năng phát trực tuyến. Dự án grpc-gateway là một gợi ý hữu ích. Chúng tôi có thể đang thực hiện một cổng vào với dnode ngay bây giờ ...
Oliver

1
Có, nếu bạn quên phát trực tuyến, thì grpc từ trình duyệt là hoàn toàn có thể.
Nicolas Noble

@NicolasNoble - thật tuyệt. Có ví dụ về cuộc gọi gRPC không trực tuyến từ trình duyệt không?
AlikElzin-kilaka

Chưa hết tiếc. Tôi đang nói về mặt lý thuyết. Nhưng những thay đổi phải ở mức tối thiểu.
Nicolas Noble

1
Chúng tôi đang thu thập tên của những người quan tâm đến chương trình truy cập sớm tại đây . Vui lòng thêm tên của bạn vào đó và chúng tôi sẽ chia sẻ những gì chúng tôi có ngay sau đó.
Nicolas Noble,

10

Triển khai grpc-web (beta) chính thức đã được phát hành vào ngày 23/03/2018. Bạn có thể tìm thấy nó tại

https://github.com/grpc/grpc-web

Các hướng dẫn sau được lấy từ README:

Xác định dịch vụ gRPC của bạn:

service EchoService {
  rpc Echo(EchoRequest) returns (EchoResponse);

  rpc ServerStreamingEcho(ServerStreamingEchoRequest)
      returns (stream ServerStreamingEchoResponse);
}

Xây dựng máy chủ bằng bất kỳ ngôn ngữ nào bạn muốn.

Tạo ứng dụng khách JS của bạn để thực hiện cuộc gọi từ trình duyệt:

var echoService = new proto.grpc.gateway.testing.EchoServiceClient(
  'http://localhost:8080');

Thực hiện cuộc gọi RPC một lần

var unaryRequest = new proto.grpc.gateway.testing.EchoRequest();
unaryRequest.setMessage(msg);
echoService.echo(unaryRequest, {},
  function(err, response) {
    console.log(response.getMessage());
  });

Các luồng từ máy chủ đến trình duyệt được hỗ trợ:

var stream = echoService.serverStreamingEcho(streamRequest, {});
stream.on('data', function(response) {
  console.log(response.getMessage());
});

Luồng hai chiều KHÔNG được hỗ trợ:

Đây là một công việc đang được tiến hành và trên lộ trình grpc-web . Mặc dù có một ví dụ protobuf hiển thị phát trực tuyến bidi, nhận xét này làm rõ rằng ví dụ này thực sự chưa hoạt động.

Hy vọng rằng điều này sẽ sớm thay đổi. :)


1
Bạn có chắc chắn hỗ trợ luồng hai chiều không? Ví dụ hai chiều của bạn dường như chỉ hiển thị phát trực tuyến máy chủ, trong khi ví dụ phát trực tuyến máy chủ của bạn chỉ hiển thị yêu cầu một lần mà không có bất kỳ luồng nào. README cũng chỉ đề cập đến tính năng phát trực tuyến máy chủ, điều này khiến tôi nghi ngờ tính năng phát trực tuyến máy khách hoặc hai chiều không được hỗ trợ. Bạn có thể làm rõ?
Matthijs Kooijman

2
@MatthijsKooijman dụ tiếng vang của họ hiển thị cả khách hàng và full duplex luồng: github.com/grpc/grpc-web/blob/master/net/grpc/gateway/examples/...
Cody A. Ray

1
Có vẻ như ví dụ đó chỉ để tham khảo trong tương lai, nó không thực sự được hỗ trợ. Xem thêm github.com/grpc/grpc-web/issues/24#issuecomment-303285538 nêu rõ điều này về ví dụ.
Matthijs Kooijman

1
@MatthijsKooijman có vẻ như bạn nói đúng. Tôi đã cập nhật câu trả lời của mình để phản ánh điều này (và bao gồm một liên kết đến lộ trình và nhận xét). Cảm ơn!
Cody A. Ray

1
bây giờ bạn đã xóa ví dụ về máy chủ phát trực tuyến khỏi câu trả lời của mình (mà trước đây bạn đã gắn nhãn sai là phát trực tuyến hai chiều).
Matthijs Kooijman



3

GRPC Bus WebSocket Proxy thực hiện chính xác điều này bằng cách ủy quyền tất cả các lệnh gọi GRPC qua kết nối WebSocket để cung cấp cho bạn thứ gì đó trông rất giống với API Node GRPC trong trình duyệt. Không giống như GRPC-Gateway, nó hoạt động với cả yêu cầu phát trực tuyến và phản hồi phát trực tuyến, cũng như các cuộc gọi không phát trực tuyến.

Có cả thành phần máy chủ và máy khách. Máy chủ GRPC Bus WebSocket Proxy có thể được chạy với Docker bằng cáchdocker run gabrielgrant/grpc-bus-websocket-proxy

Về phía trình duyệt, bạn sẽ cần cài đặt ứng dụng khách GRPC Bus WebSocket Proxy vớinpm install grpc-bus-websocket-client

và sau đó tạo một đối tượng GBC mới với: new GBC(<grpc-bus-websocket-proxy address>, <protofile-url>, <service map>)

Ví dụ:

var GBC = require("grpc-bus-websocket-client");

new GBC("ws://localhost:8080/", 'helloworld.proto', {helloworld: {Greeter: 'localhost:50051'}})
  .connect()
  .then(function(gbc) {
    gbc.services.helloworld.Greeter.sayHello({name: 'Gabriel'}, function(err, res){
      console.log(res);
    });  // --> Hello Gabriel
  });

Thư viện khách hàng mong đợi có thể tải xuống .prototệp với yêu cầu AJAX. Các service-mapcung cấp các URL của các dịch vụ khác nhau được xác định trong tập tin proto như thể hiện bởi các máy chủ proxy.

Để biết thêm chi tiết, hãy xem máy khách GRPC Bus WebSocket Proxy README


2

Tôi thấy nhiều câu trả lời không hướng đến giải pháp hai chiều trên WebSocket, vì OP đã yêu cầu hỗ trợ trình duyệt.

Bạn có thể sử dụng JSON-RPC thay vì gRPC, để nhận RPC hai chiều qua WebSocket , hỗ trợ nhiều hơn nữa, bao gồm cả WebRTC (trình duyệt cho trình duyệt).

Tôi đoán nó có thể được sửa đổi để hỗ trợ gRPC nếu bạn thực sự cần loại tuần tự hóa này.

Tuy nhiên, đối với tab trình duyệt đến tab trình duyệt, các đối tượng yêu cầu không được tuần tự hóa và được chuyển giao nguyên bản, và tương tự với các công nhân chuỗi hoặc cụm NodeJS, mang lại hiệu suất cao hơn rất nhiều.

Ngoài ra, bạn có thể chuyển "con trỏ" sang SharedArrayBuffer, thay vì tuần tự hóa thông qua định dạng gRPC.

Tuần tự hóa JSON và deserialization trong V8 cũng không thể đánh bại.

https://github.com/bigstepinc/jsonrpc-bidirectional


0

Xem xét các giải pháp hiện tại với gRPC qua web, đây là những gì có sẵn tại thời điểm viết bài này (và những gì tôi tìm thấy):

  • gRPC-web : yêu cầu TypeScript cho máy khách
  • gRPC-web-proxy : yêu cầu Go
  • gRPC-gateway : yêu cầu sửa đổi .proto và trang trí
  • gRPC-bus-websocket-proxy-server : khi viết tài liệu này, nó thiếu các bài kiểm tra và có vẻ như bị bỏ rơi (chỉnh sửa: hãy xem các nhận xét của tác giả gốc!)
  • gRPC-dynamic-gateway : một chút quá mức cần thiết cho các dịch vụ gRPC đơn giản và xác thực rất khó xử
  • gRPC-bus : yêu cầu thứ gì đó để vận chuyển

Tôi cũng muốn cắm giải pháp của riêng mình mà tôi đã viết cho công ty của mình và nó đang được sử dụng trong quá trình sản xuất để gửi các yêu cầu proxy đến dịch vụ gRPC chỉ bao gồm các cuộc gọi trực tuyến máy chủ và một lần:

Mỗi inch của mã đều được bao phủ bởi các bài kiểm tra. Đây là phần mềm trung gian Express nên không cần sửa đổi bổ sung đối với thiết lập gRPC của bạn. Bạn cũng có thể ủy quyền xác thực HTTP cho Express (ví dụ: với Passport).


Chào! grpc-express trông thật tuyệt, đặc biệt. dành cho những người sử dụng Express, những người không cần phát trực tuyến từ ứng dụng khách. Tôi tò mò bạn muốn thử nghiệm bổ sung nào cho gRPC-bus-websocket-proxy-server ? Đó là một lớp bao bọc / vận chuyển khá mỏng cho grpc-bus (được kiểm tra đơn vị khá tốt), vì vậy tôi không nghĩ rằng việc sao chép chúng thực sự có ý nghĩa và "demo" thực sự là bài kiểm tra chấp nhận. Trong mọi trường hợp, chúng tôi đang tích cực sử dụng nó trong người không biết nhục , nó chỉ chưa cần phải được cập nhật nhiều thời gian gần đây vì nó chủ yếu chỉ hoạt động :)
Gabriel Grant
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.