0

grpc-web を使用してバックエンド grpc サービスからブラウザーにサンプル ビデオ ファイルを送信したいのですが、公式の hello world tutorialに基づいていくつかの調整を行いました。ところで、envoy の設定は何も変わっていません。ビデオ ファイルは 17 個のチャンクに分割されています。ブラウザで 17 個のメッセージを受信できますが、中には何もありません。データを取得するにはどうすればよいですか?

プロトブフの定義:

syntax = "proto3";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (stream HelloReply);
}

message HelloRequest {}

message HelloReply {
  bytes message = 1;
}

サーバー.js:

var PROTO_PATH = __dirname + '/helloworld.proto';

var grpc = require('grpc');
var fs = require('fs');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
    PROTO_PATH,
    {keepCase: true,
     longs: String,
     enums: String,
     defaults: true,
     oneofs: true
    });
var protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
var helloworld = protoDescriptor.helloworld;

function doSayHello(call) {
  let count = 0;
  let videoDataStream = fs.createReadStream('./sample.mp4');
  videoDataStream.on('data',function(chunk){
      console.log(chunk);
      console.log(++count);
      call.write({videoStream: chunk});
//      call.write(chunk);
  }).on('end',function(){
      call.end();
  });
}

function getServer() {
  var server = new grpc.Server();
  server.addService(helloworld.Greeter.service, {
    sayHello: doSayHello,
  });
  return server;
}

if (require.main === module) {
  var server = getServer();
  server.bind('0.0.0.0:9090', grpc.ServerCredentials.createInsecure());
  server.start();
}

exports.getServer = getServer;

client.js:

const {HelloRequest, HelloReply} = require('./helloworld_pb.js');
const {GreeterClient} = require('./helloworld_grpc_web_pb.js');

var client = new GreeterClient('http://localhost:8080');

var request = new HelloRequest();

client.sayHello(request).on('data', function(chunk){
  //console.log(chunk.getMessage());
  console.log(chunk);
});

とにかく、プロキシに問題がある場合に備えて、以下は私の envoy.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
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route:
                  cluster: greeter_service
                  max_grpc_timeout: 0s
              cors:
                allow_origin_string_match:
                - prefix: "*"
                allow_methods: GET, PUT, DELETE, POST, OPTIONS
                allow_headers: keep-alive,user-agent,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,grpc-timeout
                max_age: "1728000"
                expose_headers: custom-header-1,grpc-status,grpc-message
          http_filters:
          - name: envoy.grpc_web
          - name: envoy.cors
          - name: envoy.router
  clusters:
  - name: greeter_service
    connect_timeout: 0.25s
    type: logical_dns
    http2_protocol_options: {}
    lb_policy: round_robin
    hosts: [{ socket_address: { address: host.docker.internal, port_value: 9090 }}]

サーバー側に記録されたバイト: ここに画像の説明を入力

およびブラウザのコンソール出力の下: ここに画像の説明を入力

4

1 に答える 1