mirror of https://github.com/grpc/grpc-dart.git
Revert "Support grpc-web" (#159)
This reverts commit d58659507c
.
Development of grpc-web will continue on the branch
https://github.com/grpc/grpc-dart/tree/grpc-web until it is ready.
This commit is contained in:
parent
d58659507c
commit
d7ae930e7f
|
@ -2,7 +2,6 @@
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.packages
|
.packages
|
||||||
.pub/
|
.pub/
|
||||||
.vscode/
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
# Remove the following pattern if you wish to check in your lock file
|
# Remove the following pattern if you wish to check in your lock file
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
language: dart
|
language: dart
|
||||||
|
sudo: false
|
||||||
|
|
||||||
# necessary to avoid chrome sandboxing issues
|
# Run against both the dev and channel.
|
||||||
sudo: required
|
|
||||||
addons:
|
|
||||||
chrome: stable
|
|
||||||
|
|
||||||
# Run against both the dev and stable channel.
|
|
||||||
dart:
|
dart:
|
||||||
- stable
|
- stable
|
||||||
- dev
|
- dev
|
||||||
|
@ -13,7 +9,6 @@ dart:
|
||||||
# Define test tasks to run.
|
# Define test tasks to run.
|
||||||
dart_task:
|
dart_task:
|
||||||
- test: --platform vm
|
- test: --platform vm
|
||||||
- test: --platform chrome
|
|
||||||
|
|
||||||
# Only run one instance of the formatter and the analyzer, rather than running
|
# Only run one instance of the formatter and the analyzer, rather than running
|
||||||
# them against each Dart version.
|
# them against each Dart version.
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
## 1.1.0
|
|
||||||
|
|
||||||
* Add initial support for grpc-web.
|
|
||||||
See `example/grpc-web` for an example of this working.
|
|
||||||
|
|
||||||
## 1.0.1
|
## 1.0.1
|
||||||
|
|
||||||
* Add `service_api.dart` that only contains the minimal imports needed by the code generated by
|
* Add `service_api.dart` that only contains the minimal imports needed by the code generated by
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
targets:
|
|
||||||
$default:
|
|
||||||
sources:
|
|
||||||
exclude:
|
|
||||||
- example/**
|
|
|
@ -1,62 +0,0 @@
|
||||||
# Description
|
|
||||||
The grpc-web example shows how to use the Dart gRPC library with a gRPC-Web capable server.
|
|
||||||
|
|
||||||
This is meant to be used with the echo example provided by the grpc-web repository. The definition of the service is given in echo.proto.
|
|
||||||
|
|
||||||
# Prerequistes
|
|
||||||
You will need a clone of the [grpc-web](https://github.com/grpc/grpc-web) repository to run the example server.
|
|
||||||
|
|
||||||
You will also need the dart 'webdev' tool, which you can get by running:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ pub global activate webdev
|
|
||||||
```
|
|
||||||
|
|
||||||
# Run the sample code
|
|
||||||
Follow the instructions for starting the grpc-web example server. The simplest version of this involves running the grpc-web server in a docker container with:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ docker-compose up echo-server envoy
|
|
||||||
```
|
|
||||||
|
|
||||||
To compile and run the example, assuming you are in the root of the grpc-web
|
|
||||||
folder, i.e., .../example/grpc-web/, first get the dependencies by running:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ pub get
|
|
||||||
```
|
|
||||||
|
|
||||||
Compile and run the website with:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ webdev serve web:9000
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the alternate port (9000) is necessary because the grpc-web server runs the grpc server on port 8080 by default (the save as webdev).
|
|
||||||
|
|
||||||
You can then navigate to http://localhost:9000/ to try out the example.
|
|
||||||
|
|
||||||
# Regenerate the stubs
|
|
||||||
|
|
||||||
If you have made changes to the message or service definition in
|
|
||||||
`protos/echo.proto` and need to regenerate the corresponding Dart files,
|
|
||||||
you will need to have protoc version 3.0.0 or higher and the Dart protoc plugin
|
|
||||||
version 16.0.0 or higher on your PATH.
|
|
||||||
|
|
||||||
To install protoc, see the instructions on
|
|
||||||
[the Protocol Buffers website](https://developers.google.com/protocol-buffers/).
|
|
||||||
|
|
||||||
The easiest way to get the Dart protoc plugin is by running
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ pub global activate protoc_plugin
|
|
||||||
```
|
|
||||||
|
|
||||||
and follow the directions to add `~/.pub-cache/bin` to your PATH, if you haven't
|
|
||||||
already done so.
|
|
||||||
|
|
||||||
You can now regenerate the Dart files by running
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ protoc --dart_out=grpc:lib/src/generated -Iprotos protos/echo.proto
|
|
||||||
```
|
|
|
@ -1,47 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:html';
|
|
||||||
|
|
||||||
import 'package:grpc_web/src/generated/echo.pbgrpc.dart';
|
|
||||||
|
|
||||||
class EchoApp {
|
|
||||||
final EchoServiceClient _service;
|
|
||||||
|
|
||||||
EchoApp(this._service);
|
|
||||||
|
|
||||||
Future<void> echo(String message) async {
|
|
||||||
_addLeftMessage(message);
|
|
||||||
|
|
||||||
final response = await _service.echo(new EchoRequest()..message = message);
|
|
||||||
_addRightMessage(response.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void repeatEcho(String message, int count) {
|
|
||||||
_addLeftMessage(message);
|
|
||||||
final request = ServerStreamingEchoRequest()
|
|
||||||
..message = message
|
|
||||||
..messageCount = count
|
|
||||||
..messageInterval = 500;
|
|
||||||
_service.serverStreamingEcho(request).listen((response) {
|
|
||||||
_addRightMessage(response.message);
|
|
||||||
}, onDone: () => print('Closed connection to server.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _addLeftMessage(String message) {
|
|
||||||
_addMessage(message, "label-primary pull-left");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _addRightMessage(String message) {
|
|
||||||
_addMessage(message, "label-default pull-right");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _addMessage(String message, String cssClass) {
|
|
||||||
final classes = cssClass.split(' ');
|
|
||||||
querySelector('#first').after(DivElement()
|
|
||||||
..classes.add('row')
|
|
||||||
..append(Element.tag('h2')
|
|
||||||
..append(SpanElement()
|
|
||||||
..classes.add('label')
|
|
||||||
..classes.addAll(classes)
|
|
||||||
..text = message)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: echo.proto
|
|
||||||
///
|
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
|
||||||
|
|
||||||
// ignore: UNUSED_SHOWN_NAME
|
|
||||||
import 'dart:core' show int, bool, double, String, List, Map, override;
|
|
||||||
|
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
|
||||||
|
|
||||||
class EchoRequest extends $pb.GeneratedMessage {
|
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EchoRequest', package: const $pb.PackageName('grpc.gateway.testing'))
|
|
||||||
..aOS(1, 'message')
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
EchoRequest() : super();
|
|
||||||
EchoRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
|
||||||
EchoRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
|
||||||
EchoRequest clone() => new EchoRequest()..mergeFromMessage(this);
|
|
||||||
EchoRequest copyWith(void Function(EchoRequest) updates) => super.copyWith((message) => updates(message as EchoRequest));
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static EchoRequest create() => new EchoRequest();
|
|
||||||
EchoRequest createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<EchoRequest> createRepeated() => new $pb.PbList<EchoRequest>();
|
|
||||||
static EchoRequest getDefault() => _defaultInstance ??= create()..freeze();
|
|
||||||
static EchoRequest _defaultInstance;
|
|
||||||
static void $checkItem(EchoRequest v) {
|
|
||||||
if (v is! EchoRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
String get message => $_getS(0, '');
|
|
||||||
set message(String v) { $_setString(0, v); }
|
|
||||||
bool hasMessage() => $_has(0);
|
|
||||||
void clearMessage() => clearField(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class EchoResponse extends $pb.GeneratedMessage {
|
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EchoResponse', package: const $pb.PackageName('grpc.gateway.testing'))
|
|
||||||
..aOS(1, 'message')
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
EchoResponse() : super();
|
|
||||||
EchoResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
|
||||||
EchoResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
|
||||||
EchoResponse clone() => new EchoResponse()..mergeFromMessage(this);
|
|
||||||
EchoResponse copyWith(void Function(EchoResponse) updates) => super.copyWith((message) => updates(message as EchoResponse));
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static EchoResponse create() => new EchoResponse();
|
|
||||||
EchoResponse createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<EchoResponse> createRepeated() => new $pb.PbList<EchoResponse>();
|
|
||||||
static EchoResponse getDefault() => _defaultInstance ??= create()..freeze();
|
|
||||||
static EchoResponse _defaultInstance;
|
|
||||||
static void $checkItem(EchoResponse v) {
|
|
||||||
if (v is! EchoResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
String get message => $_getS(0, '');
|
|
||||||
set message(String v) { $_setString(0, v); }
|
|
||||||
bool hasMessage() => $_has(0);
|
|
||||||
void clearMessage() => clearField(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ServerStreamingEchoRequest extends $pb.GeneratedMessage {
|
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ServerStreamingEchoRequest', package: const $pb.PackageName('grpc.gateway.testing'))
|
|
||||||
..aOS(1, 'message')
|
|
||||||
..a<int>(2, 'messageCount', $pb.PbFieldType.O3)
|
|
||||||
..a<int>(3, 'messageInterval', $pb.PbFieldType.O3)
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
ServerStreamingEchoRequest() : super();
|
|
||||||
ServerStreamingEchoRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
|
||||||
ServerStreamingEchoRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
|
||||||
ServerStreamingEchoRequest clone() => new ServerStreamingEchoRequest()..mergeFromMessage(this);
|
|
||||||
ServerStreamingEchoRequest copyWith(void Function(ServerStreamingEchoRequest) updates) => super.copyWith((message) => updates(message as ServerStreamingEchoRequest));
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static ServerStreamingEchoRequest create() => new ServerStreamingEchoRequest();
|
|
||||||
ServerStreamingEchoRequest createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<ServerStreamingEchoRequest> createRepeated() => new $pb.PbList<ServerStreamingEchoRequest>();
|
|
||||||
static ServerStreamingEchoRequest getDefault() => _defaultInstance ??= create()..freeze();
|
|
||||||
static ServerStreamingEchoRequest _defaultInstance;
|
|
||||||
static void $checkItem(ServerStreamingEchoRequest v) {
|
|
||||||
if (v is! ServerStreamingEchoRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
String get message => $_getS(0, '');
|
|
||||||
set message(String v) { $_setString(0, v); }
|
|
||||||
bool hasMessage() => $_has(0);
|
|
||||||
void clearMessage() => clearField(1);
|
|
||||||
|
|
||||||
int get messageCount => $_get(1, 0);
|
|
||||||
set messageCount(int v) { $_setSignedInt32(1, v); }
|
|
||||||
bool hasMessageCount() => $_has(1);
|
|
||||||
void clearMessageCount() => clearField(2);
|
|
||||||
|
|
||||||
int get messageInterval => $_get(2, 0);
|
|
||||||
set messageInterval(int v) { $_setSignedInt32(2, v); }
|
|
||||||
bool hasMessageInterval() => $_has(2);
|
|
||||||
void clearMessageInterval() => clearField(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ServerStreamingEchoResponse extends $pb.GeneratedMessage {
|
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ServerStreamingEchoResponse', package: const $pb.PackageName('grpc.gateway.testing'))
|
|
||||||
..aOS(1, 'message')
|
|
||||||
..hasRequiredFields = false
|
|
||||||
;
|
|
||||||
|
|
||||||
ServerStreamingEchoResponse() : super();
|
|
||||||
ServerStreamingEchoResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
|
||||||
ServerStreamingEchoResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
|
||||||
ServerStreamingEchoResponse clone() => new ServerStreamingEchoResponse()..mergeFromMessage(this);
|
|
||||||
ServerStreamingEchoResponse copyWith(void Function(ServerStreamingEchoResponse) updates) => super.copyWith((message) => updates(message as ServerStreamingEchoResponse));
|
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static ServerStreamingEchoResponse create() => new ServerStreamingEchoResponse();
|
|
||||||
ServerStreamingEchoResponse createEmptyInstance() => create();
|
|
||||||
static $pb.PbList<ServerStreamingEchoResponse> createRepeated() => new $pb.PbList<ServerStreamingEchoResponse>();
|
|
||||||
static ServerStreamingEchoResponse getDefault() => _defaultInstance ??= create()..freeze();
|
|
||||||
static ServerStreamingEchoResponse _defaultInstance;
|
|
||||||
static void $checkItem(ServerStreamingEchoResponse v) {
|
|
||||||
if (v is! ServerStreamingEchoResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
String get message => $_getS(0, '');
|
|
||||||
set message(String v) { $_setString(0, v); }
|
|
||||||
bool hasMessage() => $_has(0);
|
|
||||||
void clearMessage() => clearField(1);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: echo.proto
|
|
||||||
///
|
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: echo.proto
|
|
||||||
///
|
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
|
||||||
|
|
||||||
import 'dart:async' as $async;
|
|
||||||
|
|
||||||
import 'package:grpc/service_api.dart' as $grpc;
|
|
||||||
import 'echo.pb.dart';
|
|
||||||
export 'echo.pb.dart';
|
|
||||||
|
|
||||||
class EchoServiceClient extends $grpc.Client {
|
|
||||||
static final _$echo = new $grpc.ClientMethod<EchoRequest, EchoResponse>(
|
|
||||||
'/grpc.gateway.testing.EchoService/Echo',
|
|
||||||
(EchoRequest value) => value.writeToBuffer(),
|
|
||||||
(List<int> value) => new EchoResponse.fromBuffer(value));
|
|
||||||
static final _$serverStreamingEcho = new $grpc.ClientMethod<
|
|
||||||
ServerStreamingEchoRequest, ServerStreamingEchoResponse>(
|
|
||||||
'/grpc.gateway.testing.EchoService/ServerStreamingEcho',
|
|
||||||
(ServerStreamingEchoRequest value) => value.writeToBuffer(),
|
|
||||||
(List<int> value) => new ServerStreamingEchoResponse.fromBuffer(value));
|
|
||||||
|
|
||||||
EchoServiceClient($grpc.ClientChannel channel, {$grpc.CallOptions options})
|
|
||||||
: super(channel, options: options);
|
|
||||||
|
|
||||||
$grpc.ResponseFuture<EchoResponse> echo(EchoRequest request,
|
|
||||||
{$grpc.CallOptions options}) {
|
|
||||||
final call = $createCall(_$echo, new $async.Stream.fromIterable([request]),
|
|
||||||
options: options);
|
|
||||||
return new $grpc.ResponseFuture(call);
|
|
||||||
}
|
|
||||||
|
|
||||||
$grpc.ResponseStream<ServerStreamingEchoResponse> serverStreamingEcho(
|
|
||||||
ServerStreamingEchoRequest request,
|
|
||||||
{$grpc.CallOptions options}) {
|
|
||||||
final call = $createCall(
|
|
||||||
_$serverStreamingEcho, new $async.Stream.fromIterable([request]),
|
|
||||||
options: options);
|
|
||||||
return new $grpc.ResponseStream(call);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class EchoServiceBase extends $grpc.Service {
|
|
||||||
String get $name => 'grpc.gateway.testing.EchoService';
|
|
||||||
|
|
||||||
EchoServiceBase() {
|
|
||||||
$addMethod(new $grpc.ServiceMethod<EchoRequest, EchoResponse>(
|
|
||||||
'Echo',
|
|
||||||
echo_Pre,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
(List<int> value) => new EchoRequest.fromBuffer(value),
|
|
||||||
(EchoResponse value) => value.writeToBuffer()));
|
|
||||||
$addMethod(new $grpc.ServiceMethod<ServerStreamingEchoRequest,
|
|
||||||
ServerStreamingEchoResponse>(
|
|
||||||
'ServerStreamingEcho',
|
|
||||||
serverStreamingEcho_Pre,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
(List<int> value) => new ServerStreamingEchoRequest.fromBuffer(value),
|
|
||||||
(ServerStreamingEchoResponse value) => value.writeToBuffer()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$async.Future<EchoResponse> echo_Pre(
|
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
|
||||||
return echo(call, await request);
|
|
||||||
}
|
|
||||||
|
|
||||||
$async.Stream<ServerStreamingEchoResponse> serverStreamingEcho_Pre(
|
|
||||||
$grpc.ServiceCall call, $async.Future request) async* {
|
|
||||||
yield* serverStreamingEcho(
|
|
||||||
call, (await request) as ServerStreamingEchoRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
$async.Future<EchoResponse> echo($grpc.ServiceCall call, EchoRequest request);
|
|
||||||
$async.Stream<ServerStreamingEchoResponse> serverStreamingEcho(
|
|
||||||
$grpc.ServiceCall call, ServerStreamingEchoRequest request);
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
///
|
|
||||||
// Generated code. Do not modify.
|
|
||||||
// source: echo.proto
|
|
||||||
///
|
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
|
||||||
|
|
||||||
const EchoRequest$json = const {
|
|
||||||
'1': 'EchoRequest',
|
|
||||||
'2': const [
|
|
||||||
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const EchoResponse$json = const {
|
|
||||||
'1': 'EchoResponse',
|
|
||||||
'2': const [
|
|
||||||
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const ServerStreamingEchoRequest$json = const {
|
|
||||||
'1': 'ServerStreamingEchoRequest',
|
|
||||||
'2': const [
|
|
||||||
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
|
|
||||||
const {'1': 'message_count', '3': 2, '4': 1, '5': 5, '10': 'messageCount'},
|
|
||||||
const {'1': 'message_interval', '3': 3, '4': 1, '5': 5, '10': 'messageInterval'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const ServerStreamingEchoResponse$json = const {
|
|
||||||
'1': 'ServerStreamingEchoResponse',
|
|
||||||
'2': const [
|
|
||||||
const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,41 +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.
|
|
||||||
|
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package grpc.gateway.testing;
|
|
||||||
|
|
||||||
message EchoRequest {
|
|
||||||
string message = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message EchoResponse {
|
|
||||||
string message = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ServerStreamingEchoRequest {
|
|
||||||
string message = 1;
|
|
||||||
int32 message_count = 2;
|
|
||||||
int32 message_interval = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ServerStreamingEchoResponse {
|
|
||||||
string message = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
service EchoService {
|
|
||||||
rpc Echo(EchoRequest) returns (EchoResponse);
|
|
||||||
rpc ServerStreamingEcho(ServerStreamingEchoRequest)
|
|
||||||
returns (stream ServerStreamingEchoResponse);
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
name: grpc_web
|
|
||||||
description: Dart gRPC-Web sample client
|
|
||||||
homepage: https://github.com/dart-lang/grpc-dart
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: '>=2.0.0 <3.0.0'
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
grpc:
|
|
||||||
path: ../../
|
|
||||||
protobuf: ^0.13.4
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
build_runner: ^0.10.0
|
|
||||||
build_web_compilers: '^0.4.1'
|
|
|
@ -1,42 +0,0 @@
|
||||||
<!--
|
|
||||||
Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
for details. All rights reserved.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Echo Example</title>
|
|
||||||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
|
|
||||||
<script defer src="main.dart.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="row" id="first">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" class="form-control" id="msg">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="btn btn-primary" type="button" id="send">Send
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p class="help-block">Example: "Hello", "4 Hello"</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,48 +0,0 @@
|
||||||
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
import 'dart:html';
|
|
||||||
|
|
||||||
import 'package:grpc/grpc_web.dart';
|
|
||||||
import 'package:grpc_web/app.dart';
|
|
||||||
import 'package:grpc_web/src/generated/echo.pbgrpc.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
final channel = new GrpcWebClientChannel.xhr('http://localhost',
|
|
||||||
port: 8080);
|
|
||||||
final service = EchoServiceClient(channel);
|
|
||||||
final app = EchoApp(service);
|
|
||||||
|
|
||||||
final button = querySelector('#send') as ButtonElement;
|
|
||||||
button.onClick.listen((e) async {
|
|
||||||
final msg = querySelector('#msg') as TextInputElement;
|
|
||||||
final value = msg.value.trim();
|
|
||||||
msg.value = '';
|
|
||||||
|
|
||||||
if (value.isEmpty) return false;
|
|
||||||
|
|
||||||
if (value.indexOf(' ') > 0) {
|
|
||||||
final countStr = value.substring(0, value.indexOf(' '));
|
|
||||||
final count = int.tryParse(countStr);
|
|
||||||
|
|
||||||
if (count != null) {
|
|
||||||
app.repeatEcho(value.substring(value.indexOf(' ') + 1), count);
|
|
||||||
} else {
|
|
||||||
app.echo(value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
app.echo(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -20,7 +20,7 @@ class GreeterClient extends Client {
|
||||||
GreeterClient(ClientChannel channel, {CallOptions options})
|
GreeterClient(ClientChannel channel, {CallOptions options})
|
||||||
: super(channel, options: options);
|
: super(channel, options: options);
|
||||||
|
|
||||||
Future<HelloReply> sayHello(HelloRequest request,
|
ResponseFuture<HelloReply> sayHello(HelloRequest request,
|
||||||
{CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(_$sayHello, new Stream.fromIterable([request]),
|
final call = $createCall(_$sayHello, new Stream.fromIterable([request]),
|
||||||
options: options);
|
options: options);
|
||||||
|
|
|
@ -13,4 +13,3 @@ dependencies:
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
test: ^1.3.0
|
test: ^1.3.0
|
||||||
|
|
|
@ -114,12 +114,6 @@ class TestService extends TestServiceBase {
|
||||||
final bufferedResponses = await request.map(_responseForRequest).toList();
|
final bufferedResponses = await request.map(_responseForRequest).toList();
|
||||||
yield* new Stream.fromIterable(bufferedResponses);
|
yield* new Stream.fromIterable(bufferedResponses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Empty> unimplementedCall(ServiceCall call, Empty request) {
|
|
||||||
// TODO: implement unimplementedCall
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> main(List<String> args) async {
|
Future<void> main(List<String> args) async {
|
||||||
|
|
|
@ -19,9 +19,9 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:grpc/grpc.dart';
|
import 'package:grpc/grpc.dart';
|
||||||
import 'generated/empty.pb.dart';
|
import 'package:interop/src/generated/empty.pb.dart';
|
||||||
import 'generated/messages.pb.dart';
|
import 'package:interop/src/generated/messages.pb.dart';
|
||||||
import 'generated/test.pbgrpc.dart';
|
import 'package:interop/src/generated/test.pbgrpc.dart';
|
||||||
|
|
||||||
const _headerEchoKey = 'x-grpc-test-echo-initial';
|
const _headerEchoKey = 'x-grpc-test-echo-initial';
|
||||||
const _headerEchoData = 'test_initial_metadata_value';
|
const _headerEchoData = 'test_initial_metadata_value';
|
||||||
|
@ -95,7 +95,7 @@ class Tester {
|
||||||
if (_useTestCA) {
|
if (_useTestCA) {
|
||||||
trustedRoot = new File('ca.pem').readAsBytesSync();
|
trustedRoot = new File('ca.pem').readAsBytesSync();
|
||||||
}
|
}
|
||||||
credentials = new Http2ChannelCredentials.secure(
|
credentials = new ChannelCredentials.secure(
|
||||||
certificates: trustedRoot, authority: serverHostOverride);
|
certificates: trustedRoot, authority: serverHostOverride);
|
||||||
} else {
|
} else {
|
||||||
credentials = const ChannelCredentials.insecure();
|
credentials = const ChannelCredentials.insecure();
|
||||||
|
|
|
@ -1,32 +1,36 @@
|
||||||
///
|
///
|
||||||
// Generated code. Do not modify.
|
// Generated code. Do not modify.
|
||||||
// source: empty.proto
|
|
||||||
///
|
///
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
// ignore_for_file: non_constant_identifier_names,library_prefixes
|
||||||
|
library grpc.testing_empty;
|
||||||
|
|
||||||
// ignore: UNUSED_SHOWN_NAME
|
// ignore: UNUSED_SHOWN_NAME
|
||||||
import 'dart:core' show int, bool, double, String, List, Map, override;
|
import 'dart:core' show int, bool, double, String, List, override;
|
||||||
|
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart';
|
||||||
|
|
||||||
class Empty extends $pb.GeneratedMessage {
|
class Empty extends GeneratedMessage {
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Empty', package: const $pb.PackageName('grpc.testing'))
|
static final BuilderInfo _i = new BuilderInfo('Empty')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false;
|
||||||
;
|
|
||||||
|
|
||||||
Empty() : super();
|
Empty() : super();
|
||||||
Empty.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
Empty.fromBuffer(List<int> i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
Empty.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
: super.fromBuffer(i, r);
|
||||||
|
Empty.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
Empty clone() => new Empty()..mergeFromMessage(this);
|
Empty clone() => new Empty()..mergeFromMessage(this);
|
||||||
Empty copyWith(void Function(Empty) updates) => super.copyWith((message) => updates(message as Empty));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static Empty create() => new Empty();
|
static Empty create() => new Empty();
|
||||||
Empty createEmptyInstance() => create();
|
static PbList<Empty> createRepeated() => new PbList<Empty>();
|
||||||
static $pb.PbList<Empty> createRepeated() => new $pb.PbList<Empty>();
|
static Empty getDefault() {
|
||||||
static Empty getDefault() => _defaultInstance ??= create()..freeze();
|
if (_defaultInstance == null) _defaultInstance = new _ReadonlyEmpty();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static Empty _defaultInstance;
|
static Empty _defaultInstance;
|
||||||
static void $checkItem(Empty v) {
|
static void $checkItem(Empty v) {
|
||||||
if (v is! Empty) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! Empty) checkItemFailed(v, 'Empty');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _ReadonlyEmpty extends Empty with ReadonlyMessageMixin {}
|
||||||
|
|
|
@ -1,441 +1,655 @@
|
||||||
///
|
///
|
||||||
// Generated code. Do not modify.
|
// Generated code. Do not modify.
|
||||||
// source: messages.proto
|
|
||||||
///
|
///
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
// ignore_for_file: non_constant_identifier_names,library_prefixes
|
||||||
|
library grpc.testing_messages;
|
||||||
|
|
||||||
// ignore: UNUSED_SHOWN_NAME
|
// ignore: UNUSED_SHOWN_NAME
|
||||||
import 'dart:core' show int, bool, double, String, List, Map, override;
|
import 'dart:core' show int, bool, double, String, List, override;
|
||||||
|
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart';
|
||||||
|
|
||||||
import 'messages.pbenum.dart';
|
import 'messages.pbenum.dart';
|
||||||
|
|
||||||
export 'messages.pbenum.dart';
|
export 'messages.pbenum.dart';
|
||||||
|
|
||||||
class BoolValue extends $pb.GeneratedMessage {
|
class BoolValue extends GeneratedMessage {
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('BoolValue', package: const $pb.PackageName('grpc.testing'))
|
static final BuilderInfo _i = new BuilderInfo('BoolValue')
|
||||||
..aOB(1, 'value')
|
..aOB(1, 'value')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false;
|
||||||
;
|
|
||||||
|
|
||||||
BoolValue() : super();
|
BoolValue() : super();
|
||||||
BoolValue.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
BoolValue.fromBuffer(List<int> i,
|
||||||
BoolValue.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromBuffer(i, r);
|
||||||
|
BoolValue.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
BoolValue clone() => new BoolValue()..mergeFromMessage(this);
|
BoolValue clone() => new BoolValue()..mergeFromMessage(this);
|
||||||
BoolValue copyWith(void Function(BoolValue) updates) => super.copyWith((message) => updates(message as BoolValue));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static BoolValue create() => new BoolValue();
|
static BoolValue create() => new BoolValue();
|
||||||
BoolValue createEmptyInstance() => create();
|
static PbList<BoolValue> createRepeated() => new PbList<BoolValue>();
|
||||||
static $pb.PbList<BoolValue> createRepeated() => new $pb.PbList<BoolValue>();
|
static BoolValue getDefault() {
|
||||||
static BoolValue getDefault() => _defaultInstance ??= create()..freeze();
|
if (_defaultInstance == null) _defaultInstance = new _ReadonlyBoolValue();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static BoolValue _defaultInstance;
|
static BoolValue _defaultInstance;
|
||||||
static void $checkItem(BoolValue v) {
|
static void $checkItem(BoolValue v) {
|
||||||
if (v is! BoolValue) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! BoolValue) checkItemFailed(v, 'BoolValue');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get value => $_get(0, false);
|
bool get value => $_get(0, false);
|
||||||
set value(bool v) { $_setBool(0, v); }
|
set value(bool v) {
|
||||||
|
$_setBool(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasValue() => $_has(0);
|
bool hasValue() => $_has(0);
|
||||||
void clearValue() => clearField(1);
|
void clearValue() => clearField(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Payload extends $pb.GeneratedMessage {
|
class _ReadonlyBoolValue extends BoolValue with ReadonlyMessageMixin {}
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Payload', package: const $pb.PackageName('grpc.testing'))
|
|
||||||
..e<PayloadType>(1, 'type', $pb.PbFieldType.OE, PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
|
class Payload extends GeneratedMessage {
|
||||||
..a<List<int>>(2, 'body', $pb.PbFieldType.OY)
|
static final BuilderInfo _i = new BuilderInfo('Payload')
|
||||||
..hasRequiredFields = false
|
..e<PayloadType>(1, 'type', PbFieldType.OE, PayloadType.COMPRESSABLE,
|
||||||
;
|
PayloadType.valueOf, PayloadType.values)
|
||||||
|
..a<List<int>>(2, 'body', PbFieldType.OY)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
Payload() : super();
|
Payload() : super();
|
||||||
Payload.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
Payload.fromBuffer(List<int> i,
|
||||||
Payload.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromBuffer(i, r);
|
||||||
|
Payload.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
Payload clone() => new Payload()..mergeFromMessage(this);
|
Payload clone() => new Payload()..mergeFromMessage(this);
|
||||||
Payload copyWith(void Function(Payload) updates) => super.copyWith((message) => updates(message as Payload));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static Payload create() => new Payload();
|
static Payload create() => new Payload();
|
||||||
Payload createEmptyInstance() => create();
|
static PbList<Payload> createRepeated() => new PbList<Payload>();
|
||||||
static $pb.PbList<Payload> createRepeated() => new $pb.PbList<Payload>();
|
static Payload getDefault() {
|
||||||
static Payload getDefault() => _defaultInstance ??= create()..freeze();
|
if (_defaultInstance == null) _defaultInstance = new _ReadonlyPayload();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static Payload _defaultInstance;
|
static Payload _defaultInstance;
|
||||||
static void $checkItem(Payload v) {
|
static void $checkItem(Payload v) {
|
||||||
if (v is! Payload) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! Payload) checkItemFailed(v, 'Payload');
|
||||||
}
|
}
|
||||||
|
|
||||||
PayloadType get type => $_getN(0);
|
PayloadType get type => $_getN(0);
|
||||||
set type(PayloadType v) { setField(1, v); }
|
set type(PayloadType v) {
|
||||||
|
setField(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasType() => $_has(0);
|
bool hasType() => $_has(0);
|
||||||
void clearType() => clearField(1);
|
void clearType() => clearField(1);
|
||||||
|
|
||||||
List<int> get body => $_getN(1);
|
List<int> get body => $_getN(1);
|
||||||
set body(List<int> v) { $_setBytes(1, v); }
|
set body(List<int> v) {
|
||||||
|
$_setBytes(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasBody() => $_has(1);
|
bool hasBody() => $_has(1);
|
||||||
void clearBody() => clearField(2);
|
void clearBody() => clearField(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EchoStatus extends $pb.GeneratedMessage {
|
class _ReadonlyPayload extends Payload with ReadonlyMessageMixin {}
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('EchoStatus', package: const $pb.PackageName('grpc.testing'))
|
|
||||||
..a<int>(1, 'code', $pb.PbFieldType.O3)
|
class EchoStatus extends GeneratedMessage {
|
||||||
|
static final BuilderInfo _i = new BuilderInfo('EchoStatus')
|
||||||
|
..a<int>(1, 'code', PbFieldType.O3)
|
||||||
..aOS(2, 'message')
|
..aOS(2, 'message')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false;
|
||||||
;
|
|
||||||
|
|
||||||
EchoStatus() : super();
|
EchoStatus() : super();
|
||||||
EchoStatus.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
EchoStatus.fromBuffer(List<int> i,
|
||||||
EchoStatus.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromBuffer(i, r);
|
||||||
|
EchoStatus.fromJson(String i, [ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
EchoStatus clone() => new EchoStatus()..mergeFromMessage(this);
|
EchoStatus clone() => new EchoStatus()..mergeFromMessage(this);
|
||||||
EchoStatus copyWith(void Function(EchoStatus) updates) => super.copyWith((message) => updates(message as EchoStatus));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static EchoStatus create() => new EchoStatus();
|
static EchoStatus create() => new EchoStatus();
|
||||||
EchoStatus createEmptyInstance() => create();
|
static PbList<EchoStatus> createRepeated() => new PbList<EchoStatus>();
|
||||||
static $pb.PbList<EchoStatus> createRepeated() => new $pb.PbList<EchoStatus>();
|
static EchoStatus getDefault() {
|
||||||
static EchoStatus getDefault() => _defaultInstance ??= create()..freeze();
|
if (_defaultInstance == null) _defaultInstance = new _ReadonlyEchoStatus();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static EchoStatus _defaultInstance;
|
static EchoStatus _defaultInstance;
|
||||||
static void $checkItem(EchoStatus v) {
|
static void $checkItem(EchoStatus v) {
|
||||||
if (v is! EchoStatus) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! EchoStatus) checkItemFailed(v, 'EchoStatus');
|
||||||
}
|
}
|
||||||
|
|
||||||
int get code => $_get(0, 0);
|
int get code => $_get(0, 0);
|
||||||
set code(int v) { $_setSignedInt32(0, v); }
|
set code(int v) {
|
||||||
|
$_setUnsignedInt32(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasCode() => $_has(0);
|
bool hasCode() => $_has(0);
|
||||||
void clearCode() => clearField(1);
|
void clearCode() => clearField(1);
|
||||||
|
|
||||||
String get message => $_getS(1, '');
|
String get message => $_getS(1, '');
|
||||||
set message(String v) { $_setString(1, v); }
|
set message(String v) {
|
||||||
|
$_setString(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasMessage() => $_has(1);
|
bool hasMessage() => $_has(1);
|
||||||
void clearMessage() => clearField(2);
|
void clearMessage() => clearField(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleRequest extends $pb.GeneratedMessage {
|
class _ReadonlyEchoStatus extends EchoStatus with ReadonlyMessageMixin {}
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('SimpleRequest', package: const $pb.PackageName('grpc.testing'))
|
|
||||||
..e<PayloadType>(1, 'responseType', $pb.PbFieldType.OE, PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
|
class SimpleRequest extends GeneratedMessage {
|
||||||
..a<int>(2, 'responseSize', $pb.PbFieldType.O3)
|
static final BuilderInfo _i = new BuilderInfo('SimpleRequest')
|
||||||
..a<Payload>(3, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
|
..e<PayloadType>(1, 'responseType', PbFieldType.OE,
|
||||||
|
PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
|
||||||
|
..a<int>(2, 'responseSize', PbFieldType.O3)
|
||||||
|
..a<Payload>(
|
||||||
|
3, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
|
||||||
..aOB(4, 'fillUsername')
|
..aOB(4, 'fillUsername')
|
||||||
..aOB(5, 'fillOauthScope')
|
..aOB(5, 'fillOauthScope')
|
||||||
..a<BoolValue>(6, 'responseCompressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
|
..a<BoolValue>(6, 'responseCompressed', PbFieldType.OM,
|
||||||
..a<EchoStatus>(7, 'responseStatus', $pb.PbFieldType.OM, EchoStatus.getDefault, EchoStatus.create)
|
BoolValue.getDefault, BoolValue.create)
|
||||||
..a<BoolValue>(8, 'expectCompressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
|
..a<EchoStatus>(7, 'responseStatus', PbFieldType.OM, EchoStatus.getDefault,
|
||||||
..hasRequiredFields = false
|
EchoStatus.create)
|
||||||
;
|
..a<BoolValue>(8, 'expectCompressed', PbFieldType.OM, BoolValue.getDefault,
|
||||||
|
BoolValue.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
SimpleRequest() : super();
|
SimpleRequest() : super();
|
||||||
SimpleRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
SimpleRequest.fromBuffer(List<int> i,
|
||||||
SimpleRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromBuffer(i, r);
|
||||||
|
SimpleRequest.fromJson(String i,
|
||||||
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
SimpleRequest clone() => new SimpleRequest()..mergeFromMessage(this);
|
SimpleRequest clone() => new SimpleRequest()..mergeFromMessage(this);
|
||||||
SimpleRequest copyWith(void Function(SimpleRequest) updates) => super.copyWith((message) => updates(message as SimpleRequest));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static SimpleRequest create() => new SimpleRequest();
|
static SimpleRequest create() => new SimpleRequest();
|
||||||
SimpleRequest createEmptyInstance() => create();
|
static PbList<SimpleRequest> createRepeated() => new PbList<SimpleRequest>();
|
||||||
static $pb.PbList<SimpleRequest> createRepeated() => new $pb.PbList<SimpleRequest>();
|
static SimpleRequest getDefault() {
|
||||||
static SimpleRequest getDefault() => _defaultInstance ??= create()..freeze();
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlySimpleRequest();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static SimpleRequest _defaultInstance;
|
static SimpleRequest _defaultInstance;
|
||||||
static void $checkItem(SimpleRequest v) {
|
static void $checkItem(SimpleRequest v) {
|
||||||
if (v is! SimpleRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! SimpleRequest) checkItemFailed(v, 'SimpleRequest');
|
||||||
}
|
}
|
||||||
|
|
||||||
PayloadType get responseType => $_getN(0);
|
PayloadType get responseType => $_getN(0);
|
||||||
set responseType(PayloadType v) { setField(1, v); }
|
set responseType(PayloadType v) {
|
||||||
|
setField(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasResponseType() => $_has(0);
|
bool hasResponseType() => $_has(0);
|
||||||
void clearResponseType() => clearField(1);
|
void clearResponseType() => clearField(1);
|
||||||
|
|
||||||
int get responseSize => $_get(1, 0);
|
int get responseSize => $_get(1, 0);
|
||||||
set responseSize(int v) { $_setSignedInt32(1, v); }
|
set responseSize(int v) {
|
||||||
|
$_setUnsignedInt32(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasResponseSize() => $_has(1);
|
bool hasResponseSize() => $_has(1);
|
||||||
void clearResponseSize() => clearField(2);
|
void clearResponseSize() => clearField(2);
|
||||||
|
|
||||||
Payload get payload => $_getN(2);
|
Payload get payload => $_getN(2);
|
||||||
set payload(Payload v) { setField(3, v); }
|
set payload(Payload v) {
|
||||||
|
setField(3, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasPayload() => $_has(2);
|
bool hasPayload() => $_has(2);
|
||||||
void clearPayload() => clearField(3);
|
void clearPayload() => clearField(3);
|
||||||
|
|
||||||
bool get fillUsername => $_get(3, false);
|
bool get fillUsername => $_get(3, false);
|
||||||
set fillUsername(bool v) { $_setBool(3, v); }
|
set fillUsername(bool v) {
|
||||||
|
$_setBool(3, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasFillUsername() => $_has(3);
|
bool hasFillUsername() => $_has(3);
|
||||||
void clearFillUsername() => clearField(4);
|
void clearFillUsername() => clearField(4);
|
||||||
|
|
||||||
bool get fillOauthScope => $_get(4, false);
|
bool get fillOauthScope => $_get(4, false);
|
||||||
set fillOauthScope(bool v) { $_setBool(4, v); }
|
set fillOauthScope(bool v) {
|
||||||
|
$_setBool(4, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasFillOauthScope() => $_has(4);
|
bool hasFillOauthScope() => $_has(4);
|
||||||
void clearFillOauthScope() => clearField(5);
|
void clearFillOauthScope() => clearField(5);
|
||||||
|
|
||||||
BoolValue get responseCompressed => $_getN(5);
|
BoolValue get responseCompressed => $_getN(5);
|
||||||
set responseCompressed(BoolValue v) { setField(6, v); }
|
set responseCompressed(BoolValue v) {
|
||||||
|
setField(6, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasResponseCompressed() => $_has(5);
|
bool hasResponseCompressed() => $_has(5);
|
||||||
void clearResponseCompressed() => clearField(6);
|
void clearResponseCompressed() => clearField(6);
|
||||||
|
|
||||||
EchoStatus get responseStatus => $_getN(6);
|
EchoStatus get responseStatus => $_getN(6);
|
||||||
set responseStatus(EchoStatus v) { setField(7, v); }
|
set responseStatus(EchoStatus v) {
|
||||||
|
setField(7, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasResponseStatus() => $_has(6);
|
bool hasResponseStatus() => $_has(6);
|
||||||
void clearResponseStatus() => clearField(7);
|
void clearResponseStatus() => clearField(7);
|
||||||
|
|
||||||
BoolValue get expectCompressed => $_getN(7);
|
BoolValue get expectCompressed => $_getN(7);
|
||||||
set expectCompressed(BoolValue v) { setField(8, v); }
|
set expectCompressed(BoolValue v) {
|
||||||
|
setField(8, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasExpectCompressed() => $_has(7);
|
bool hasExpectCompressed() => $_has(7);
|
||||||
void clearExpectCompressed() => clearField(8);
|
void clearExpectCompressed() => clearField(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleResponse extends $pb.GeneratedMessage {
|
class _ReadonlySimpleRequest extends SimpleRequest with ReadonlyMessageMixin {}
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('SimpleResponse', package: const $pb.PackageName('grpc.testing'))
|
|
||||||
..a<Payload>(1, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
|
class SimpleResponse extends GeneratedMessage {
|
||||||
|
static final BuilderInfo _i = new BuilderInfo('SimpleResponse')
|
||||||
|
..a<Payload>(
|
||||||
|
1, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
|
||||||
..aOS(2, 'username')
|
..aOS(2, 'username')
|
||||||
..aOS(3, 'oauthScope')
|
..aOS(3, 'oauthScope')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false;
|
||||||
;
|
|
||||||
|
|
||||||
SimpleResponse() : super();
|
SimpleResponse() : super();
|
||||||
SimpleResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
SimpleResponse.fromBuffer(List<int> i,
|
||||||
SimpleResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromBuffer(i, r);
|
||||||
|
SimpleResponse.fromJson(String i,
|
||||||
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
SimpleResponse clone() => new SimpleResponse()..mergeFromMessage(this);
|
SimpleResponse clone() => new SimpleResponse()..mergeFromMessage(this);
|
||||||
SimpleResponse copyWith(void Function(SimpleResponse) updates) => super.copyWith((message) => updates(message as SimpleResponse));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static SimpleResponse create() => new SimpleResponse();
|
static SimpleResponse create() => new SimpleResponse();
|
||||||
SimpleResponse createEmptyInstance() => create();
|
static PbList<SimpleResponse> createRepeated() =>
|
||||||
static $pb.PbList<SimpleResponse> createRepeated() => new $pb.PbList<SimpleResponse>();
|
new PbList<SimpleResponse>();
|
||||||
static SimpleResponse getDefault() => _defaultInstance ??= create()..freeze();
|
static SimpleResponse getDefault() {
|
||||||
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlySimpleResponse();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static SimpleResponse _defaultInstance;
|
static SimpleResponse _defaultInstance;
|
||||||
static void $checkItem(SimpleResponse v) {
|
static void $checkItem(SimpleResponse v) {
|
||||||
if (v is! SimpleResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! SimpleResponse) checkItemFailed(v, 'SimpleResponse');
|
||||||
}
|
}
|
||||||
|
|
||||||
Payload get payload => $_getN(0);
|
Payload get payload => $_getN(0);
|
||||||
set payload(Payload v) { setField(1, v); }
|
set payload(Payload v) {
|
||||||
|
setField(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasPayload() => $_has(0);
|
bool hasPayload() => $_has(0);
|
||||||
void clearPayload() => clearField(1);
|
void clearPayload() => clearField(1);
|
||||||
|
|
||||||
String get username => $_getS(1, '');
|
String get username => $_getS(1, '');
|
||||||
set username(String v) { $_setString(1, v); }
|
set username(String v) {
|
||||||
|
$_setString(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasUsername() => $_has(1);
|
bool hasUsername() => $_has(1);
|
||||||
void clearUsername() => clearField(2);
|
void clearUsername() => clearField(2);
|
||||||
|
|
||||||
String get oauthScope => $_getS(2, '');
|
String get oauthScope => $_getS(2, '');
|
||||||
set oauthScope(String v) { $_setString(2, v); }
|
set oauthScope(String v) {
|
||||||
|
$_setString(2, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasOauthScope() => $_has(2);
|
bool hasOauthScope() => $_has(2);
|
||||||
void clearOauthScope() => clearField(3);
|
void clearOauthScope() => clearField(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamingInputCallRequest extends $pb.GeneratedMessage {
|
class _ReadonlySimpleResponse extends SimpleResponse with ReadonlyMessageMixin {
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingInputCallRequest', package: const $pb.PackageName('grpc.testing'))
|
}
|
||||||
..a<Payload>(1, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
|
|
||||||
..a<BoolValue>(2, 'expectCompressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
|
class StreamingInputCallRequest extends GeneratedMessage {
|
||||||
..hasRequiredFields = false
|
static final BuilderInfo _i = new BuilderInfo('StreamingInputCallRequest')
|
||||||
;
|
..a<Payload>(
|
||||||
|
1, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
|
||||||
|
..a<BoolValue>(2, 'expectCompressed', PbFieldType.OM, BoolValue.getDefault,
|
||||||
|
BoolValue.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
StreamingInputCallRequest() : super();
|
StreamingInputCallRequest() : super();
|
||||||
StreamingInputCallRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
StreamingInputCallRequest.fromBuffer(List<int> i,
|
||||||
StreamingInputCallRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
StreamingInputCallRequest clone() => new StreamingInputCallRequest()..mergeFromMessage(this);
|
: super.fromBuffer(i, r);
|
||||||
StreamingInputCallRequest copyWith(void Function(StreamingInputCallRequest) updates) => super.copyWith((message) => updates(message as StreamingInputCallRequest));
|
StreamingInputCallRequest.fromJson(String i,
|
||||||
$pb.BuilderInfo get info_ => _i;
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
|
StreamingInputCallRequest clone() =>
|
||||||
|
new StreamingInputCallRequest()..mergeFromMessage(this);
|
||||||
|
BuilderInfo get info_ => _i;
|
||||||
static StreamingInputCallRequest create() => new StreamingInputCallRequest();
|
static StreamingInputCallRequest create() => new StreamingInputCallRequest();
|
||||||
StreamingInputCallRequest createEmptyInstance() => create();
|
static PbList<StreamingInputCallRequest> createRepeated() =>
|
||||||
static $pb.PbList<StreamingInputCallRequest> createRepeated() => new $pb.PbList<StreamingInputCallRequest>();
|
new PbList<StreamingInputCallRequest>();
|
||||||
static StreamingInputCallRequest getDefault() => _defaultInstance ??= create()..freeze();
|
static StreamingInputCallRequest getDefault() {
|
||||||
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlyStreamingInputCallRequest();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static StreamingInputCallRequest _defaultInstance;
|
static StreamingInputCallRequest _defaultInstance;
|
||||||
static void $checkItem(StreamingInputCallRequest v) {
|
static void $checkItem(StreamingInputCallRequest v) {
|
||||||
if (v is! StreamingInputCallRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! StreamingInputCallRequest)
|
||||||
|
checkItemFailed(v, 'StreamingInputCallRequest');
|
||||||
}
|
}
|
||||||
|
|
||||||
Payload get payload => $_getN(0);
|
Payload get payload => $_getN(0);
|
||||||
set payload(Payload v) { setField(1, v); }
|
set payload(Payload v) {
|
||||||
|
setField(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasPayload() => $_has(0);
|
bool hasPayload() => $_has(0);
|
||||||
void clearPayload() => clearField(1);
|
void clearPayload() => clearField(1);
|
||||||
|
|
||||||
BoolValue get expectCompressed => $_getN(1);
|
BoolValue get expectCompressed => $_getN(1);
|
||||||
set expectCompressed(BoolValue v) { setField(2, v); }
|
set expectCompressed(BoolValue v) {
|
||||||
|
setField(2, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasExpectCompressed() => $_has(1);
|
bool hasExpectCompressed() => $_has(1);
|
||||||
void clearExpectCompressed() => clearField(2);
|
void clearExpectCompressed() => clearField(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamingInputCallResponse extends $pb.GeneratedMessage {
|
class _ReadonlyStreamingInputCallRequest extends StreamingInputCallRequest
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingInputCallResponse', package: const $pb.PackageName('grpc.testing'))
|
with ReadonlyMessageMixin {}
|
||||||
..a<int>(1, 'aggregatedPayloadSize', $pb.PbFieldType.O3)
|
|
||||||
..hasRequiredFields = false
|
class StreamingInputCallResponse extends GeneratedMessage {
|
||||||
;
|
static final BuilderInfo _i = new BuilderInfo('StreamingInputCallResponse')
|
||||||
|
..a<int>(1, 'aggregatedPayloadSize', PbFieldType.O3)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
StreamingInputCallResponse() : super();
|
StreamingInputCallResponse() : super();
|
||||||
StreamingInputCallResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
StreamingInputCallResponse.fromBuffer(List<int> i,
|
||||||
StreamingInputCallResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
StreamingInputCallResponse clone() => new StreamingInputCallResponse()..mergeFromMessage(this);
|
: super.fromBuffer(i, r);
|
||||||
StreamingInputCallResponse copyWith(void Function(StreamingInputCallResponse) updates) => super.copyWith((message) => updates(message as StreamingInputCallResponse));
|
StreamingInputCallResponse.fromJson(String i,
|
||||||
$pb.BuilderInfo get info_ => _i;
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
static StreamingInputCallResponse create() => new StreamingInputCallResponse();
|
: super.fromJson(i, r);
|
||||||
StreamingInputCallResponse createEmptyInstance() => create();
|
StreamingInputCallResponse clone() =>
|
||||||
static $pb.PbList<StreamingInputCallResponse> createRepeated() => new $pb.PbList<StreamingInputCallResponse>();
|
new StreamingInputCallResponse()..mergeFromMessage(this);
|
||||||
static StreamingInputCallResponse getDefault() => _defaultInstance ??= create()..freeze();
|
BuilderInfo get info_ => _i;
|
||||||
|
static StreamingInputCallResponse create() =>
|
||||||
|
new StreamingInputCallResponse();
|
||||||
|
static PbList<StreamingInputCallResponse> createRepeated() =>
|
||||||
|
new PbList<StreamingInputCallResponse>();
|
||||||
|
static StreamingInputCallResponse getDefault() {
|
||||||
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlyStreamingInputCallResponse();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static StreamingInputCallResponse _defaultInstance;
|
static StreamingInputCallResponse _defaultInstance;
|
||||||
static void $checkItem(StreamingInputCallResponse v) {
|
static void $checkItem(StreamingInputCallResponse v) {
|
||||||
if (v is! StreamingInputCallResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! StreamingInputCallResponse)
|
||||||
|
checkItemFailed(v, 'StreamingInputCallResponse');
|
||||||
}
|
}
|
||||||
|
|
||||||
int get aggregatedPayloadSize => $_get(0, 0);
|
int get aggregatedPayloadSize => $_get(0, 0);
|
||||||
set aggregatedPayloadSize(int v) { $_setSignedInt32(0, v); }
|
set aggregatedPayloadSize(int v) {
|
||||||
|
$_setUnsignedInt32(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasAggregatedPayloadSize() => $_has(0);
|
bool hasAggregatedPayloadSize() => $_has(0);
|
||||||
void clearAggregatedPayloadSize() => clearField(1);
|
void clearAggregatedPayloadSize() => clearField(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResponseParameters extends $pb.GeneratedMessage {
|
class _ReadonlyStreamingInputCallResponse extends StreamingInputCallResponse
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ResponseParameters', package: const $pb.PackageName('grpc.testing'))
|
with ReadonlyMessageMixin {}
|
||||||
..a<int>(1, 'size', $pb.PbFieldType.O3)
|
|
||||||
..a<int>(2, 'intervalUs', $pb.PbFieldType.O3)
|
class ResponseParameters extends GeneratedMessage {
|
||||||
..a<BoolValue>(3, 'compressed', $pb.PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
|
static final BuilderInfo _i = new BuilderInfo('ResponseParameters')
|
||||||
..hasRequiredFields = false
|
..a<int>(1, 'size', PbFieldType.O3)
|
||||||
;
|
..a<int>(2, 'intervalUs', PbFieldType.O3)
|
||||||
|
..a<BoolValue>(
|
||||||
|
3, 'compressed', PbFieldType.OM, BoolValue.getDefault, BoolValue.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
ResponseParameters() : super();
|
ResponseParameters() : super();
|
||||||
ResponseParameters.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
ResponseParameters.fromBuffer(List<int> i,
|
||||||
ResponseParameters.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
ResponseParameters clone() => new ResponseParameters()..mergeFromMessage(this);
|
: super.fromBuffer(i, r);
|
||||||
ResponseParameters copyWith(void Function(ResponseParameters) updates) => super.copyWith((message) => updates(message as ResponseParameters));
|
ResponseParameters.fromJson(String i,
|
||||||
$pb.BuilderInfo get info_ => _i;
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
|
ResponseParameters clone() =>
|
||||||
|
new ResponseParameters()..mergeFromMessage(this);
|
||||||
|
BuilderInfo get info_ => _i;
|
||||||
static ResponseParameters create() => new ResponseParameters();
|
static ResponseParameters create() => new ResponseParameters();
|
||||||
ResponseParameters createEmptyInstance() => create();
|
static PbList<ResponseParameters> createRepeated() =>
|
||||||
static $pb.PbList<ResponseParameters> createRepeated() => new $pb.PbList<ResponseParameters>();
|
new PbList<ResponseParameters>();
|
||||||
static ResponseParameters getDefault() => _defaultInstance ??= create()..freeze();
|
static ResponseParameters getDefault() {
|
||||||
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlyResponseParameters();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static ResponseParameters _defaultInstance;
|
static ResponseParameters _defaultInstance;
|
||||||
static void $checkItem(ResponseParameters v) {
|
static void $checkItem(ResponseParameters v) {
|
||||||
if (v is! ResponseParameters) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! ResponseParameters) checkItemFailed(v, 'ResponseParameters');
|
||||||
}
|
}
|
||||||
|
|
||||||
int get size => $_get(0, 0);
|
int get size => $_get(0, 0);
|
||||||
set size(int v) { $_setSignedInt32(0, v); }
|
set size(int v) {
|
||||||
|
$_setUnsignedInt32(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasSize() => $_has(0);
|
bool hasSize() => $_has(0);
|
||||||
void clearSize() => clearField(1);
|
void clearSize() => clearField(1);
|
||||||
|
|
||||||
int get intervalUs => $_get(1, 0);
|
int get intervalUs => $_get(1, 0);
|
||||||
set intervalUs(int v) { $_setSignedInt32(1, v); }
|
set intervalUs(int v) {
|
||||||
|
$_setUnsignedInt32(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasIntervalUs() => $_has(1);
|
bool hasIntervalUs() => $_has(1);
|
||||||
void clearIntervalUs() => clearField(2);
|
void clearIntervalUs() => clearField(2);
|
||||||
|
|
||||||
BoolValue get compressed => $_getN(2);
|
BoolValue get compressed => $_getN(2);
|
||||||
set compressed(BoolValue v) { setField(3, v); }
|
set compressed(BoolValue v) {
|
||||||
|
setField(3, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasCompressed() => $_has(2);
|
bool hasCompressed() => $_has(2);
|
||||||
void clearCompressed() => clearField(3);
|
void clearCompressed() => clearField(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamingOutputCallRequest extends $pb.GeneratedMessage {
|
class _ReadonlyResponseParameters extends ResponseParameters
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingOutputCallRequest', package: const $pb.PackageName('grpc.testing'))
|
with ReadonlyMessageMixin {}
|
||||||
..e<PayloadType>(1, 'responseType', $pb.PbFieldType.OE, PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
|
|
||||||
..pp<ResponseParameters>(2, 'responseParameters', $pb.PbFieldType.PM, ResponseParameters.$checkItem, ResponseParameters.create)
|
class StreamingOutputCallRequest extends GeneratedMessage {
|
||||||
..a<Payload>(3, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
|
static final BuilderInfo _i = new BuilderInfo('StreamingOutputCallRequest')
|
||||||
..a<EchoStatus>(7, 'responseStatus', $pb.PbFieldType.OM, EchoStatus.getDefault, EchoStatus.create)
|
..e<PayloadType>(1, 'responseType', PbFieldType.OE,
|
||||||
..hasRequiredFields = false
|
PayloadType.COMPRESSABLE, PayloadType.valueOf, PayloadType.values)
|
||||||
;
|
..pp<ResponseParameters>(2, 'responseParameters', PbFieldType.PM,
|
||||||
|
ResponseParameters.$checkItem, ResponseParameters.create)
|
||||||
|
..a<Payload>(
|
||||||
|
3, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
|
||||||
|
..a<EchoStatus>(7, 'responseStatus', PbFieldType.OM, EchoStatus.getDefault,
|
||||||
|
EchoStatus.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
StreamingOutputCallRequest() : super();
|
StreamingOutputCallRequest() : super();
|
||||||
StreamingOutputCallRequest.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
StreamingOutputCallRequest.fromBuffer(List<int> i,
|
||||||
StreamingOutputCallRequest.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
StreamingOutputCallRequest clone() => new StreamingOutputCallRequest()..mergeFromMessage(this);
|
: super.fromBuffer(i, r);
|
||||||
StreamingOutputCallRequest copyWith(void Function(StreamingOutputCallRequest) updates) => super.copyWith((message) => updates(message as StreamingOutputCallRequest));
|
StreamingOutputCallRequest.fromJson(String i,
|
||||||
$pb.BuilderInfo get info_ => _i;
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
static StreamingOutputCallRequest create() => new StreamingOutputCallRequest();
|
: super.fromJson(i, r);
|
||||||
StreamingOutputCallRequest createEmptyInstance() => create();
|
StreamingOutputCallRequest clone() =>
|
||||||
static $pb.PbList<StreamingOutputCallRequest> createRepeated() => new $pb.PbList<StreamingOutputCallRequest>();
|
new StreamingOutputCallRequest()..mergeFromMessage(this);
|
||||||
static StreamingOutputCallRequest getDefault() => _defaultInstance ??= create()..freeze();
|
BuilderInfo get info_ => _i;
|
||||||
|
static StreamingOutputCallRequest create() =>
|
||||||
|
new StreamingOutputCallRequest();
|
||||||
|
static PbList<StreamingOutputCallRequest> createRepeated() =>
|
||||||
|
new PbList<StreamingOutputCallRequest>();
|
||||||
|
static StreamingOutputCallRequest getDefault() {
|
||||||
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlyStreamingOutputCallRequest();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static StreamingOutputCallRequest _defaultInstance;
|
static StreamingOutputCallRequest _defaultInstance;
|
||||||
static void $checkItem(StreamingOutputCallRequest v) {
|
static void $checkItem(StreamingOutputCallRequest v) {
|
||||||
if (v is! StreamingOutputCallRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! StreamingOutputCallRequest)
|
||||||
|
checkItemFailed(v, 'StreamingOutputCallRequest');
|
||||||
}
|
}
|
||||||
|
|
||||||
PayloadType get responseType => $_getN(0);
|
PayloadType get responseType => $_getN(0);
|
||||||
set responseType(PayloadType v) { setField(1, v); }
|
set responseType(PayloadType v) {
|
||||||
|
setField(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasResponseType() => $_has(0);
|
bool hasResponseType() => $_has(0);
|
||||||
void clearResponseType() => clearField(1);
|
void clearResponseType() => clearField(1);
|
||||||
|
|
||||||
List<ResponseParameters> get responseParameters => $_getList(1);
|
List<ResponseParameters> get responseParameters => $_getList(1);
|
||||||
|
|
||||||
Payload get payload => $_getN(2);
|
Payload get payload => $_getN(2);
|
||||||
set payload(Payload v) { setField(3, v); }
|
set payload(Payload v) {
|
||||||
|
setField(3, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasPayload() => $_has(2);
|
bool hasPayload() => $_has(2);
|
||||||
void clearPayload() => clearField(3);
|
void clearPayload() => clearField(3);
|
||||||
|
|
||||||
EchoStatus get responseStatus => $_getN(3);
|
EchoStatus get responseStatus => $_getN(3);
|
||||||
set responseStatus(EchoStatus v) { setField(7, v); }
|
set responseStatus(EchoStatus v) {
|
||||||
|
setField(7, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasResponseStatus() => $_has(3);
|
bool hasResponseStatus() => $_has(3);
|
||||||
void clearResponseStatus() => clearField(7);
|
void clearResponseStatus() => clearField(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamingOutputCallResponse extends $pb.GeneratedMessage {
|
class _ReadonlyStreamingOutputCallRequest extends StreamingOutputCallRequest
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('StreamingOutputCallResponse', package: const $pb.PackageName('grpc.testing'))
|
with ReadonlyMessageMixin {}
|
||||||
..a<Payload>(1, 'payload', $pb.PbFieldType.OM, Payload.getDefault, Payload.create)
|
|
||||||
..hasRequiredFields = false
|
class StreamingOutputCallResponse extends GeneratedMessage {
|
||||||
;
|
static final BuilderInfo _i = new BuilderInfo('StreamingOutputCallResponse')
|
||||||
|
..a<Payload>(
|
||||||
|
1, 'payload', PbFieldType.OM, Payload.getDefault, Payload.create)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
StreamingOutputCallResponse() : super();
|
StreamingOutputCallResponse() : super();
|
||||||
StreamingOutputCallResponse.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
StreamingOutputCallResponse.fromBuffer(List<int> i,
|
||||||
StreamingOutputCallResponse.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
StreamingOutputCallResponse clone() => new StreamingOutputCallResponse()..mergeFromMessage(this);
|
: super.fromBuffer(i, r);
|
||||||
StreamingOutputCallResponse copyWith(void Function(StreamingOutputCallResponse) updates) => super.copyWith((message) => updates(message as StreamingOutputCallResponse));
|
StreamingOutputCallResponse.fromJson(String i,
|
||||||
$pb.BuilderInfo get info_ => _i;
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
static StreamingOutputCallResponse create() => new StreamingOutputCallResponse();
|
: super.fromJson(i, r);
|
||||||
StreamingOutputCallResponse createEmptyInstance() => create();
|
StreamingOutputCallResponse clone() =>
|
||||||
static $pb.PbList<StreamingOutputCallResponse> createRepeated() => new $pb.PbList<StreamingOutputCallResponse>();
|
new StreamingOutputCallResponse()..mergeFromMessage(this);
|
||||||
static StreamingOutputCallResponse getDefault() => _defaultInstance ??= create()..freeze();
|
BuilderInfo get info_ => _i;
|
||||||
|
static StreamingOutputCallResponse create() =>
|
||||||
|
new StreamingOutputCallResponse();
|
||||||
|
static PbList<StreamingOutputCallResponse> createRepeated() =>
|
||||||
|
new PbList<StreamingOutputCallResponse>();
|
||||||
|
static StreamingOutputCallResponse getDefault() {
|
||||||
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlyStreamingOutputCallResponse();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static StreamingOutputCallResponse _defaultInstance;
|
static StreamingOutputCallResponse _defaultInstance;
|
||||||
static void $checkItem(StreamingOutputCallResponse v) {
|
static void $checkItem(StreamingOutputCallResponse v) {
|
||||||
if (v is! StreamingOutputCallResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! StreamingOutputCallResponse)
|
||||||
|
checkItemFailed(v, 'StreamingOutputCallResponse');
|
||||||
}
|
}
|
||||||
|
|
||||||
Payload get payload => $_getN(0);
|
Payload get payload => $_getN(0);
|
||||||
set payload(Payload v) { setField(1, v); }
|
set payload(Payload v) {
|
||||||
|
setField(1, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasPayload() => $_has(0);
|
bool hasPayload() => $_has(0);
|
||||||
void clearPayload() => clearField(1);
|
void clearPayload() => clearField(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReconnectParams extends $pb.GeneratedMessage {
|
class _ReadonlyStreamingOutputCallResponse extends StreamingOutputCallResponse
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ReconnectParams', package: const $pb.PackageName('grpc.testing'))
|
with ReadonlyMessageMixin {}
|
||||||
..a<int>(1, 'maxReconnectBackoffMs', $pb.PbFieldType.O3)
|
|
||||||
..hasRequiredFields = false
|
class ReconnectParams extends GeneratedMessage {
|
||||||
;
|
static final BuilderInfo _i = new BuilderInfo('ReconnectParams')
|
||||||
|
..a<int>(1, 'maxReconnectBackoffMs', PbFieldType.O3)
|
||||||
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
ReconnectParams() : super();
|
ReconnectParams() : super();
|
||||||
ReconnectParams.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
ReconnectParams.fromBuffer(List<int> i,
|
||||||
ReconnectParams.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromBuffer(i, r);
|
||||||
|
ReconnectParams.fromJson(String i,
|
||||||
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
ReconnectParams clone() => new ReconnectParams()..mergeFromMessage(this);
|
ReconnectParams clone() => new ReconnectParams()..mergeFromMessage(this);
|
||||||
ReconnectParams copyWith(void Function(ReconnectParams) updates) => super.copyWith((message) => updates(message as ReconnectParams));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static ReconnectParams create() => new ReconnectParams();
|
static ReconnectParams create() => new ReconnectParams();
|
||||||
ReconnectParams createEmptyInstance() => create();
|
static PbList<ReconnectParams> createRepeated() =>
|
||||||
static $pb.PbList<ReconnectParams> createRepeated() => new $pb.PbList<ReconnectParams>();
|
new PbList<ReconnectParams>();
|
||||||
static ReconnectParams getDefault() => _defaultInstance ??= create()..freeze();
|
static ReconnectParams getDefault() {
|
||||||
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlyReconnectParams();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static ReconnectParams _defaultInstance;
|
static ReconnectParams _defaultInstance;
|
||||||
static void $checkItem(ReconnectParams v) {
|
static void $checkItem(ReconnectParams v) {
|
||||||
if (v is! ReconnectParams) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! ReconnectParams) checkItemFailed(v, 'ReconnectParams');
|
||||||
}
|
}
|
||||||
|
|
||||||
int get maxReconnectBackoffMs => $_get(0, 0);
|
int get maxReconnectBackoffMs => $_get(0, 0);
|
||||||
set maxReconnectBackoffMs(int v) { $_setSignedInt32(0, v); }
|
set maxReconnectBackoffMs(int v) {
|
||||||
|
$_setUnsignedInt32(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasMaxReconnectBackoffMs() => $_has(0);
|
bool hasMaxReconnectBackoffMs() => $_has(0);
|
||||||
void clearMaxReconnectBackoffMs() => clearField(1);
|
void clearMaxReconnectBackoffMs() => clearField(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReconnectInfo extends $pb.GeneratedMessage {
|
class _ReadonlyReconnectParams extends ReconnectParams
|
||||||
static final $pb.BuilderInfo _i = new $pb.BuilderInfo('ReconnectInfo', package: const $pb.PackageName('grpc.testing'))
|
with ReadonlyMessageMixin {}
|
||||||
|
|
||||||
|
class ReconnectInfo extends GeneratedMessage {
|
||||||
|
static final BuilderInfo _i = new BuilderInfo('ReconnectInfo')
|
||||||
..aOB(1, 'passed')
|
..aOB(1, 'passed')
|
||||||
..p<int>(2, 'backoffMs', $pb.PbFieldType.P3)
|
..p<int>(2, 'backoffMs', PbFieldType.P3)
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false;
|
||||||
;
|
|
||||||
|
|
||||||
ReconnectInfo() : super();
|
ReconnectInfo() : super();
|
||||||
ReconnectInfo.fromBuffer(List<int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromBuffer(i, r);
|
ReconnectInfo.fromBuffer(List<int> i,
|
||||||
ReconnectInfo.fromJson(String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) : super.fromJson(i, r);
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromBuffer(i, r);
|
||||||
|
ReconnectInfo.fromJson(String i,
|
||||||
|
[ExtensionRegistry r = ExtensionRegistry.EMPTY])
|
||||||
|
: super.fromJson(i, r);
|
||||||
ReconnectInfo clone() => new ReconnectInfo()..mergeFromMessage(this);
|
ReconnectInfo clone() => new ReconnectInfo()..mergeFromMessage(this);
|
||||||
ReconnectInfo copyWith(void Function(ReconnectInfo) updates) => super.copyWith((message) => updates(message as ReconnectInfo));
|
BuilderInfo get info_ => _i;
|
||||||
$pb.BuilderInfo get info_ => _i;
|
|
||||||
static ReconnectInfo create() => new ReconnectInfo();
|
static ReconnectInfo create() => new ReconnectInfo();
|
||||||
ReconnectInfo createEmptyInstance() => create();
|
static PbList<ReconnectInfo> createRepeated() => new PbList<ReconnectInfo>();
|
||||||
static $pb.PbList<ReconnectInfo> createRepeated() => new $pb.PbList<ReconnectInfo>();
|
static ReconnectInfo getDefault() {
|
||||||
static ReconnectInfo getDefault() => _defaultInstance ??= create()..freeze();
|
if (_defaultInstance == null)
|
||||||
|
_defaultInstance = new _ReadonlyReconnectInfo();
|
||||||
|
return _defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
static ReconnectInfo _defaultInstance;
|
static ReconnectInfo _defaultInstance;
|
||||||
static void $checkItem(ReconnectInfo v) {
|
static void $checkItem(ReconnectInfo v) {
|
||||||
if (v is! ReconnectInfo) $pb.checkItemFailed(v, _i.qualifiedMessageName);
|
if (v is! ReconnectInfo) checkItemFailed(v, 'ReconnectInfo');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get passed => $_get(0, false);
|
bool get passed => $_get(0, false);
|
||||||
set passed(bool v) { $_setBool(0, v); }
|
set passed(bool v) {
|
||||||
|
$_setBool(0, v);
|
||||||
|
}
|
||||||
|
|
||||||
bool hasPassed() => $_has(0);
|
bool hasPassed() => $_has(0);
|
||||||
void clearPassed() => clearField(1);
|
void clearPassed() => clearField(1);
|
||||||
|
|
||||||
List<int> get backoffMs => $_getList(1);
|
List<int> get backoffMs => $_getList(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _ReadonlyReconnectInfo extends ReconnectInfo with ReadonlyMessageMixin {}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
///
|
///
|
||||||
// Generated code. Do not modify.
|
// Generated code. Do not modify.
|
||||||
// source: messages.proto
|
|
||||||
///
|
///
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
// ignore_for_file: non_constant_identifier_names,library_prefixes
|
||||||
|
library grpc.testing_messages_pbenum;
|
||||||
|
|
||||||
// ignore_for_file: UNDEFINED_SHOWN_NAME,UNUSED_SHOWN_NAME
|
// ignore_for_file: UNDEFINED_SHOWN_NAME,UNUSED_SHOWN_NAME
|
||||||
import 'dart:core' show int, dynamic, String, List, Map;
|
import 'dart:core' show int, dynamic, String, List, Map;
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart';
|
||||||
|
|
||||||
class PayloadType extends $pb.ProtobufEnum {
|
class PayloadType extends ProtobufEnum {
|
||||||
static const PayloadType COMPRESSABLE = const PayloadType._(0, 'COMPRESSABLE');
|
static const PayloadType COMPRESSABLE =
|
||||||
|
const PayloadType._(0, 'COMPRESSABLE');
|
||||||
|
|
||||||
static const List<PayloadType> values = const <PayloadType>[
|
static const List<PayloadType> values = const <PayloadType>[
|
||||||
COMPRESSABLE,
|
COMPRESSABLE,
|
||||||
];
|
];
|
||||||
|
|
||||||
static final Map<int, PayloadType> _byValue = $pb.ProtobufEnum.initByValue(values);
|
static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
|
||||||
static PayloadType valueOf(int value) => _byValue[value];
|
static PayloadType valueOf(int value) => _byValue[value] as PayloadType;
|
||||||
static void $checkItem(PayloadType v) {
|
static void $checkItem(PayloadType v) {
|
||||||
if (v is! PayloadType) $pb.checkItemFailed(v, 'PayloadType');
|
if (v is! PayloadType) checkItemFailed(v, 'PayloadType');
|
||||||
}
|
}
|
||||||
|
|
||||||
const PayloadType._(int v, String n) : super(v, n);
|
const PayloadType._(int v, String n) : super(v, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
///
|
///
|
||||||
// Generated code. Do not modify.
|
// Generated code. Do not modify.
|
||||||
// source: test.proto
|
|
||||||
///
|
///
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
// ignore_for_file: non_constant_identifier_names,library_prefixes
|
||||||
|
library grpc.testing_test;
|
||||||
|
|
||||||
// ignore: UNUSED_SHOWN_NAME
|
// ignore: UNUSED_SHOWN_NAME
|
||||||
import 'dart:core' show int, bool, double, String, List, Map, override;
|
import 'dart:core' show int, bool, double, String, List, override;
|
||||||
|
|
||||||
|
|
|
@ -1,343 +1,307 @@
|
||||||
///
|
///
|
||||||
// Generated code. Do not modify.
|
// Generated code. Do not modify.
|
||||||
// source: test.proto
|
|
||||||
///
|
///
|
||||||
// ignore_for_file: non_constant_identifier_names,library_prefixes,unused_import
|
// ignore_for_file: non_constant_identifier_names,library_prefixes
|
||||||
|
library grpc.testing_test_pbgrpc;
|
||||||
|
|
||||||
import 'dart:async' as $async;
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:grpc/service_api.dart' as $grpc;
|
import 'package:grpc/grpc.dart';
|
||||||
import 'empty.pb.dart' as $0;
|
|
||||||
import 'messages.pb.dart' as $1;
|
import 'empty.pb.dart';
|
||||||
|
import 'messages.pb.dart';
|
||||||
export 'test.pb.dart';
|
export 'test.pb.dart';
|
||||||
|
|
||||||
class TestServiceClient extends $grpc.Client {
|
class TestServiceClient extends Client {
|
||||||
static final _$emptyCall = new $grpc.ClientMethod<$0.Empty, $0.Empty>(
|
static final _$emptyCall = new ClientMethod<Empty, Empty>(
|
||||||
'/grpc.testing.TestService/EmptyCall',
|
'/grpc.testing.TestService/EmptyCall',
|
||||||
($0.Empty value) => value.writeToBuffer(),
|
(Empty value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value));
|
(List<int> value) => new Empty.fromBuffer(value));
|
||||||
static final _$unaryCall =
|
static final _$unaryCall = new ClientMethod<SimpleRequest, SimpleResponse>(
|
||||||
new $grpc.ClientMethod<$1.SimpleRequest, $1.SimpleResponse>(
|
|
||||||
'/grpc.testing.TestService/UnaryCall',
|
'/grpc.testing.TestService/UnaryCall',
|
||||||
($1.SimpleRequest value) => value.writeToBuffer(),
|
(SimpleRequest value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $1.SimpleResponse.fromBuffer(value));
|
(List<int> value) => new SimpleResponse.fromBuffer(value));
|
||||||
static final _$cacheableUnaryCall =
|
static final _$cacheableUnaryCall =
|
||||||
new $grpc.ClientMethod<$1.SimpleRequest, $1.SimpleResponse>(
|
new ClientMethod<SimpleRequest, SimpleResponse>(
|
||||||
'/grpc.testing.TestService/CacheableUnaryCall',
|
'/grpc.testing.TestService/CacheableUnaryCall',
|
||||||
($1.SimpleRequest value) => value.writeToBuffer(),
|
(SimpleRequest value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $1.SimpleResponse.fromBuffer(value));
|
(List<int> value) => new SimpleResponse.fromBuffer(value));
|
||||||
static final _$streamingOutputCall = new $grpc.ClientMethod<
|
static final _$streamingOutputCall =
|
||||||
$1.StreamingOutputCallRequest, $1.StreamingOutputCallResponse>(
|
new ClientMethod<StreamingOutputCallRequest, StreamingOutputCallResponse>(
|
||||||
'/grpc.testing.TestService/StreamingOutputCall',
|
'/grpc.testing.TestService/StreamingOutputCall',
|
||||||
($1.StreamingOutputCallRequest value) => value.writeToBuffer(),
|
(StreamingOutputCallRequest value) => value.writeToBuffer(),
|
||||||
(List<int> value) =>
|
(List<int> value) =>
|
||||||
new $1.StreamingOutputCallResponse.fromBuffer(value));
|
new StreamingOutputCallResponse.fromBuffer(value));
|
||||||
static final _$streamingInputCall = new $grpc.ClientMethod<
|
static final _$streamingInputCall =
|
||||||
$1.StreamingInputCallRequest, $1.StreamingInputCallResponse>(
|
new ClientMethod<StreamingInputCallRequest, StreamingInputCallResponse>(
|
||||||
'/grpc.testing.TestService/StreamingInputCall',
|
'/grpc.testing.TestService/StreamingInputCall',
|
||||||
($1.StreamingInputCallRequest value) => value.writeToBuffer(),
|
(StreamingInputCallRequest value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $1.StreamingInputCallResponse.fromBuffer(value));
|
(List<int> value) =>
|
||||||
static final _$fullDuplexCall = new $grpc.ClientMethod<
|
new StreamingInputCallResponse.fromBuffer(value));
|
||||||
$1.StreamingOutputCallRequest, $1.StreamingOutputCallResponse>(
|
static final _$fullDuplexCall =
|
||||||
|
new ClientMethod<StreamingOutputCallRequest, StreamingOutputCallResponse>(
|
||||||
'/grpc.testing.TestService/FullDuplexCall',
|
'/grpc.testing.TestService/FullDuplexCall',
|
||||||
($1.StreamingOutputCallRequest value) => value.writeToBuffer(),
|
(StreamingOutputCallRequest value) => value.writeToBuffer(),
|
||||||
(List<int> value) =>
|
(List<int> value) =>
|
||||||
new $1.StreamingOutputCallResponse.fromBuffer(value));
|
new StreamingOutputCallResponse.fromBuffer(value));
|
||||||
static final _$halfDuplexCall = new $grpc.ClientMethod<
|
static final _$halfDuplexCall =
|
||||||
$1.StreamingOutputCallRequest, $1.StreamingOutputCallResponse>(
|
new ClientMethod<StreamingOutputCallRequest, StreamingOutputCallResponse>(
|
||||||
'/grpc.testing.TestService/HalfDuplexCall',
|
'/grpc.testing.TestService/HalfDuplexCall',
|
||||||
($1.StreamingOutputCallRequest value) => value.writeToBuffer(),
|
(StreamingOutputCallRequest value) => value.writeToBuffer(),
|
||||||
(List<int> value) =>
|
(List<int> value) =>
|
||||||
new $1.StreamingOutputCallResponse.fromBuffer(value));
|
new StreamingOutputCallResponse.fromBuffer(value));
|
||||||
static final _$unimplementedCall = new $grpc.ClientMethod<$0.Empty, $0.Empty>(
|
static final _$unimplementedCall = new ClientMethod<Empty, Empty>(
|
||||||
'/grpc.testing.TestService/UnimplementedCall',
|
'/grpc.testing.TestService/UnimplementedCall',
|
||||||
($0.Empty value) => value.writeToBuffer(),
|
(Empty value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value));
|
(List<int> value) => new Empty.fromBuffer(value));
|
||||||
|
|
||||||
TestServiceClient($grpc.ClientChannel channel, {$grpc.CallOptions options})
|
TestServiceClient(ClientChannel channel, {CallOptions options})
|
||||||
: super(channel, options: options);
|
: super(channel, options: options);
|
||||||
|
|
||||||
$grpc.ResponseFuture<$0.Empty> emptyCall($0.Empty request,
|
ResponseFuture<Empty> emptyCall(Empty request, {CallOptions options}) {
|
||||||
{$grpc.CallOptions options}) {
|
final call = $createCall(_$emptyCall, new Stream.fromIterable([request]),
|
||||||
final call = $createCall(
|
|
||||||
_$emptyCall, new $async.Stream.fromIterable([request]),
|
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseFuture<$1.SimpleResponse> unaryCall($1.SimpleRequest request,
|
ResponseFuture<SimpleResponse> unaryCall(SimpleRequest request,
|
||||||
{$grpc.CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(
|
final call = $createCall(_$unaryCall, new Stream.fromIterable([request]),
|
||||||
_$unaryCall, new $async.Stream.fromIterable([request]),
|
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseFuture<$1.SimpleResponse> cacheableUnaryCall(
|
ResponseFuture<SimpleResponse> cacheableUnaryCall(SimpleRequest request,
|
||||||
$1.SimpleRequest request,
|
{CallOptions options}) {
|
||||||
{$grpc.CallOptions options}) {
|
|
||||||
final call = $createCall(
|
final call = $createCall(
|
||||||
_$cacheableUnaryCall, new $async.Stream.fromIterable([request]),
|
_$cacheableUnaryCall, new Stream.fromIterable([request]),
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseStream<$1.StreamingOutputCallResponse> streamingOutputCall(
|
ResponseStream<StreamingOutputCallResponse> streamingOutputCall(
|
||||||
$1.StreamingOutputCallRequest request,
|
StreamingOutputCallRequest request,
|
||||||
{$grpc.CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(
|
final call = $createCall(
|
||||||
_$streamingOutputCall, new $async.Stream.fromIterable([request]),
|
_$streamingOutputCall, new Stream.fromIterable([request]),
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseStream(call);
|
return new ResponseStream(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseFuture<$1.StreamingInputCallResponse> streamingInputCall(
|
ResponseFuture<StreamingInputCallResponse> streamingInputCall(
|
||||||
$async.Stream<$1.StreamingInputCallRequest> request,
|
Stream<StreamingInputCallRequest> request,
|
||||||
{$grpc.CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(_$streamingInputCall, request, options: options);
|
final call = $createCall(_$streamingInputCall, request, options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseStream<$1.StreamingOutputCallResponse> fullDuplexCall(
|
ResponseStream<StreamingOutputCallResponse> fullDuplexCall(
|
||||||
$async.Stream<$1.StreamingOutputCallRequest> request,
|
Stream<StreamingOutputCallRequest> request,
|
||||||
{$grpc.CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(_$fullDuplexCall, request, options: options);
|
final call = $createCall(_$fullDuplexCall, request, options: options);
|
||||||
return new $grpc.ResponseStream(call);
|
return new ResponseStream(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseStream<$1.StreamingOutputCallResponse> halfDuplexCall(
|
ResponseStream<StreamingOutputCallResponse> halfDuplexCall(
|
||||||
$async.Stream<$1.StreamingOutputCallRequest> request,
|
Stream<StreamingOutputCallRequest> request,
|
||||||
{$grpc.CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(_$halfDuplexCall, request, options: options);
|
final call = $createCall(_$halfDuplexCall, request, options: options);
|
||||||
return new $grpc.ResponseStream(call);
|
return new ResponseStream(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseFuture<$0.Empty> unimplementedCall($0.Empty request,
|
ResponseFuture<Empty> unimplementedCall(Empty request,
|
||||||
{$grpc.CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(
|
final call = $createCall(
|
||||||
_$unimplementedCall, new $async.Stream.fromIterable([request]),
|
_$unimplementedCall, new Stream.fromIterable([request]),
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class TestServiceBase extends $grpc.Service {
|
abstract class TestServiceBase extends Service {
|
||||||
String get $name => 'grpc.testing.TestService';
|
String get $name => 'grpc.testing.TestService';
|
||||||
|
|
||||||
TestServiceBase() {
|
TestServiceBase() {
|
||||||
$addMethod(new $grpc.ServiceMethod<$0.Empty, $0.Empty>(
|
$addMethod(new ServiceMethod<Empty, Empty>(
|
||||||
'EmptyCall',
|
'EmptyCall',
|
||||||
emptyCall_Pre,
|
emptyCall_Pre,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value),
|
(List<int> value) => new Empty.fromBuffer(value),
|
||||||
($0.Empty value) => value.writeToBuffer()));
|
(Empty value) => value.writeToBuffer()));
|
||||||
$addMethod(new $grpc.ServiceMethod<$1.SimpleRequest, $1.SimpleResponse>(
|
$addMethod(new ServiceMethod<SimpleRequest, SimpleResponse>(
|
||||||
'UnaryCall',
|
'UnaryCall',
|
||||||
unaryCall_Pre,
|
unaryCall_Pre,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
(List<int> value) => new $1.SimpleRequest.fromBuffer(value),
|
(List<int> value) => new SimpleRequest.fromBuffer(value),
|
||||||
($1.SimpleResponse value) => value.writeToBuffer()));
|
(SimpleResponse value) => value.writeToBuffer()));
|
||||||
$addMethod(new $grpc.ServiceMethod<$1.SimpleRequest, $1.SimpleResponse>(
|
$addMethod(new ServiceMethod<SimpleRequest, SimpleResponse>(
|
||||||
'CacheableUnaryCall',
|
'CacheableUnaryCall',
|
||||||
cacheableUnaryCall_Pre,
|
cacheableUnaryCall_Pre,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
(List<int> value) => new $1.SimpleRequest.fromBuffer(value),
|
(List<int> value) => new SimpleRequest.fromBuffer(value),
|
||||||
($1.SimpleResponse value) => value.writeToBuffer()));
|
(SimpleResponse value) => value.writeToBuffer()));
|
||||||
$addMethod(new $grpc.ServiceMethod<$1.StreamingOutputCallRequest,
|
$addMethod(new ServiceMethod<StreamingOutputCallRequest,
|
||||||
$1.StreamingOutputCallResponse>(
|
StreamingOutputCallResponse>(
|
||||||
'StreamingOutputCall',
|
'StreamingOutputCall',
|
||||||
streamingOutputCall_Pre,
|
streamingOutputCall_Pre,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
(List<int> value) =>
|
(List<int> value) => new StreamingOutputCallRequest.fromBuffer(value),
|
||||||
new $1.StreamingOutputCallRequest.fromBuffer(value),
|
(StreamingOutputCallResponse value) => value.writeToBuffer()));
|
||||||
($1.StreamingOutputCallResponse value) => value.writeToBuffer()));
|
$addMethod(new ServiceMethod<StreamingInputCallRequest,
|
||||||
$addMethod(new $grpc.ServiceMethod<$1.StreamingInputCallRequest,
|
StreamingInputCallResponse>(
|
||||||
$1.StreamingInputCallResponse>(
|
|
||||||
'StreamingInputCall',
|
'StreamingInputCall',
|
||||||
streamingInputCall,
|
streamingInputCall,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
(List<int> value) => new $1.StreamingInputCallRequest.fromBuffer(value),
|
(List<int> value) => new StreamingInputCallRequest.fromBuffer(value),
|
||||||
($1.StreamingInputCallResponse value) => value.writeToBuffer()));
|
(StreamingInputCallResponse value) => value.writeToBuffer()));
|
||||||
$addMethod(new $grpc.ServiceMethod<$1.StreamingOutputCallRequest,
|
$addMethod(new ServiceMethod<StreamingOutputCallRequest,
|
||||||
$1.StreamingOutputCallResponse>(
|
StreamingOutputCallResponse>(
|
||||||
'FullDuplexCall',
|
'FullDuplexCall',
|
||||||
fullDuplexCall,
|
fullDuplexCall,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
(List<int> value) =>
|
(List<int> value) => new StreamingOutputCallRequest.fromBuffer(value),
|
||||||
new $1.StreamingOutputCallRequest.fromBuffer(value),
|
(StreamingOutputCallResponse value) => value.writeToBuffer()));
|
||||||
($1.StreamingOutputCallResponse value) => value.writeToBuffer()));
|
$addMethod(new ServiceMethod<StreamingOutputCallRequest,
|
||||||
$addMethod(new $grpc.ServiceMethod<$1.StreamingOutputCallRequest,
|
StreamingOutputCallResponse>(
|
||||||
$1.StreamingOutputCallResponse>(
|
|
||||||
'HalfDuplexCall',
|
'HalfDuplexCall',
|
||||||
halfDuplexCall,
|
halfDuplexCall,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
(List<int> value) =>
|
(List<int> value) => new StreamingOutputCallRequest.fromBuffer(value),
|
||||||
new $1.StreamingOutputCallRequest.fromBuffer(value),
|
(StreamingOutputCallResponse value) => value.writeToBuffer()));
|
||||||
($1.StreamingOutputCallResponse value) => value.writeToBuffer()));
|
|
||||||
$addMethod(new $grpc.ServiceMethod<$0.Empty, $0.Empty>(
|
|
||||||
'UnimplementedCall',
|
|
||||||
unimplementedCall_Pre,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value),
|
|
||||||
($0.Empty value) => value.writeToBuffer()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.Empty> emptyCall_Pre(
|
Future<Empty> emptyCall_Pre(ServiceCall call, Future request) async {
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
|
||||||
return emptyCall(call, await request);
|
return emptyCall(call, await request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$1.SimpleResponse> unaryCall_Pre(
|
Future<SimpleResponse> unaryCall_Pre(ServiceCall call, Future request) async {
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
|
||||||
return unaryCall(call, await request);
|
return unaryCall(call, await request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$1.SimpleResponse> cacheableUnaryCall_Pre(
|
Future<SimpleResponse> cacheableUnaryCall_Pre(
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
ServiceCall call, Future request) async {
|
||||||
return cacheableUnaryCall(call, await request);
|
return cacheableUnaryCall(call, await request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Stream<$1.StreamingOutputCallResponse> streamingOutputCall_Pre(
|
Stream<StreamingOutputCallResponse> streamingOutputCall_Pre(
|
||||||
$grpc.ServiceCall call, $async.Future request) async* {
|
ServiceCall call, Future request) async* {
|
||||||
yield* streamingOutputCall(
|
yield* streamingOutputCall(
|
||||||
call, (await request) as $1.StreamingOutputCallRequest);
|
call, (await request) as StreamingOutputCallRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.Empty> unimplementedCall_Pre(
|
Future<Empty> emptyCall(ServiceCall call, Empty request);
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
Future<SimpleResponse> unaryCall(ServiceCall call, SimpleRequest request);
|
||||||
return unimplementedCall(call, await request);
|
Future<SimpleResponse> cacheableUnaryCall(
|
||||||
|
ServiceCall call, SimpleRequest request);
|
||||||
|
Stream<StreamingOutputCallResponse> streamingOutputCall(
|
||||||
|
ServiceCall call, StreamingOutputCallRequest request);
|
||||||
|
Future<StreamingInputCallResponse> streamingInputCall(
|
||||||
|
ServiceCall call, Stream<StreamingInputCallRequest> request);
|
||||||
|
Stream<StreamingOutputCallResponse> fullDuplexCall(
|
||||||
|
ServiceCall call, Stream<StreamingOutputCallRequest> request);
|
||||||
|
Stream<StreamingOutputCallResponse> halfDuplexCall(
|
||||||
|
ServiceCall call, Stream<StreamingOutputCallRequest> request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.Empty> emptyCall($grpc.ServiceCall call, $0.Empty request);
|
class UnimplementedServiceClient extends Client {
|
||||||
$async.Future<$1.SimpleResponse> unaryCall(
|
static final _$unimplementedCall = new ClientMethod<Empty, Empty>(
|
||||||
$grpc.ServiceCall call, $1.SimpleRequest request);
|
|
||||||
$async.Future<$1.SimpleResponse> cacheableUnaryCall(
|
|
||||||
$grpc.ServiceCall call, $1.SimpleRequest request);
|
|
||||||
$async.Stream<$1.StreamingOutputCallResponse> streamingOutputCall(
|
|
||||||
$grpc.ServiceCall call, $1.StreamingOutputCallRequest request);
|
|
||||||
$async.Future<$1.StreamingInputCallResponse> streamingInputCall(
|
|
||||||
$grpc.ServiceCall call,
|
|
||||||
$async.Stream<$1.StreamingInputCallRequest> request);
|
|
||||||
$async.Stream<$1.StreamingOutputCallResponse> fullDuplexCall(
|
|
||||||
$grpc.ServiceCall call,
|
|
||||||
$async.Stream<$1.StreamingOutputCallRequest> request);
|
|
||||||
$async.Stream<$1.StreamingOutputCallResponse> halfDuplexCall(
|
|
||||||
$grpc.ServiceCall call,
|
|
||||||
$async.Stream<$1.StreamingOutputCallRequest> request);
|
|
||||||
$async.Future<$0.Empty> unimplementedCall(
|
|
||||||
$grpc.ServiceCall call, $0.Empty request);
|
|
||||||
}
|
|
||||||
|
|
||||||
class UnimplementedServiceClient extends $grpc.Client {
|
|
||||||
static final _$unimplementedCall = new $grpc.ClientMethod<$0.Empty, $0.Empty>(
|
|
||||||
'/grpc.testing.UnimplementedService/UnimplementedCall',
|
'/grpc.testing.UnimplementedService/UnimplementedCall',
|
||||||
($0.Empty value) => value.writeToBuffer(),
|
(Empty value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value));
|
(List<int> value) => new Empty.fromBuffer(value));
|
||||||
|
|
||||||
UnimplementedServiceClient($grpc.ClientChannel channel,
|
UnimplementedServiceClient(ClientChannel channel, {CallOptions options})
|
||||||
{$grpc.CallOptions options})
|
|
||||||
: super(channel, options: options);
|
: super(channel, options: options);
|
||||||
|
|
||||||
$grpc.ResponseFuture<$0.Empty> unimplementedCall($0.Empty request,
|
ResponseFuture<Empty> unimplementedCall(Empty request,
|
||||||
{$grpc.CallOptions options}) {
|
{CallOptions options}) {
|
||||||
final call = $createCall(
|
final call = $createCall(
|
||||||
_$unimplementedCall, new $async.Stream.fromIterable([request]),
|
_$unimplementedCall, new Stream.fromIterable([request]),
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class UnimplementedServiceBase extends $grpc.Service {
|
abstract class UnimplementedServiceBase extends Service {
|
||||||
String get $name => 'grpc.testing.UnimplementedService';
|
String get $name => 'grpc.testing.UnimplementedService';
|
||||||
|
|
||||||
UnimplementedServiceBase() {
|
UnimplementedServiceBase() {
|
||||||
$addMethod(new $grpc.ServiceMethod<$0.Empty, $0.Empty>(
|
$addMethod(new ServiceMethod<Empty, Empty>(
|
||||||
'UnimplementedCall',
|
'UnimplementedCall',
|
||||||
unimplementedCall_Pre,
|
unimplementedCall_Pre,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value),
|
(List<int> value) => new Empty.fromBuffer(value),
|
||||||
($0.Empty value) => value.writeToBuffer()));
|
(Empty value) => value.writeToBuffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.Empty> unimplementedCall_Pre(
|
Future<Empty> unimplementedCall_Pre(ServiceCall call, Future request) async {
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
|
||||||
return unimplementedCall(call, await request);
|
return unimplementedCall(call, await request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.Empty> unimplementedCall(
|
Future<Empty> unimplementedCall(ServiceCall call, Empty request);
|
||||||
$grpc.ServiceCall call, $0.Empty request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReconnectServiceClient extends $grpc.Client {
|
class ReconnectServiceClient extends Client {
|
||||||
static final _$start = new $grpc.ClientMethod<$1.ReconnectParams, $0.Empty>(
|
static final _$start = new ClientMethod<ReconnectParams, Empty>(
|
||||||
'/grpc.testing.ReconnectService/Start',
|
'/grpc.testing.ReconnectService/Start',
|
||||||
($1.ReconnectParams value) => value.writeToBuffer(),
|
(ReconnectParams value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value));
|
(List<int> value) => new Empty.fromBuffer(value));
|
||||||
static final _$stop = new $grpc.ClientMethod<$0.Empty, $1.ReconnectInfo>(
|
static final _$stop = new ClientMethod<Empty, ReconnectInfo>(
|
||||||
'/grpc.testing.ReconnectService/Stop',
|
'/grpc.testing.ReconnectService/Stop',
|
||||||
($0.Empty value) => value.writeToBuffer(),
|
(Empty value) => value.writeToBuffer(),
|
||||||
(List<int> value) => new $1.ReconnectInfo.fromBuffer(value));
|
(List<int> value) => new ReconnectInfo.fromBuffer(value));
|
||||||
|
|
||||||
ReconnectServiceClient($grpc.ClientChannel channel,
|
ReconnectServiceClient(ClientChannel channel, {CallOptions options})
|
||||||
{$grpc.CallOptions options})
|
|
||||||
: super(channel, options: options);
|
: super(channel, options: options);
|
||||||
|
|
||||||
$grpc.ResponseFuture<$0.Empty> start($1.ReconnectParams request,
|
ResponseFuture<Empty> start(ReconnectParams request, {CallOptions options}) {
|
||||||
{$grpc.CallOptions options}) {
|
final call = $createCall(_$start, new Stream.fromIterable([request]),
|
||||||
final call = $createCall(_$start, new $async.Stream.fromIterable([request]),
|
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpc.ResponseFuture<$1.ReconnectInfo> stop($0.Empty request,
|
ResponseFuture<ReconnectInfo> stop(Empty request, {CallOptions options}) {
|
||||||
{$grpc.CallOptions options}) {
|
final call = $createCall(_$stop, new Stream.fromIterable([request]),
|
||||||
final call = $createCall(_$stop, new $async.Stream.fromIterable([request]),
|
|
||||||
options: options);
|
options: options);
|
||||||
return new $grpc.ResponseFuture(call);
|
return new ResponseFuture(call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ReconnectServiceBase extends $grpc.Service {
|
abstract class ReconnectServiceBase extends Service {
|
||||||
String get $name => 'grpc.testing.ReconnectService';
|
String get $name => 'grpc.testing.ReconnectService';
|
||||||
|
|
||||||
ReconnectServiceBase() {
|
ReconnectServiceBase() {
|
||||||
$addMethod(new $grpc.ServiceMethod<$1.ReconnectParams, $0.Empty>(
|
$addMethod(new ServiceMethod<ReconnectParams, Empty>(
|
||||||
'Start',
|
'Start',
|
||||||
start_Pre,
|
start_Pre,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
(List<int> value) => new $1.ReconnectParams.fromBuffer(value),
|
(List<int> value) => new ReconnectParams.fromBuffer(value),
|
||||||
($0.Empty value) => value.writeToBuffer()));
|
(Empty value) => value.writeToBuffer()));
|
||||||
$addMethod(new $grpc.ServiceMethod<$0.Empty, $1.ReconnectInfo>(
|
$addMethod(new ServiceMethod<Empty, ReconnectInfo>(
|
||||||
'Stop',
|
'Stop',
|
||||||
stop_Pre,
|
stop_Pre,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
(List<int> value) => new $0.Empty.fromBuffer(value),
|
(List<int> value) => new Empty.fromBuffer(value),
|
||||||
($1.ReconnectInfo value) => value.writeToBuffer()));
|
(ReconnectInfo value) => value.writeToBuffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.Empty> start_Pre(
|
Future<Empty> start_Pre(ServiceCall call, Future request) async {
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
|
||||||
return start(call, await request);
|
return start(call, await request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$1.ReconnectInfo> stop_Pre(
|
Future<ReconnectInfo> stop_Pre(ServiceCall call, Future request) async {
|
||||||
$grpc.ServiceCall call, $async.Future request) async {
|
|
||||||
return stop(call, await request);
|
return stop(call, await request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$async.Future<$0.Empty> start(
|
Future<Empty> start(ServiceCall call, ReconnectParams request);
|
||||||
$grpc.ServiceCall call, $1.ReconnectParams request);
|
Future<ReconnectInfo> stop(ServiceCall call, Empty request);
|
||||||
$async.Future<$1.ReconnectInfo> stop(
|
|
||||||
$grpc.ServiceCall call, $0.Empty request);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,12 @@
|
||||||
export 'src/auth/auth.dart';
|
export 'src/auth/auth.dart';
|
||||||
|
|
||||||
export 'src/client/call.dart';
|
export 'src/client/call.dart';
|
||||||
export 'src/client/channel.dart' hide ClientChannel;
|
export 'src/client/channel.dart';
|
||||||
export 'src/client/client.dart';
|
export 'src/client/client.dart';
|
||||||
export 'src/client/common.dart';
|
export 'src/client/common.dart';
|
||||||
export 'src/client/connection.dart';
|
export 'src/client/connection.dart';
|
||||||
export 'src/client/http2_channel.dart' show ClientChannel;
|
|
||||||
export 'src/client/method.dart';
|
export 'src/client/method.dart';
|
||||||
export 'src/client/options.dart';
|
export 'src/client/options.dart';
|
||||||
export 'src/client/transport/http2_credentials.dart';
|
|
||||||
export 'src/client/transport/transport.dart';
|
|
||||||
|
|
||||||
export 'src/server/call.dart';
|
export 'src/server/call.dart';
|
||||||
export 'src/server/handler.dart';
|
export 'src/server/handler.dart';
|
||||||
|
@ -32,7 +29,6 @@ export 'src/server/interceptor.dart';
|
||||||
export 'src/server/server.dart';
|
export 'src/server/server.dart';
|
||||||
export 'src/server/service.dart';
|
export 'src/server/service.dart';
|
||||||
|
|
||||||
export 'src/shared/message.dart';
|
|
||||||
export 'src/shared/security.dart';
|
export 'src/shared/security.dart';
|
||||||
export 'src/shared/status.dart';
|
export 'src/shared/status.dart';
|
||||||
export 'src/shared/streams.dart';
|
export 'src/shared/streams.dart';
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
export 'src/auth/auth.dart';
|
|
||||||
|
|
||||||
export 'src/client/call.dart';
|
|
||||||
export 'src/client/channel.dart' hide ClientChannel;
|
|
||||||
export 'src/client/client.dart';
|
|
||||||
export 'src/client/common.dart';
|
|
||||||
export 'src/client/connection.dart';
|
|
||||||
export 'src/client/method.dart';
|
|
||||||
export 'src/client/options.dart';
|
|
||||||
export 'src/client/transport/transport.dart';
|
|
||||||
export 'src/client/web_channel.dart' show GrpcWebClientChannel;
|
|
||||||
|
|
||||||
export 'src/shared/status.dart';
|
|
||||||
export 'src/shared/streams.dart';
|
|
||||||
export 'src/shared/timeout.dart';
|
|
|
@ -24,4 +24,5 @@ export 'src/client/common.dart' show ResponseFuture, ResponseStream;
|
||||||
export 'src/client/method.dart' show ClientMethod;
|
export 'src/client/method.dart' show ClientMethod;
|
||||||
export 'src/client/options.dart' show CallOptions;
|
export 'src/client/options.dart' show CallOptions;
|
||||||
export 'src/server/call.dart' show ServiceCall;
|
export 'src/server/call.dart' show ServiceCall;
|
||||||
|
export 'src/server/server.dart' show Server;
|
||||||
export 'src/server/service.dart' show Service, ServiceMethod;
|
export 'src/server/service.dart' show Service, ServiceMethod;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
|
// Copyright (c) 2017, the gRPC project authors. Please see the AUTHORS file
|
||||||
// for details. All rights reserved.
|
// for details. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -15,14 +15,15 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:http2/transport.dart';
|
||||||
|
|
||||||
import '../shared/status.dart';
|
import '../shared/status.dart';
|
||||||
import '../shared/message.dart';
|
import '../shared/streams.dart';
|
||||||
|
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
import 'connection.dart';
|
import 'connection.dart';
|
||||||
import 'method.dart';
|
import 'method.dart';
|
||||||
import 'options.dart';
|
import 'options.dart';
|
||||||
import 'transport/transport.dart';
|
|
||||||
|
|
||||||
const _reservedHeaders = const [
|
const _reservedHeaders = const [
|
||||||
'content-type',
|
'content-type',
|
||||||
|
@ -44,9 +45,9 @@ class ClientCall<Q, R> implements Response {
|
||||||
|
|
||||||
Map<String, String> _headerMetadata;
|
Map<String, String> _headerMetadata;
|
||||||
|
|
||||||
GrpcTransportStream _stream;
|
TransportStream _stream;
|
||||||
StreamController<R> _responses;
|
StreamController<R> _responses;
|
||||||
StreamSubscription<List<int>> _requestSubscription;
|
StreamSubscription<StreamMessage> _requestSubscription;
|
||||||
StreamSubscription<GrpcMessage> _responseSubscription;
|
StreamSubscription<GrpcMessage> _responseSubscription;
|
||||||
|
|
||||||
bool isCancelled = false;
|
bool isCancelled = false;
|
||||||
|
@ -119,6 +120,8 @@ class ClientCall<Q, R> implements Response {
|
||||||
}
|
}
|
||||||
_requestSubscription = _requests
|
_requestSubscription = _requests
|
||||||
.map(_method.requestSerializer)
|
.map(_method.requestSerializer)
|
||||||
|
.map(GrpcHttpEncoder.frame)
|
||||||
|
.map<StreamMessage>((bytes) => new DataStreamMessage(bytes))
|
||||||
.handleError(_onRequestError)
|
.handleError(_onRequestError)
|
||||||
.listen(_stream.outgoingMessages.add,
|
.listen(_stream.outgoingMessages.add,
|
||||||
onError: _stream.outgoingMessages.addError,
|
onError: _stream.outgoingMessages.addError,
|
||||||
|
@ -140,7 +143,10 @@ class ClientCall<Q, R> implements Response {
|
||||||
if (_stream != null &&
|
if (_stream != null &&
|
||||||
_responses.hasListener &&
|
_responses.hasListener &&
|
||||||
_responseSubscription == null) {
|
_responseSubscription == null) {
|
||||||
_responseSubscription = _stream.incomingMessages.listen(_onResponseData,
|
_responseSubscription = _stream.incomingMessages
|
||||||
|
.transform(new GrpcHttpDecoder())
|
||||||
|
.transform(grpcDecompressor())
|
||||||
|
.listen(_onResponseData,
|
||||||
onError: _onResponseError,
|
onError: _onResponseError,
|
||||||
onDone: _onResponseDone,
|
onDone: _onResponseDone,
|
||||||
cancelOnError: true);
|
cancelOnError: true);
|
||||||
|
|
|
@ -21,28 +21,23 @@ import 'call.dart';
|
||||||
import 'connection.dart';
|
import 'connection.dart';
|
||||||
import 'method.dart';
|
import 'method.dart';
|
||||||
import 'options.dart';
|
import 'options.dart';
|
||||||
import 'transport/transport.dart';
|
|
||||||
|
|
||||||
typedef ConnectTransport = Future<Transport> Function(
|
|
||||||
String host, int port, ChannelOptions options);
|
|
||||||
|
|
||||||
/// A channel to a virtual RPC endpoint.
|
/// A channel to a virtual RPC endpoint.
|
||||||
///
|
///
|
||||||
/// For each RPC, the channel picks a [ClientConnection] to dispatch the call.
|
/// For each RPC, the channel picks a [ClientConnection] to dispatch the call.
|
||||||
/// RPCs on the same channel may be sent to different connections, depending on
|
/// RPCs on the same channel may be sent to different connections, depending on
|
||||||
/// load balancing settings.
|
/// load balancing settings.
|
||||||
abstract class ClientChannel {
|
class ClientChannel {
|
||||||
final String host;
|
final String host;
|
||||||
final int port;
|
final int port;
|
||||||
final ChannelOptions options;
|
final ChannelOptions options;
|
||||||
final ConnectTransport connectTransport;
|
|
||||||
|
|
||||||
// TODO(jakobr): Multiple connections, load balancing.
|
// TODO(jakobr): Multiple connections, load balancing.
|
||||||
ClientConnection _connection;
|
ClientConnection _connection;
|
||||||
|
|
||||||
bool _isShutdown = false;
|
bool _isShutdown = false;
|
||||||
|
|
||||||
ClientChannel(this.host, this.connectTransport,
|
ClientChannel(this.host,
|
||||||
{this.port = 443, this.options = const ChannelOptions()});
|
{this.port = 443, this.options = const ChannelOptions()});
|
||||||
|
|
||||||
/// Shuts down this channel.
|
/// Shuts down this channel.
|
||||||
|
@ -69,7 +64,7 @@ abstract class ClientChannel {
|
||||||
/// The connection may be shared between multiple RPCs.
|
/// The connection may be shared between multiple RPCs.
|
||||||
Future<ClientConnection> getConnection() async {
|
Future<ClientConnection> getConnection() async {
|
||||||
if (_isShutdown) throw new GrpcError.unavailable('Channel shutting down.');
|
if (_isShutdown) throw new GrpcError.unavailable('Channel shutting down.');
|
||||||
return _connection ??= new ClientConnection(host, port, options, connectTransport);
|
return _connection ??= new ClientConnection(host, port, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initiates a new RPC on this connection.
|
/// Initiates a new RPC on this connection.
|
||||||
|
|
|
@ -14,16 +14,17 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:grpc/src/client/channel.dart';
|
import 'package:http2/transport.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
import '../shared/status.dart';
|
import '../shared/timeout.dart';
|
||||||
|
|
||||||
import 'call.dart';
|
import 'call.dart';
|
||||||
import 'options.dart';
|
import 'options.dart';
|
||||||
|
|
||||||
import 'transport/transport.dart';
|
|
||||||
|
|
||||||
enum ConnectionState {
|
enum ConnectionState {
|
||||||
/// Actively trying to connect.
|
/// Actively trying to connect.
|
||||||
connecting,
|
connecting,
|
||||||
|
@ -45,38 +46,98 @@ enum ConnectionState {
|
||||||
///
|
///
|
||||||
/// RPCs made on a connection are always sent to the same endpoint.
|
/// RPCs made on a connection are always sent to the same endpoint.
|
||||||
class ClientConnection {
|
class ClientConnection {
|
||||||
|
static final _methodPost = new Header.ascii(':method', 'POST');
|
||||||
|
static final _schemeHttp = new Header.ascii(':scheme', 'http');
|
||||||
|
static final _schemeHttps = new Header.ascii(':scheme', 'https');
|
||||||
|
static final _contentTypeGrpc =
|
||||||
|
new Header.ascii('content-type', 'application/grpc');
|
||||||
|
static final _teTrailers = new Header.ascii('te', 'trailers');
|
||||||
|
static final _grpcAcceptEncoding =
|
||||||
|
new Header.ascii('grpc-accept-encoding', 'identity');
|
||||||
|
static final _userAgent = new Header.ascii('user-agent', 'dart-grpc/0.2.0');
|
||||||
|
|
||||||
final String host;
|
final String host;
|
||||||
final int port;
|
final int port;
|
||||||
final ChannelOptions options;
|
final ChannelOptions options;
|
||||||
final ConnectTransport connectTransport;
|
|
||||||
|
|
||||||
ConnectionState _state = ConnectionState.idle;
|
ConnectionState _state = ConnectionState.idle;
|
||||||
void Function(ClientConnection connection) onStateChanged;
|
void Function(ClientConnection connection) onStateChanged;
|
||||||
final _pendingCalls = <ClientCall>[];
|
final _pendingCalls = <ClientCall>[];
|
||||||
|
|
||||||
Transport _transport;
|
ClientTransportConnection _transport;
|
||||||
|
|
||||||
/// Used for idle and reconnect timeout, depending on [_state].
|
/// Used for idle and reconnect timeout, depending on [_state].
|
||||||
Timer _timer;
|
Timer _timer;
|
||||||
Duration _currentReconnectDelay;
|
Duration _currentReconnectDelay;
|
||||||
|
|
||||||
ClientConnection(this.host, this.port, this.options, this.connectTransport);
|
ClientConnection(this.host, this.port, this.options);
|
||||||
|
|
||||||
ConnectionState get state => _state;
|
ConnectionState get state => _state;
|
||||||
|
|
||||||
|
static List<Header> createCallHeaders(bool useTls, String authority,
|
||||||
|
String path, Duration timeout, Map<String, String> metadata) {
|
||||||
|
final headers = [
|
||||||
|
_methodPost,
|
||||||
|
useTls ? _schemeHttps : _schemeHttp,
|
||||||
|
new Header(ascii.encode(':path'), utf8.encode(path)),
|
||||||
|
new Header(ascii.encode(':authority'), utf8.encode(authority)),
|
||||||
|
];
|
||||||
|
if (timeout != null) {
|
||||||
|
headers.add(new Header.ascii('grpc-timeout', toTimeoutString(timeout)));
|
||||||
|
}
|
||||||
|
headers.addAll([
|
||||||
|
_contentTypeGrpc,
|
||||||
|
_teTrailers,
|
||||||
|
_grpcAcceptEncoding,
|
||||||
|
_userAgent,
|
||||||
|
]);
|
||||||
|
metadata?.forEach((key, value) {
|
||||||
|
headers.add(new Header(ascii.encode(key), utf8.encode(value)));
|
||||||
|
});
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
String get authority => options.credentials.authority ?? host;
|
String get authority => options.credentials.authority ?? host;
|
||||||
|
|
||||||
|
@visibleForTesting
|
||||||
|
Future<ClientTransportConnection> connectTransport() async {
|
||||||
|
final securityContext = options.credentials.securityContext;
|
||||||
|
|
||||||
|
var socket = await Socket.connect(host, port);
|
||||||
|
if (_state == ConnectionState.shutdown) {
|
||||||
|
socket.destroy();
|
||||||
|
throw 'Shutting down';
|
||||||
|
}
|
||||||
|
if (securityContext != null) {
|
||||||
|
socket = await SecureSocket.secure(socket,
|
||||||
|
host: authority,
|
||||||
|
context: securityContext,
|
||||||
|
onBadCertificate: _validateBadCertificate);
|
||||||
|
if (_state == ConnectionState.shutdown) {
|
||||||
|
socket.destroy();
|
||||||
|
throw 'Shutting down';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket.done.then(_handleSocketClosed);
|
||||||
|
return new ClientTransportConnection.viaSocket(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _validateBadCertificate(X509Certificate certificate) {
|
||||||
|
final validator = options.credentials.onBadCertificate;
|
||||||
|
if (validator == null) return false;
|
||||||
|
return validator(certificate, authority);
|
||||||
|
}
|
||||||
|
|
||||||
void _connect() {
|
void _connect() {
|
||||||
if (_state != ConnectionState.idle &&
|
if (_state != ConnectionState.idle &&
|
||||||
_state != ConnectionState.transientFailure) {
|
_state != ConnectionState.transientFailure) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_setState(ConnectionState.connecting);
|
_setState(ConnectionState.connecting);
|
||||||
connectTransport(host, port, options).then((transport) {
|
connectTransport().then((transport) {
|
||||||
_currentReconnectDelay = null;
|
_currentReconnectDelay = null;
|
||||||
_transport = transport;
|
_transport = transport;
|
||||||
_transport.onActiveStateChanged = _handleActiveStateChanged;
|
_transport.onActiveStateChanged = _handleActiveStateChanged;
|
||||||
_transport.onSocketClosed = _handleSocketClosed;
|
|
||||||
_setState(ConnectionState.ready);
|
_setState(ConnectionState.ready);
|
||||||
_pendingCalls.forEach(_startCall);
|
_pendingCalls.forEach(_startCall);
|
||||||
_pendingCalls.clear();
|
_pendingCalls.clear();
|
||||||
|
@ -99,9 +160,11 @@ class ClientConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GrpcTransportStream makeRequest(
|
ClientTransportStream makeRequest(
|
||||||
String path, Duration timeout, Map<String, String> metadata) {
|
String path, Duration timeout, Map<String, String> metadata) {
|
||||||
return _transport.makeRequest(path, timeout, metadata);
|
final headers = createCallHeaders(
|
||||||
|
options.credentials.isSecure, authority, path, timeout, metadata);
|
||||||
|
return _transport.makeRequest(headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _startCall(ClientCall call) {
|
void _startCall(ClientCall call) {
|
||||||
|
@ -198,7 +261,7 @@ class ClientConnection {
|
||||||
_connect();
|
_connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleSocketClosed() {
|
void _handleSocketClosed(_) {
|
||||||
_cancelTimer();
|
_cancelTimer();
|
||||||
_transport = null;
|
_transport = null;
|
||||||
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
import 'channel.dart' as channel;
|
|
||||||
import 'options.dart';
|
|
||||||
import 'transport/transport.dart';
|
|
||||||
import 'transport/http2_transport.dart';
|
|
||||||
|
|
||||||
@visibleForTesting
|
|
||||||
Future<Transport> connectTransport(
|
|
||||||
String host, int port, ChannelOptions options) async {
|
|
||||||
return Http2Transport(host, port, options)..connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClientChannel extends channel.ClientChannel {
|
|
||||||
ClientChannel(String host,
|
|
||||||
{int port = 443, ChannelOptions options = const ChannelOptions()})
|
|
||||||
: super(host, connectTransport, port: port, options: options);
|
|
||||||
}
|
|
|
@ -14,15 +14,18 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:meta/meta.dart';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import '../shared/security.dart';
|
||||||
|
|
||||||
const defaultIdleTimeout = const Duration(minutes: 5);
|
const defaultIdleTimeout = const Duration(minutes: 5);
|
||||||
|
|
||||||
typedef Duration BackoffStrategy(Duration lastBackoff);
|
typedef Duration BackoffStrategy(Duration lastBackoff);
|
||||||
|
|
||||||
// Backoff algorithm from https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
|
// Backoff algorithm from https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
|
||||||
|
const _minConnectTimeout = const Duration(seconds: 20);
|
||||||
const _initialBackoff = const Duration(seconds: 1);
|
const _initialBackoff = const Duration(seconds: 1);
|
||||||
const _maxBackoff = const Duration(seconds: 120);
|
const _maxBackoff = const Duration(seconds: 120);
|
||||||
const _multiplier = 1.6;
|
const _multiplier = 1.6;
|
||||||
|
@ -36,16 +39,54 @@ Duration defaultBackoffStrategy(Duration lastBackoff) {
|
||||||
return nextBackoff < _maxBackoff ? nextBackoff : _maxBackoff;
|
return nextBackoff < _maxBackoff ? nextBackoff : _maxBackoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handler for checking certificates that fail validation. If this handler
|
||||||
|
/// returns `true`, the bad certificate is allowed, and the TLS handshake can
|
||||||
|
/// continue. If the handler returns `false`, the TLS handshake fails, and the
|
||||||
|
/// connection is aborted.
|
||||||
|
typedef bool BadCertificateHandler(X509Certificate certificate, String host);
|
||||||
|
|
||||||
|
/// Bad certificate handler that disables all certificate checks.
|
||||||
|
/// DO NOT USE IN PRODUCTION!
|
||||||
|
/// Can be used during development and testing to accept self-signed
|
||||||
|
/// certificates, etc.
|
||||||
|
bool allowBadCertificates(X509Certificate certificate, String host) => true;
|
||||||
|
|
||||||
/// Options controlling TLS security settings on a [ClientChannel].
|
/// Options controlling TLS security settings on a [ClientChannel].
|
||||||
class ChannelCredentials {
|
class ChannelCredentials {
|
||||||
final bool isSecure;
|
final bool isSecure;
|
||||||
|
final List<int> _certificateBytes;
|
||||||
|
final String _certificatePassword;
|
||||||
final String authority;
|
final String authority;
|
||||||
|
final BadCertificateHandler onBadCertificate;
|
||||||
|
|
||||||
@visibleForOverriding
|
const ChannelCredentials._(this.isSecure, this._certificateBytes,
|
||||||
const ChannelCredentials(this.isSecure, this.authority);
|
this._certificatePassword, this.authority, this.onBadCertificate);
|
||||||
|
|
||||||
/// Disable TLS. RPCs are sent in clear text.
|
/// Disable TLS. RPCs are sent in clear text.
|
||||||
const ChannelCredentials.insecure() : this(false, null);
|
const ChannelCredentials.insecure() : this._(false, null, null, null, null);
|
||||||
|
|
||||||
|
/// Enable TLS and optionally specify the [certificates] to trust. If
|
||||||
|
/// [certificates] is not provided, the default trust store is used.
|
||||||
|
const ChannelCredentials.secure(
|
||||||
|
{List<int> certificates,
|
||||||
|
String password,
|
||||||
|
String authority,
|
||||||
|
BadCertificateHandler onBadCertificate})
|
||||||
|
: this._(true, certificates, password, authority, onBadCertificate);
|
||||||
|
|
||||||
|
SecurityContext get securityContext {
|
||||||
|
if (!isSecure) return null;
|
||||||
|
if (_certificateBytes != null) {
|
||||||
|
return createSecurityContext(false)
|
||||||
|
..setTrustedCertificatesBytes(_certificateBytes,
|
||||||
|
password: _certificatePassword);
|
||||||
|
}
|
||||||
|
final context = new SecurityContext(withTrustedRoots: true);
|
||||||
|
if (SecurityContext.alpnSupported) {
|
||||||
|
context.setAlpnProtocols(supportedAlpnProtocols, false);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Options controlling how connections are made on a [ClientChannel].
|
/// Options controlling how connections are made on a [ClientChannel].
|
||||||
|
@ -54,11 +95,14 @@ class ChannelOptions {
|
||||||
final Duration idleTimeout;
|
final Duration idleTimeout;
|
||||||
final BackoffStrategy backoffStrategy;
|
final BackoffStrategy backoffStrategy;
|
||||||
|
|
||||||
const ChannelOptions({
|
const ChannelOptions(
|
||||||
ChannelCredentials credentials,
|
{ChannelCredentials credentials,
|
||||||
this.idleTimeout = defaultIdleTimeout,
|
Duration idleTimeout,
|
||||||
this.backoffStrategy = defaultBackoffStrategy,
|
BackoffStrategy backoffStrategy =
|
||||||
}) : this.credentials = credentials ?? const ChannelCredentials.insecure();
|
defaultBackoffStrategy}) // Remove when dart-lang/sdk#31066 is fixed.
|
||||||
|
: this.credentials = credentials ?? const ChannelCredentials.secure(),
|
||||||
|
this.idleTimeout = idleTimeout ?? defaultIdleTimeout,
|
||||||
|
this.backoffStrategy = backoffStrategy ?? defaultBackoffStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides per-RPC metadata.
|
/// Provides per-RPC metadata.
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import '../../shared/security.dart';
|
|
||||||
import '../options.dart';
|
|
||||||
|
|
||||||
/// Handler for checking certificates that fail validation. If this handler
|
|
||||||
/// returns `true`, the bad certificate is allowed, and the TLS handshake can
|
|
||||||
/// continue. If the handler returns `false`, the TLS handshake fails, and the
|
|
||||||
/// connection is aborted.
|
|
||||||
typedef bool BadCertificateHandler(X509Certificate certificate, String host);
|
|
||||||
|
|
||||||
/// Bad certificate handler that disables all certificate checks.
|
|
||||||
/// DO NOT USE IN PRODUCTION!
|
|
||||||
/// Can be used during development and testing to accept self-signed
|
|
||||||
/// certificates, etc.
|
|
||||||
bool allowBadCertificates(X509Certificate certificate, String host) => true;
|
|
||||||
|
|
||||||
class Http2ChannelCredentials extends ChannelCredentials {
|
|
||||||
final List<int> _certificateBytes;
|
|
||||||
final String _certificatePassword;
|
|
||||||
final BadCertificateHandler onBadCertificate;
|
|
||||||
|
|
||||||
const Http2ChannelCredentials._(bool isSecure, String authority,
|
|
||||||
this._certificateBytes, this._certificatePassword, this.onBadCertificate)
|
|
||||||
: super(isSecure, authority);
|
|
||||||
|
|
||||||
/// Enable TLS and optionally specify the [certificates] to trust. If
|
|
||||||
/// [certificates] is not provided, the default trust store is used.
|
|
||||||
const Http2ChannelCredentials.secure(
|
|
||||||
{List<int> certificates,
|
|
||||||
String password,
|
|
||||||
String authority,
|
|
||||||
BadCertificateHandler onBadCertificate})
|
|
||||||
: this._(true, authority, certificates, password, onBadCertificate);
|
|
||||||
|
|
||||||
SecurityContext get securityContext {
|
|
||||||
if (!isSecure) return null;
|
|
||||||
if (_certificateBytes != null) {
|
|
||||||
return createSecurityContext(false)
|
|
||||||
..setTrustedCertificatesBytes(_certificateBytes,
|
|
||||||
password: _certificatePassword);
|
|
||||||
}
|
|
||||||
final context = new SecurityContext(withTrustedRoots: true);
|
|
||||||
context.setAlpnProtocols(supportedAlpnProtocols, false);
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,169 +0,0 @@
|
||||||
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:http2/transport.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
import '../../shared/message.dart';
|
|
||||||
import '../../shared/streams.dart';
|
|
||||||
import '../../shared/timeout.dart';
|
|
||||||
|
|
||||||
import '../options.dart';
|
|
||||||
|
|
||||||
import 'http2_credentials.dart';
|
|
||||||
import 'transport.dart';
|
|
||||||
|
|
||||||
class Http2TransportStream extends GrpcTransportStream {
|
|
||||||
TransportStream _transportStream;
|
|
||||||
StreamController<GrpcMessage> _incomingMessages;
|
|
||||||
StreamController<List<int>> _outgoingMessages;
|
|
||||||
|
|
||||||
Stream<GrpcMessage> get incomingMessages => _incomingMessages.stream;
|
|
||||||
StreamSink<List<int>> get outgoingMessages => _outgoingMessages.sink;
|
|
||||||
|
|
||||||
Http2TransportStream(this._transportStream) {
|
|
||||||
_incomingMessages = new StreamController();
|
|
||||||
_outgoingMessages = new StreamController();
|
|
||||||
|
|
||||||
_transportStream.incomingMessages
|
|
||||||
.transform(new GrpcHttpDecoder())
|
|
||||||
.transform(grpcDecompressor())
|
|
||||||
.pipe(_incomingMessages);
|
|
||||||
|
|
||||||
_outgoingMessages.stream
|
|
||||||
.map(frame)
|
|
||||||
.map<StreamMessage>((bytes) => new DataStreamMessage(bytes))
|
|
||||||
.handleError(_onRequestError)
|
|
||||||
.listen(_transportStream.outgoingMessages.add,
|
|
||||||
onError: _transportStream.outgoingMessages.addError,
|
|
||||||
onDone: _transportStream.outgoingMessages.close,
|
|
||||||
cancelOnError: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onRequestError() {
|
|
||||||
// TODO: Implement errors on requests
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> terminate() async {
|
|
||||||
await _incomingMessages.close();
|
|
||||||
await _outgoingMessages.close();
|
|
||||||
_transportStream.terminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Http2Transport extends Transport {
|
|
||||||
static final _methodPost = new Header.ascii(':method', 'POST');
|
|
||||||
static final _schemeHttp = new Header.ascii(':scheme', 'http');
|
|
||||||
static final _schemeHttps = new Header.ascii(':scheme', 'https');
|
|
||||||
static final _contentTypeGrpc =
|
|
||||||
new Header.ascii('content-type', 'application/grpc');
|
|
||||||
static final _teTrailers = new Header.ascii('te', 'trailers');
|
|
||||||
static final _grpcAcceptEncoding =
|
|
||||||
new Header.ascii('grpc-accept-encoding', 'identity');
|
|
||||||
static final _userAgent = new Header.ascii('user-agent', 'dart-grpc/0.2.0');
|
|
||||||
|
|
||||||
final String host;
|
|
||||||
final int port;
|
|
||||||
final ChannelOptions options;
|
|
||||||
|
|
||||||
@visibleForTesting
|
|
||||||
ClientTransportConnection transportConnection;
|
|
||||||
|
|
||||||
Http2Transport(this.host, this.port, this.options);
|
|
||||||
|
|
||||||
String get authority => options.credentials.authority ?? host;
|
|
||||||
|
|
||||||
static List<Header> createCallHeaders(bool useTls, String authority,
|
|
||||||
String path, Duration timeout, Map<String, String> metadata) {
|
|
||||||
final headers = [
|
|
||||||
_methodPost,
|
|
||||||
useTls ? _schemeHttps : _schemeHttp,
|
|
||||||
new Header(ascii.encode(':path'), utf8.encode(path)),
|
|
||||||
new Header(ascii.encode(':authority'), utf8.encode(authority)),
|
|
||||||
];
|
|
||||||
if (timeout != null) {
|
|
||||||
headers.add(new Header.ascii('grpc-timeout', toTimeoutString(timeout)));
|
|
||||||
}
|
|
||||||
headers.addAll([
|
|
||||||
_contentTypeGrpc,
|
|
||||||
_teTrailers,
|
|
||||||
_grpcAcceptEncoding,
|
|
||||||
_userAgent,
|
|
||||||
]);
|
|
||||||
metadata?.forEach((key, value) {
|
|
||||||
headers.add(new Header(ascii.encode(key), utf8.encode(value)));
|
|
||||||
});
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> connect() async {
|
|
||||||
var socket = await Socket.connect(host, port);
|
|
||||||
|
|
||||||
final credentials = options.credentials;
|
|
||||||
if (credentials is Http2ChannelCredentials) {
|
|
||||||
final securityContext = credentials.securityContext;
|
|
||||||
if (securityContext != null) {
|
|
||||||
socket = await SecureSocket.secure(socket,
|
|
||||||
host: authority,
|
|
||||||
context: securityContext,
|
|
||||||
onBadCertificate: _validateBadCertificate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
socket.done.then(_handleSocketClosed);
|
|
||||||
transportConnection = ClientTransportConnection.viaSocket(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
GrpcTransportStream makeRequest(
|
|
||||||
String path, Duration timeout, Map<String, String> metadata) {
|
|
||||||
final headers = createCallHeaders(
|
|
||||||
options.credentials.isSecure, authority, path, timeout, metadata);
|
|
||||||
final stream = transportConnection.makeRequest(headers);
|
|
||||||
return new Http2TransportStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> finish() async {
|
|
||||||
await transportConnection.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> terminate() async {
|
|
||||||
await transportConnection.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _validateBadCertificate(X509Certificate certificate) {
|
|
||||||
final credentials = options.credentials;
|
|
||||||
if (credentials is Http2ChannelCredentials) {
|
|
||||||
final validator = credentials.onBadCertificate;
|
|
||||||
|
|
||||||
if (validator == null) return false;
|
|
||||||
return validator(certificate, authority);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleSocketClosed(_) {
|
|
||||||
if (onSocketClosed != null) {
|
|
||||||
onSocketClosed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import '../../shared/message.dart';
|
|
||||||
|
|
||||||
typedef void SocketClosedHandler();
|
|
||||||
typedef void ActiveStateHandler(bool isActive);
|
|
||||||
|
|
||||||
abstract class GrpcTransportStream {
|
|
||||||
Stream<GrpcMessage> get incomingMessages;
|
|
||||||
StreamSink<List<int>> get outgoingMessages;
|
|
||||||
|
|
||||||
Future<void> terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class Transport {
|
|
||||||
ActiveStateHandler onActiveStateChanged;
|
|
||||||
SocketClosedHandler onSocketClosed;
|
|
||||||
|
|
||||||
Future<void> connect();
|
|
||||||
GrpcTransportStream makeRequest(
|
|
||||||
String path, Duration timeout, Map<String, String> metadata);
|
|
||||||
Future<void> finish();
|
|
||||||
Future<void> terminate();
|
|
||||||
}
|
|
|
@ -1,160 +0,0 @@
|
||||||
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:math';
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import '../../shared/message.dart';
|
|
||||||
import '../../shared/status.dart';
|
|
||||||
|
|
||||||
enum _GrpcWebParseState { Init, Length, Message }
|
|
||||||
|
|
||||||
class GrpcWebDecoder extends Converter<ByteBuffer, GrpcMessage> {
|
|
||||||
@override
|
|
||||||
GrpcMessage convert(ByteBuffer input) {
|
|
||||||
final sink = GrpcMessageSink();
|
|
||||||
startChunkedConversion(sink)
|
|
||||||
..add(input)
|
|
||||||
..close();
|
|
||||||
return sink.message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Sink<ByteBuffer> startChunkedConversion(Sink<GrpcMessage> sink) {
|
|
||||||
return _GrpcWebConversionSink(sink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _GrpcWebConversionSink extends ChunkedConversionSink<ByteBuffer> {
|
|
||||||
static const int frameTypeData = 0x00;
|
|
||||||
static const int frameTypeTrailers = 0x80;
|
|
||||||
|
|
||||||
final Sink<GrpcMessage> _out;
|
|
||||||
|
|
||||||
final _dataHeader = new Uint8List(4);
|
|
||||||
|
|
||||||
_GrpcWebParseState _state = _GrpcWebParseState.Init;
|
|
||||||
int _chunkOffset;
|
|
||||||
int _frameType;
|
|
||||||
int _dataOffset = 0;
|
|
||||||
Uint8List _data;
|
|
||||||
|
|
||||||
_GrpcWebConversionSink(this._out);
|
|
||||||
|
|
||||||
int _parseFrameType(List<int> chunkData) {
|
|
||||||
final frameType = chunkData[_chunkOffset];
|
|
||||||
_chunkOffset++;
|
|
||||||
if (frameType != frameTypeData && frameType != frameTypeTrailers) {
|
|
||||||
throw GrpcError.unimplemented('Invalid frame type: ${frameType}');
|
|
||||||
}
|
|
||||||
_state = _GrpcWebParseState.Length;
|
|
||||||
return frameType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _parseLength(List<int> chunkData) {
|
|
||||||
final chunkLength = chunkData.length;
|
|
||||||
|
|
||||||
final headerRemaining = _dataHeader.lengthInBytes - _dataOffset;
|
|
||||||
final chunkRemaining = chunkLength - _chunkOffset;
|
|
||||||
final toCopy = min(headerRemaining, chunkRemaining);
|
|
||||||
_dataHeader.setRange(
|
|
||||||
_dataOffset, _dataOffset + toCopy, chunkData, _chunkOffset);
|
|
||||||
_dataOffset += toCopy;
|
|
||||||
_chunkOffset += toCopy;
|
|
||||||
if (_dataOffset == _dataHeader.lengthInBytes) {
|
|
||||||
final dataLength = _dataHeader.buffer.asByteData().getUint32(0);
|
|
||||||
_dataOffset = 0;
|
|
||||||
_state = _GrpcWebParseState.Message;
|
|
||||||
if (dataLength == 0) {
|
|
||||||
// empty message
|
|
||||||
_finishMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
_data = new Uint8List(dataLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _parseMessage(List<int> chunkData) {
|
|
||||||
final dataRemaining = _data.lengthInBytes - _dataOffset;
|
|
||||||
if (dataRemaining > 0) {
|
|
||||||
final chunkRemaining = chunkData.length - _chunkOffset;
|
|
||||||
final toCopy = min(dataRemaining, chunkRemaining);
|
|
||||||
_data.setRange(
|
|
||||||
_dataOffset, _dataOffset + toCopy, chunkData, _chunkOffset);
|
|
||||||
_dataOffset += toCopy;
|
|
||||||
_chunkOffset += toCopy;
|
|
||||||
}
|
|
||||||
if (_dataOffset == _data.lengthInBytes) {
|
|
||||||
_finishMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _finishMessage() {
|
|
||||||
switch (_frameType) {
|
|
||||||
case frameTypeData:
|
|
||||||
_out.add(new GrpcData(_data, isCompressed: false));
|
|
||||||
break;
|
|
||||||
case frameTypeTrailers:
|
|
||||||
final stringData = String.fromCharCodes(_data);
|
|
||||||
final headers = _parseHttp1Headers(stringData);
|
|
||||||
_out.add(new GrpcMetadata(headers));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_state = _GrpcWebParseState.Init;
|
|
||||||
_data = null;
|
|
||||||
_dataOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> _parseHttp1Headers(String stringData) {
|
|
||||||
final chunks = stringData.trim().split('\r\n');
|
|
||||||
final headers = <String, String>{};
|
|
||||||
for (final chunk in chunks) {
|
|
||||||
final pos = chunk.indexOf(':');
|
|
||||||
headers[chunk.substring(0, pos).trim()] = chunk.substring(pos + 1).trim();
|
|
||||||
}
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void add(ByteBuffer chunk) {
|
|
||||||
_chunkOffset = 0;
|
|
||||||
final chunkData = chunk.asUint8List();
|
|
||||||
while (_chunkOffset < chunk.lengthInBytes) {
|
|
||||||
switch (_state) {
|
|
||||||
case _GrpcWebParseState.Init:
|
|
||||||
_frameType = _parseFrameType(chunkData);
|
|
||||||
break;
|
|
||||||
case _GrpcWebParseState.Length:
|
|
||||||
_parseLength(chunkData);
|
|
||||||
break;
|
|
||||||
case _GrpcWebParseState.Message:
|
|
||||||
_parseMessage(chunkData);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_chunkOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void close() {
|
|
||||||
if (_data != null || _dataOffset != 0) {
|
|
||||||
throw new GrpcError.unavailable('Closed in non-idle state');
|
|
||||||
}
|
|
||||||
_out.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
// Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:html';
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
import '../../shared/message.dart';
|
|
||||||
import 'transport.dart';
|
|
||||||
import 'web_streams.dart';
|
|
||||||
|
|
||||||
class XhrTransportStream implements GrpcTransportStream {
|
|
||||||
HttpRequest _request;
|
|
||||||
int _requestBytesRead = 0;
|
|
||||||
StreamController<ByteBuffer> _incomingProcessor;
|
|
||||||
StreamController<GrpcMessage> _incomingMessages;
|
|
||||||
StreamController<List<int>> _outgoingMessages;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<GrpcMessage> get incomingMessages => _incomingMessages.stream;
|
|
||||||
|
|
||||||
@override
|
|
||||||
StreamSink<List<int>> get outgoingMessages => _outgoingMessages.sink;
|
|
||||||
|
|
||||||
XhrTransportStream(this._request) {
|
|
||||||
_incomingProcessor = StreamController();
|
|
||||||
_incomingMessages = StreamController();
|
|
||||||
_outgoingMessages = StreamController();
|
|
||||||
|
|
||||||
_incomingProcessor.stream
|
|
||||||
.transform(GrpcWebDecoder())
|
|
||||||
.transform(grpcDecompressor())
|
|
||||||
.listen(_incomingMessages.add,
|
|
||||||
onError: _incomingMessages.addError,
|
|
||||||
onDone: _incomingMessages.close);
|
|
||||||
|
|
||||||
_outgoingMessages.stream
|
|
||||||
.map(frame)
|
|
||||||
.listen((data) => _request.send(data));
|
|
||||||
|
|
||||||
_request.onReadyStateChange.listen((data) {
|
|
||||||
final contentType = _request.getResponseHeader('Content-Type');
|
|
||||||
if (contentType == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_request.readyState == HttpRequest.HEADERS_RECEIVED) {
|
|
||||||
if (contentType.startsWith('application/grpc')) {
|
|
||||||
if (_request.response == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force a metadata message with headers
|
|
||||||
final headers = GrpcMetadata(_request.responseHeaders);
|
|
||||||
_incomingMessages.add(headers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_request.readyState == HttpRequest.DONE) {
|
|
||||||
_incomingProcessor.close();
|
|
||||||
_outgoingMessages.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_request.onProgress.listen((_) {
|
|
||||||
// use response over responseText as most browsers don't support
|
|
||||||
// using responseText during an onProgress event.
|
|
||||||
final responseString = _request.response as String;
|
|
||||||
final bytes = Uint8List.fromList(
|
|
||||||
responseString.substring(_requestBytesRead).codeUnits)
|
|
||||||
.buffer;
|
|
||||||
_requestBytesRead = responseString.length;
|
|
||||||
_incomingProcessor.add(bytes);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> terminate() async {
|
|
||||||
await _incomingProcessor.close();
|
|
||||||
await _outgoingMessages.close();
|
|
||||||
_request.abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class XhrTransport extends Transport {
|
|
||||||
final String host;
|
|
||||||
final int port;
|
|
||||||
|
|
||||||
HttpRequest _request;
|
|
||||||
|
|
||||||
XhrTransport(this.host, this.port);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> connect() async {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> finish() async {}
|
|
||||||
|
|
||||||
@visibleForTesting
|
|
||||||
void initializeRequest(HttpRequest request, Map<String, String> metadata) {
|
|
||||||
for (final header in metadata.keys) {
|
|
||||||
request.setRequestHeader(header, metadata[header]);
|
|
||||||
}
|
|
||||||
request.setRequestHeader('Content-Type', 'application/grpc-web+proto');
|
|
||||||
request.setRequestHeader('X-User-Agent', 'grpc-web-dart/0.1');
|
|
||||||
request.setRequestHeader('X-Grpc-Web', '1');
|
|
||||||
// Overriding the mimetype allows us to stream and parse the data
|
|
||||||
request.overrideMimeType('text/plain; charset=x-user-defined');
|
|
||||||
request.responseType = 'text';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
GrpcTransportStream makeRequest(
|
|
||||||
String path, Duration timeout, Map<String, String> metadata) {
|
|
||||||
_request = HttpRequest();
|
|
||||||
_request.open('POST', '${host}:${port}${path}');
|
|
||||||
|
|
||||||
initializeRequest(_request, metadata);
|
|
||||||
|
|
||||||
return XhrTransportStream(_request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> terminate() async {}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
// Copyright (c) 2019, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
import 'package:grpc/src/client/options.dart';
|
|
||||||
import 'package:grpc/src/client/transport/transport.dart';
|
|
||||||
import 'package:grpc/src/client/transport/xhr_transport.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
import 'channel.dart';
|
|
||||||
|
|
||||||
@visibleForTesting
|
|
||||||
Future<Transport> connectXhrTransport(
|
|
||||||
String host, int port, ChannelOptions _) async {
|
|
||||||
return XhrTransport(host, port)..connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
class GrpcWebClientChannel extends ClientChannel {
|
|
||||||
GrpcWebClientChannel.xhr(String host,
|
|
||||||
{int port = 443}) : super(host, connectXhrTransport, port: port);
|
|
||||||
}
|
|
|
@ -18,7 +18,6 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:http2/transport.dart';
|
import 'package:http2/transport.dart';
|
||||||
|
|
||||||
import '../shared/message.dart';
|
|
||||||
import '../shared/status.dart';
|
import '../shared/status.dart';
|
||||||
import '../shared/streams.dart';
|
import '../shared/streams.dart';
|
||||||
import '../shared/timeout.dart';
|
import '../shared/timeout.dart';
|
||||||
|
@ -229,7 +228,7 @@ class ServerHandler extends ServiceCall {
|
||||||
if (!_headersSent) {
|
if (!_headersSent) {
|
||||||
sendHeaders();
|
sendHeaders();
|
||||||
}
|
}
|
||||||
_stream.sendData(frame(bytes));
|
_stream.sendData(GrpcHttpEncoder.frame(bytes));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
final grpcError =
|
final grpcError =
|
||||||
new GrpcError.internal('Error sending response: $error');
|
new GrpcError.internal('Error sending response: $error');
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
abstract class GrpcMessage {}
|
|
||||||
|
|
||||||
class GrpcMetadata extends GrpcMessage {
|
|
||||||
final Map<String, String> metadata;
|
|
||||||
GrpcMetadata(this.metadata);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'gRPC Metadata ($metadata)';
|
|
||||||
}
|
|
||||||
|
|
||||||
class GrpcData extends GrpcMessage {
|
|
||||||
final List<int> data;
|
|
||||||
final bool isCompressed;
|
|
||||||
GrpcData(this.data, {this.isCompressed});
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'gRPC Data (${data.length} bytes)';
|
|
||||||
}
|
|
||||||
|
|
||||||
class GrpcMessageSink extends Sink<GrpcMessage> {
|
|
||||||
GrpcMessage message;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void add(GrpcMessage data) {
|
|
||||||
if (message != null) {
|
|
||||||
throw 'Too many messages received!';
|
|
||||||
}
|
|
||||||
message = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void close() {
|
|
||||||
if (message == null) {
|
|
||||||
throw 'No messages received!';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<int> frame(List<int> payload) {
|
|
||||||
final payloadLength = payload.length;
|
|
||||||
final bytes = new Uint8List(payloadLength + 5);
|
|
||||||
final header = bytes.buffer.asByteData(0, 5);
|
|
||||||
header.setUint8(0, 0); // TODO(dart-lang/grpc-dart#6): Handle compression
|
|
||||||
header.setUint32(1, payloadLength);
|
|
||||||
bytes.setRange(5, bytes.length, payload);
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamTransformer<GrpcMessage, GrpcMessage> grpcDecompressor() =>
|
|
||||||
new StreamTransformer<GrpcMessage, GrpcMessage>.fromHandlers(
|
|
||||||
handleData: (GrpcMessage value, EventSink<GrpcMessage> sink) {
|
|
||||||
if (value is GrpcData) {
|
|
||||||
if (value.isCompressed) {
|
|
||||||
// TODO(dart-lang/grpc-dart#6): Actually handle decompression.
|
|
||||||
sink.add(new GrpcData(value.data, isCompressed: false));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sink.add(value);
|
|
||||||
});
|
|
|
@ -20,9 +20,40 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:http2/transport.dart';
|
import 'package:http2/transport.dart';
|
||||||
|
|
||||||
import 'message.dart';
|
|
||||||
import 'status.dart';
|
import 'status.dart';
|
||||||
|
|
||||||
|
abstract class GrpcMessage {}
|
||||||
|
|
||||||
|
class GrpcMetadata extends GrpcMessage {
|
||||||
|
final Map<String, String> metadata;
|
||||||
|
GrpcMetadata(this.metadata);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'gRPC Metadata ($metadata)';
|
||||||
|
}
|
||||||
|
|
||||||
|
class GrpcData extends GrpcMessage {
|
||||||
|
final List<int> data;
|
||||||
|
final bool isCompressed;
|
||||||
|
GrpcData(this.data, {this.isCompressed});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'gRPC Data (${data.length} bytes)';
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamTransformer<GrpcMessage, GrpcMessage> grpcDecompressor() =>
|
||||||
|
new StreamTransformer<GrpcMessage, GrpcMessage>.fromHandlers(
|
||||||
|
handleData: (GrpcMessage value, EventSink<GrpcMessage> sink) {
|
||||||
|
if (value is GrpcData) {
|
||||||
|
if (value.isCompressed) {
|
||||||
|
// TODO(dart-lang/grpc-dart#6): Actually handle decompression.
|
||||||
|
sink.add(new GrpcData(value.data, isCompressed: false));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sink.add(value);
|
||||||
|
});
|
||||||
|
|
||||||
class GrpcHttpEncoder extends Converter<GrpcMessage, StreamMessage> {
|
class GrpcHttpEncoder extends Converter<GrpcMessage, StreamMessage> {
|
||||||
@override
|
@override
|
||||||
StreamMessage convert(GrpcMessage input) {
|
StreamMessage convert(GrpcMessage input) {
|
||||||
|
@ -37,12 +68,22 @@ class GrpcHttpEncoder extends Converter<GrpcMessage, StreamMessage> {
|
||||||
}
|
}
|
||||||
throw new GrpcError.internal('Unexpected message type');
|
throw new GrpcError.internal('Unexpected message type');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<int> frame(List<int> payload) {
|
||||||
|
final payloadLength = payload.length;
|
||||||
|
final bytes = new Uint8List(payloadLength + 5);
|
||||||
|
final header = bytes.buffer.asByteData(0, 5);
|
||||||
|
header.setUint8(0, 0); // TODO(dart-lang/grpc-dart#6): Handle compression
|
||||||
|
header.setUint32(1, payloadLength);
|
||||||
|
bytes.setRange(5, bytes.length, payload);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GrpcHttpDecoder extends Converter<StreamMessage, GrpcMessage> {
|
class GrpcHttpDecoder extends Converter<StreamMessage, GrpcMessage> {
|
||||||
@override
|
@override
|
||||||
GrpcMessage convert(StreamMessage input) {
|
GrpcMessage convert(StreamMessage input) {
|
||||||
final sink = new GrpcMessageSink();
|
final sink = new _GrpcMessageSink();
|
||||||
startChunkedConversion(sink)
|
startChunkedConversion(sink)
|
||||||
..add(input)
|
..add(input)
|
||||||
..close();
|
..close();
|
||||||
|
@ -142,3 +183,22 @@ class _GrpcMessageConversionSink extends ChunkedConversionSink<StreamMessage> {
|
||||||
_out.close();
|
_out.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _GrpcMessageSink extends Sink<GrpcMessage> {
|
||||||
|
GrpcMessage message;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void add(GrpcMessage data) {
|
||||||
|
if (message != null) {
|
||||||
|
throw 'Too many messages received!';
|
||||||
|
}
|
||||||
|
message = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void close() {
|
||||||
|
if (message == null) {
|
||||||
|
throw 'No messages received!';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: grpc
|
name: grpc
|
||||||
description: Dart implementation of gRPC, a high performance, open-source universal RPC framework.
|
description: Dart implementation of gRPC, a high performance, open-source universal RPC framework.
|
||||||
version: 1.1.0
|
version: 1.0.1
|
||||||
author: Dart Team <misc@dartlang.org>
|
author: Dart Team <misc@dartlang.org>
|
||||||
homepage: https://github.com/dart-lang/grpc-dart
|
homepage: https://github.com/dart-lang/grpc-dart
|
||||||
|
|
||||||
|
@ -8,14 +8,12 @@ environment:
|
||||||
sdk: '>=2.0.0 <3.0.0'
|
sdk: '>=2.0.0 <3.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
async: '>=1.13.3 <3.0.0'
|
||||||
googleapis_auth: ^0.2.5+3
|
googleapis_auth: ^0.2.5+3
|
||||||
meta: ^1.0.5
|
meta: ^1.0.5
|
||||||
http: '>=0.11.3+17 <0.13.0'
|
http: '>=0.11.3+17 <0.13.0'
|
||||||
http2: '>=0.1.7 <2.0.0'
|
http2: '>=0.1.7 <2.0.0'
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^0.10.0
|
|
||||||
build_test: ^0.10.3
|
|
||||||
build_web_compilers: ^0.4.3
|
|
||||||
mockito: ^4.0.0
|
mockito: ^4.0.0
|
||||||
test: ^1.5.0
|
test: ^1.5.0
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:grpc/grpc.dart';
|
import 'package:grpc/grpc.dart';
|
||||||
import 'package:grpc/src/shared/message.dart';
|
import 'package:http2/transport.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../src/client_utils.dart';
|
import 'src/client_utils.dart';
|
||||||
import '../src/utils.dart';
|
import 'src/utils.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
const dummyValue = 0;
|
const dummyValue = 0;
|
||||||
|
@ -39,8 +39,8 @@ void main() {
|
||||||
const requestValue = 17;
|
const requestValue = 17;
|
||||||
const responseValue = 19;
|
const responseValue = 19;
|
||||||
|
|
||||||
void handleRequest(List<int> message) {
|
void handleRequest(StreamMessage message) {
|
||||||
final data = validateClientDataMessage(message);
|
final data = validateDataMessage(message);
|
||||||
expect(mockDecode(data.data), requestValue);
|
expect(mockDecode(data.data), requestValue);
|
||||||
|
|
||||||
harness
|
harness
|
||||||
|
@ -63,8 +63,8 @@ void main() {
|
||||||
|
|
||||||
var index = 0;
|
var index = 0;
|
||||||
|
|
||||||
void handleRequest(List<int> message) {
|
void handleRequest(StreamMessage message) {
|
||||||
final data = validateClientDataMessage(message);
|
final data = validateDataMessage(message);
|
||||||
expect(mockDecode(data.data), requests[index++]);
|
expect(mockDecode(data.data), requests[index++]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ void main() {
|
||||||
const request = 4;
|
const request = 4;
|
||||||
const responses = const [3, 17, 9];
|
const responses = const [3, 17, 9];
|
||||||
|
|
||||||
void handleRequest(List<int> message) {
|
void handleRequest(StreamMessage message) {
|
||||||
final data = validateClientDataMessage(message);
|
final data = validateDataMessage(message);
|
||||||
expect(mockDecode(data.data), request);
|
expect(mockDecode(data.data), request);
|
||||||
|
|
||||||
harness.sendResponseHeader();
|
harness.sendResponseHeader();
|
||||||
|
@ -112,8 +112,8 @@ void main() {
|
||||||
|
|
||||||
var index = 0;
|
var index = 0;
|
||||||
|
|
||||||
void handleRequest(List<int> message) {
|
void handleRequest(StreamMessage message) {
|
||||||
final data = validateClientDataMessage(message);
|
final data = validateDataMessage(message);
|
||||||
expect(mockDecode(data.data), requests[index]);
|
expect(mockDecode(data.data), requests[index]);
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
|
@ -244,11 +244,10 @@ void main() {
|
||||||
const customStatusMessage = 'Custom message';
|
const customStatusMessage = 'Custom message';
|
||||||
|
|
||||||
void handleRequest(_) {
|
void handleRequest(_) {
|
||||||
final headers = <String, String>{
|
harness.toClient.add(new HeadersStreamMessage([
|
||||||
'grpc-status': '$customStatusCode',
|
new Header.ascii('grpc-status', '$customStatusCode'),
|
||||||
'grpc-message': customStatusMessage
|
new Header.ascii('grpc-message', customStatusMessage)
|
||||||
};
|
], endStream: true));
|
||||||
harness.toClient.add(new GrpcMetadata(headers));
|
|
||||||
harness.toClient.close();
|
harness.toClient.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,8 +312,8 @@ void main() {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<Null> makeUnaryCall() async {
|
Future<void> makeUnaryCall() async {
|
||||||
void handleRequest(List<int> message) {
|
void handleRequest(StreamMessage message) {
|
||||||
harness
|
harness
|
||||||
..sendResponseHeader()
|
..sendResponseHeader()
|
||||||
..sendResponseValue(1)
|
..sendResponseValue(1)
|
|
@ -1,162 +0,0 @@
|
||||||
// Copyright (c) 2017, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
@TestOn('vm')
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:grpc/grpc.dart';
|
|
||||||
import 'package:grpc/src/client/transport/http2_credentials.dart';
|
|
||||||
import 'package:grpc/src/client/transport/http2_transport.dart';
|
|
||||||
|
|
||||||
import 'package:http2/transport.dart';
|
|
||||||
import 'package:mockito/mockito.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
|
|
||||||
import '../src/utils.dart';
|
|
||||||
|
|
||||||
class MockTransport extends Mock implements ClientTransportConnection {}
|
|
||||||
|
|
||||||
class MockStream extends Mock implements ClientTransportStream {}
|
|
||||||
|
|
||||||
typedef void VerifyHeadersCallback(List<Header> headers);
|
|
||||||
|
|
||||||
class MockHttp2Transport extends Http2Transport {
|
|
||||||
MockStream mockClientStream;
|
|
||||||
VerifyHeadersCallback onVerifyHeaders;
|
|
||||||
|
|
||||||
StreamController<StreamMessage> fromClient;
|
|
||||||
StreamController<StreamMessage> toClient;
|
|
||||||
|
|
||||||
MockHttp2Transport(String host, int port, ChannelOptions options)
|
|
||||||
: super(host, port, options);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> connect() async {
|
|
||||||
transportConnection = MockTransport();
|
|
||||||
|
|
||||||
when(transportConnection.makeRequest(any)).thenAnswer((call) {
|
|
||||||
if (onVerifyHeaders != null) {
|
|
||||||
onVerifyHeaders(call.positionalArguments[0]);
|
|
||||||
}
|
|
||||||
mockClientStream = new MockStream();
|
|
||||||
fromClient = StreamController<StreamMessage>();
|
|
||||||
toClient = StreamController<StreamMessage>();
|
|
||||||
when(mockClientStream.outgoingMessages)
|
|
||||||
.thenAnswer((_) => fromClient.sink);
|
|
||||||
when(mockClientStream.incomingMessages)
|
|
||||||
.thenAnswer((_) => toClient.stream);
|
|
||||||
|
|
||||||
return mockClientStream;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> terminate() async {
|
|
||||||
fromClient.close();
|
|
||||||
toClient.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
final MockHttp2Transport transport = new MockHttp2Transport(
|
|
||||||
'host',
|
|
||||||
9999,
|
|
||||||
ChannelOptions(
|
|
||||||
credentials: new Http2ChannelCredentials.secure(authority: 'test')));
|
|
||||||
|
|
||||||
setUp(() {
|
|
||||||
transport.connect();
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() {
|
|
||||||
transport.terminate();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Make request passes proper headers', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
"parameter_1": "value_1",
|
|
||||||
"parameter_2": "value_2"
|
|
||||||
};
|
|
||||||
|
|
||||||
transport.onVerifyHeaders = (headers) {
|
|
||||||
final headerMap = headersToMap(headers);
|
|
||||||
validateRequestHeaders(headerMap,
|
|
||||||
path: 'test_path',
|
|
||||||
customHeaders: metadata,
|
|
||||||
timeout: toTimeoutString(Duration(seconds: 10)));
|
|
||||||
};
|
|
||||||
|
|
||||||
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Sent data converted to StreamMessages properly', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
"parameter_1": "value_1",
|
|
||||||
"parameter_2": "value_2"
|
|
||||||
};
|
|
||||||
|
|
||||||
final stream =
|
|
||||||
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
|
|
||||||
|
|
||||||
transport.fromClient.stream.listen((message) {
|
|
||||||
final dataMessage = validateDataMessage(message);
|
|
||||||
expect(dataMessage.data.length, 10);
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.outgoingMessages.add(List.filled(10, 0));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('StreamMessages deserializes headers properly', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
"parameter_1": "value_1",
|
|
||||||
"parameter_2": "value_2"
|
|
||||||
};
|
|
||||||
|
|
||||||
final stream =
|
|
||||||
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
|
|
||||||
|
|
||||||
stream.incomingMessages.listen((message) {
|
|
||||||
expect(message, TypeMatcher<GrpcMetadata>());
|
|
||||||
if (message is GrpcMetadata) {
|
|
||||||
message.metadata.forEach((key, value) {
|
|
||||||
expect(value, metadata[key]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final httpMessage = GrpcHttpEncoder().convert(GrpcMetadata(metadata));
|
|
||||||
transport.toClient.add(httpMessage);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('StreamMessages deserializes data properly', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
"parameter_1": "value_1",
|
|
||||||
"parameter_2": "value_2"
|
|
||||||
};
|
|
||||||
|
|
||||||
final stream =
|
|
||||||
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
|
|
||||||
final data = List<int>.filled(10, 0);
|
|
||||||
stream.incomingMessages.listen((message) {
|
|
||||||
expect(message, TypeMatcher<GrpcData>());
|
|
||||||
if (message is GrpcData) {
|
|
||||||
expect(message.data, equals(data));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final httpMessage = GrpcHttpEncoder().convert(GrpcData(data));
|
|
||||||
transport.toClient.add(httpMessage);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,214 +0,0 @@
|
||||||
// Copyright (c) 2017, the gRPC project authors. Please see the AUTHORS file
|
|
||||||
// for details. All rights reserved.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
@TestOn('browser')
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'dart:html';
|
|
||||||
|
|
||||||
import 'package:grpc/grpc.dart';
|
|
||||||
import 'package:grpc/src/client/transport/xhr_transport.dart';
|
|
||||||
import 'package:grpc/src/shared/message.dart';
|
|
||||||
import 'package:mockito/mockito.dart';
|
|
||||||
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
|
|
||||||
class MockHttpRequest extends Mock implements HttpRequest {}
|
|
||||||
|
|
||||||
class MockXhrTransport extends XhrTransport {
|
|
||||||
StreamController<Event> readyStateChangeStream = StreamController<Event>();
|
|
||||||
StreamController<ProgressEvent> progressStream =
|
|
||||||
StreamController<ProgressEvent>();
|
|
||||||
|
|
||||||
MockHttpRequest mockRequest;
|
|
||||||
|
|
||||||
MockXhrTransport(this.mockRequest) : super('test', 8080) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
GrpcTransportStream makeRequest(
|
|
||||||
String path, Duration timeout, Map<String, String> metadata) {
|
|
||||||
when(mockRequest.onReadyStateChange)
|
|
||||||
.thenAnswer((_) => readyStateChangeStream.stream);
|
|
||||||
when(mockRequest.onProgress).thenAnswer((_) => progressStream.stream);
|
|
||||||
|
|
||||||
initializeRequest(mockRequest, metadata);
|
|
||||||
|
|
||||||
return XhrTransportStream(mockRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> terminate() async {
|
|
||||||
readyStateChangeStream.close();
|
|
||||||
progressStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
test('Make request sends correct headers', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
'parameter_1': 'value_1',
|
|
||||||
'parameter_2': 'value_2'
|
|
||||||
};
|
|
||||||
|
|
||||||
final mockRequest = MockHttpRequest();
|
|
||||||
final transport = MockXhrTransport(mockRequest);
|
|
||||||
|
|
||||||
transport.makeRequest('path', Duration(seconds: 10), metadata);
|
|
||||||
|
|
||||||
verify(mockRequest.setRequestHeader(
|
|
||||||
'Content-Type', 'application/grpc-web+proto'));
|
|
||||||
verify(mockRequest.setRequestHeader('X-User-Agent', 'grpc-web-dart/0.1'));
|
|
||||||
verify(mockRequest.setRequestHeader('X-Grpc-Web', '1'));
|
|
||||||
verify(mockRequest.overrideMimeType('text/plain; charset=x-user-defined'));
|
|
||||||
verify(mockRequest.responseType = 'text');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Sent data converted to stream properly', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
'parameter_1': 'value_1',
|
|
||||||
'parameter_2': 'value_2'
|
|
||||||
};
|
|
||||||
|
|
||||||
final mockRequest = MockHttpRequest();
|
|
||||||
final transport = MockXhrTransport(mockRequest);
|
|
||||||
|
|
||||||
final stream =
|
|
||||||
transport.makeRequest('path', Duration(seconds: 10), metadata);
|
|
||||||
|
|
||||||
final data = List.filled(10, 0);
|
|
||||||
stream.outgoingMessages.add(data);
|
|
||||||
await stream.terminate();
|
|
||||||
|
|
||||||
final expectedData = frame(data);
|
|
||||||
expect(verify(mockRequest.send(captureAny)).captured.single, expectedData);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Stream handles headers properly', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
'parameter_1': 'value_1',
|
|
||||||
'parameter_2': 'value_2'
|
|
||||||
};
|
|
||||||
|
|
||||||
final mockRequest = MockHttpRequest();
|
|
||||||
final transport = MockXhrTransport(mockRequest);
|
|
||||||
|
|
||||||
final stream =
|
|
||||||
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
|
|
||||||
|
|
||||||
stream.incomingMessages.listen((message) {
|
|
||||||
expect(message, TypeMatcher<GrpcMetadata>());
|
|
||||||
if (message is GrpcMetadata) {
|
|
||||||
message.metadata.forEach((key, value) {
|
|
||||||
expect(value, metadata[key]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Stream deserializes data properly', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
'parameter_1': 'value_1',
|
|
||||||
'parameter_2': 'value_2'
|
|
||||||
};
|
|
||||||
|
|
||||||
final mockRequest = MockHttpRequest();
|
|
||||||
final transport = MockXhrTransport(mockRequest);
|
|
||||||
|
|
||||||
final stream =
|
|
||||||
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
|
|
||||||
final data = List<int>.filled(10, 224);
|
|
||||||
final encoded = frame(data);
|
|
||||||
final encodedString = String.fromCharCodes(encoded);
|
|
||||||
|
|
||||||
bool dataVerified = false;
|
|
||||||
stream.incomingMessages.listen((message) {
|
|
||||||
if (message is GrpcData) {
|
|
||||||
dataVerified = true;
|
|
||||||
expect(message.data, equals(data));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
when(mockRequest.getResponseHeader('Content-Type'))
|
|
||||||
.thenReturn('application/grpc+proto');
|
|
||||||
when(mockRequest.responseHeaders).thenReturn(metadata);
|
|
||||||
when(mockRequest.readyState).thenReturn(HttpRequest.HEADERS_RECEIVED);
|
|
||||||
when(mockRequest.response).thenReturn(encodedString);
|
|
||||||
transport.readyStateChangeStream.add(null);
|
|
||||||
transport.progressStream.add(null);
|
|
||||||
|
|
||||||
// Wait for all streams to process
|
|
||||||
await Future.sync(() {});
|
|
||||||
|
|
||||||
await stream.terminate();
|
|
||||||
expect(dataVerified, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Stream recieves multiple messages', () async {
|
|
||||||
final metadata = <String, String>{
|
|
||||||
'parameter_1': 'value_1',
|
|
||||||
'parameter_2': 'value_2'
|
|
||||||
};
|
|
||||||
|
|
||||||
final mockRequest = MockHttpRequest();
|
|
||||||
final transport = MockXhrTransport(mockRequest);
|
|
||||||
|
|
||||||
final stream =
|
|
||||||
transport.makeRequest('test_path', Duration(seconds: 10), metadata);
|
|
||||||
|
|
||||||
final data = <List<int>>[
|
|
||||||
List<int>.filled(10, 224),
|
|
||||||
List<int>.filled(5, 124)
|
|
||||||
];
|
|
||||||
final encoded = data.map((d) => frame(d));
|
|
||||||
final encodedStrings = encoded.map((e) => String.fromCharCodes(e)).toList();
|
|
||||||
// to start - expected response is the first message
|
|
||||||
var expectedResponse = encodedStrings[0];
|
|
||||||
|
|
||||||
final expectedMessages = <GrpcMessage>[
|
|
||||||
GrpcMetadata(metadata),
|
|
||||||
GrpcData(data[0]),
|
|
||||||
GrpcData(data[1])
|
|
||||||
];
|
|
||||||
stream.incomingMessages.listen((message) {
|
|
||||||
final expectedMessage = expectedMessages.removeAt(0);
|
|
||||||
expect(message.runtimeType, expectedMessage.runtimeType);
|
|
||||||
if (message is GrpcMetadata) {
|
|
||||||
expect(message.metadata, (expectedMessage as GrpcMetadata).metadata);
|
|
||||||
} else if (message is GrpcData) {
|
|
||||||
expect(message.data, (expectedMessage as GrpcData).data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
when(mockRequest.getResponseHeader('Content-Type'))
|
|
||||||
.thenReturn('application/grpc+proto');
|
|
||||||
when(mockRequest.responseHeaders).thenReturn(metadata);
|
|
||||||
when(mockRequest.readyState).thenReturn(HttpRequest.HEADERS_RECEIVED);
|
|
||||||
when(mockRequest.response).thenAnswer((_) => expectedResponse);
|
|
||||||
transport.readyStateChangeStream.add(null);
|
|
||||||
transport.progressStream.add(null);
|
|
||||||
// Wait for all streams to process
|
|
||||||
await Future.sync(() {});
|
|
||||||
|
|
||||||
// After the first call, expected response should now be both responses together
|
|
||||||
expectedResponse = encodedStrings[0] + encodedStrings[1];
|
|
||||||
transport.progressStream.add(null);
|
|
||||||
|
|
||||||
// Wait for all streams to process
|
|
||||||
await Future.sync(() {});
|
|
||||||
|
|
||||||
await stream.terminate();
|
|
||||||
expect(expectedMessages.isEmpty, isTrue);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -12,7 +12,6 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// 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.
|
||||||
@TestOn('vm')
|
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
@ -28,14 +27,14 @@ void main() {
|
||||||
await new File('test/data/certstore.p12').readAsBytes();
|
await new File('test/data/certstore.p12').readAsBytes();
|
||||||
|
|
||||||
final missingPassword =
|
final missingPassword =
|
||||||
new Http2ChannelCredentials.secure(certificates: certificates);
|
new ChannelCredentials.secure(certificates: certificates);
|
||||||
expect(() => missingPassword.securityContext, throwsA(isTlsException));
|
expect(() => missingPassword.securityContext, throwsA(isTlsException));
|
||||||
|
|
||||||
final wrongPassword = new Http2ChannelCredentials.secure(
|
final wrongPassword = new ChannelCredentials.secure(
|
||||||
certificates: certificates, password: 'wrong');
|
certificates: certificates, password: 'wrong');
|
||||||
expect(() => wrongPassword.securityContext, throwsA(isTlsException));
|
expect(() => wrongPassword.securityContext, throwsA(isTlsException));
|
||||||
|
|
||||||
final correctPassword = new Http2ChannelCredentials.secure(
|
final correctPassword = new ChannelCredentials.secure(
|
||||||
certificates: certificates, password: 'correct');
|
certificates: certificates, password: 'correct');
|
||||||
expect(correctPassword.securityContext, isNotNull);
|
expect(correctPassword.securityContext, isNotNull);
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// 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.
|
||||||
@TestOn('vm')
|
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:grpc/src/shared/message.dart';
|
import 'package:grpc/src/shared/streams.dart';
|
||||||
|
import 'package:http2/transport.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
|
|
||||||
|
@ -23,41 +24,29 @@ import 'package:grpc/grpc.dart';
|
||||||
|
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
|
||||||
typedef void ClientTestMessageHandler(List<int> message);
|
class MockTransport extends Mock implements ClientTransportConnection {}
|
||||||
|
|
||||||
GrpcData validateClientDataMessage(List<int> message) {
|
class MockStream extends Mock implements ClientTransportStream {}
|
||||||
final decoded = new GrpcData(message);
|
|
||||||
|
|
||||||
expect(decoded, new TypeMatcher<GrpcData>());
|
|
||||||
return decoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MockTransport extends Mock implements Transport {}
|
|
||||||
|
|
||||||
class MockStream extends Mock implements GrpcTransportStream {}
|
|
||||||
|
|
||||||
class FakeConnection extends ClientConnection {
|
class FakeConnection extends ClientConnection {
|
||||||
|
final ClientTransportConnection transport;
|
||||||
|
|
||||||
var connectionError;
|
var connectionError;
|
||||||
|
|
||||||
FakeConnection._(String host, Transport transport, ChannelOptions options,
|
FakeConnection(String host, this.transport, ChannelOptions options)
|
||||||
ConnectTransport connectTransport)
|
: super(host, 443, options);
|
||||||
: super(host, 443, options, connectTransport);
|
|
||||||
|
|
||||||
factory FakeConnection(
|
@override
|
||||||
String host, Transport transport, ChannelOptions options) {
|
Future<ClientTransportConnection> connectTransport() async {
|
||||||
FakeConnection f;
|
if (connectionError != null) throw connectionError;
|
||||||
f = FakeConnection._(host, transport, options, (_, _1, _2) async {
|
|
||||||
if (f.connectionError != null) throw f.connectionError;
|
|
||||||
return transport;
|
return transport;
|
||||||
});
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Duration testBackoff(Duration lastBackoff) => const Duration(milliseconds: 1);
|
Duration testBackoff(Duration lastBackoff) => const Duration(milliseconds: 1);
|
||||||
|
|
||||||
class FakeChannelOptions implements ChannelOptions {
|
class FakeChannelOptions implements ChannelOptions {
|
||||||
ChannelCredentials credentials = const Http2ChannelCredentials.secure();
|
ChannelCredentials credentials = const ChannelCredentials.secure();
|
||||||
Duration idleTimeout = const Duration(seconds: 1);
|
Duration idleTimeout = const Duration(seconds: 1);
|
||||||
BackoffStrategy backoffStrategy = testBackoff;
|
BackoffStrategy backoffStrategy = testBackoff;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +62,8 @@ class FakeChannel extends ClientChannel {
|
||||||
Future<ClientConnection> getConnection() async => connection;
|
Future<ClientConnection> getConnection() async => connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef ServerMessageHandler = void Function(StreamMessage message);
|
||||||
|
|
||||||
class TestClient extends Client {
|
class TestClient extends Client {
|
||||||
static final _$unary =
|
static final _$unary =
|
||||||
new ClientMethod<int, int>('/Test/Unary', mockEncode, mockDecode);
|
new ClientMethod<int, int>('/Test/Unary', mockEncode, mockDecode);
|
||||||
|
@ -119,8 +110,8 @@ class ClientHarness {
|
||||||
FakeChannelOptions channelOptions;
|
FakeChannelOptions channelOptions;
|
||||||
MockStream stream;
|
MockStream stream;
|
||||||
|
|
||||||
StreamController<List<int>> fromClient;
|
StreamController<StreamMessage> fromClient;
|
||||||
StreamController<GrpcMessage> toClient;
|
StreamController<StreamMessage> toClient;
|
||||||
|
|
||||||
TestClient client;
|
TestClient client;
|
||||||
|
|
||||||
|
@ -132,7 +123,8 @@ class ClientHarness {
|
||||||
stream = new MockStream();
|
stream = new MockStream();
|
||||||
fromClient = new StreamController();
|
fromClient = new StreamController();
|
||||||
toClient = new StreamController();
|
toClient = new StreamController();
|
||||||
when(transport.makeRequest(any, any, any)).thenReturn(stream);
|
when(transport.makeRequest(any, endStream: anyNamed('endStream')))
|
||||||
|
.thenReturn(stream);
|
||||||
when(transport.onActiveStateChanged = captureAny).thenReturn(null);
|
when(transport.onActiveStateChanged = captureAny).thenReturn(null);
|
||||||
when(stream.outgoingMessages).thenReturn(fromClient.sink);
|
when(stream.outgoingMessages).thenReturn(fromClient.sink);
|
||||||
when(stream.incomingMessages).thenAnswer((_) => toClient.stream);
|
when(stream.incomingMessages).thenAnswer((_) => toClient.stream);
|
||||||
|
@ -144,17 +136,18 @@ class ClientHarness {
|
||||||
toClient.close();
|
toClient.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendResponseHeader({Map<String, String> headers = const {}}) {
|
void sendResponseHeader({List<Header> headers = const []}) {
|
||||||
toClient.add(new GrpcMetadata(headers));
|
toClient.add(new HeadersStreamMessage(headers));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendResponseValue(int value) {
|
void sendResponseValue(int value) {
|
||||||
toClient.add(new GrpcData(mockEncode(value)));
|
toClient
|
||||||
|
.add(new DataStreamMessage(GrpcHttpEncoder.frame(mockEncode(value))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendResponseTrailer(
|
void sendResponseTrailer(
|
||||||
{Map<String, String> headers = const {}, bool closeStream = true}) {
|
{List<Header> headers = const [], bool closeStream = true}) {
|
||||||
toClient.add(new GrpcMetadata(headers));
|
toClient.add(new HeadersStreamMessage(headers, endStream: true));
|
||||||
if (closeStream) toClient.close();
|
if (closeStream) toClient.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,11 +164,11 @@ class ClientHarness {
|
||||||
String expectedPath,
|
String expectedPath,
|
||||||
Duration expectedTimeout,
|
Duration expectedTimeout,
|
||||||
Map<String, String> expectedCustomHeaders,
|
Map<String, String> expectedCustomHeaders,
|
||||||
List<ClientTestMessageHandler> serverHandlers = const [],
|
List<MessageHandler> serverHandlers = const [],
|
||||||
Function doneHandler,
|
Function doneHandler,
|
||||||
bool expectDone = true}) async {
|
bool expectDone = true}) async {
|
||||||
int serverHandlerIndex = 0;
|
int serverHandlerIndex = 0;
|
||||||
void handleServerMessage(List<int> message) {
|
void handleServerMessage(StreamMessage message) {
|
||||||
serverHandlers[serverHandlerIndex++](message);
|
serverHandlers[serverHandlerIndex++](message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,17 +182,12 @@ class ClientHarness {
|
||||||
expect(result, expectedResult);
|
expect(result, expectedResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
final capturedParameters =
|
final List<Header> capturedHeaders =
|
||||||
verify(transport.makeRequest(captureAny, captureAny, captureAny))
|
verify(transport.makeRequest(captureAny)).captured.single;
|
||||||
.captured;
|
validateRequestHeaders(capturedHeaders,
|
||||||
if (expectedPath != null) {
|
path: expectedPath,
|
||||||
expect(capturedParameters[0], expectedPath);
|
timeout: toTimeoutString(expectedTimeout),
|
||||||
}
|
customHeaders: expectedCustomHeaders);
|
||||||
expect(capturedParameters[1], expectedTimeout);
|
|
||||||
final Map<String, String> headers = capturedParameters[2];
|
|
||||||
headers?.forEach((key, value) {
|
|
||||||
expect(expectedCustomHeaders[key], value);
|
|
||||||
});
|
|
||||||
|
|
||||||
await clientSubscription.cancel();
|
await clientSubscription.cancel();
|
||||||
}
|
}
|
||||||
|
@ -219,7 +207,7 @@ class ClientHarness {
|
||||||
String expectedPath,
|
String expectedPath,
|
||||||
Duration expectedTimeout,
|
Duration expectedTimeout,
|
||||||
Map<String, String> expectedCustomHeaders,
|
Map<String, String> expectedCustomHeaders,
|
||||||
List<ClientTestMessageHandler> serverHandlers = const [],
|
List<MessageHandler> serverHandlers = const [],
|
||||||
bool expectDone = true}) async {
|
bool expectDone = true}) async {
|
||||||
return runTest(
|
return runTest(
|
||||||
clientCall: expectThrows(clientCall, expectedException),
|
clientCall: expectThrows(clientCall, expectedException),
|
||||||
|
|
|
@ -15,13 +15,11 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:grpc/src/shared/message.dart';
|
|
||||||
import 'package:grpc/src/shared/streams.dart';
|
import 'package:grpc/src/shared/streams.dart';
|
||||||
import 'package:http2/transport.dart';
|
import 'package:http2/transport.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'package:grpc/grpc.dart';
|
import 'package:grpc/grpc.dart';
|
||||||
import 'package:grpc/src/client/transport/http2_transport.dart';
|
|
||||||
|
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
|
||||||
|
@ -172,14 +170,14 @@ class ServerHarness {
|
||||||
{String authority = 'test',
|
{String authority = 'test',
|
||||||
Map<String, String> metadata,
|
Map<String, String> metadata,
|
||||||
Duration timeout}) {
|
Duration timeout}) {
|
||||||
final headers = Http2Transport.createCallHeaders(
|
final headers = ClientConnection.createCallHeaders(
|
||||||
true, authority, path, timeout, metadata);
|
true, authority, path, timeout, metadata);
|
||||||
toServer.add(new HeadersStreamMessage(headers));
|
toServer.add(new HeadersStreamMessage(headers));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendData(int value) {
|
void sendData(int value) {
|
||||||
toServer
|
toServer
|
||||||
.add(new DataStreamMessage(frame(mockEncode(value))));
|
.add(new DataStreamMessage(GrpcHttpEncoder.frame(mockEncode(value))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void runTest(String path, List<int> requests, List<int> expectedResponses) {
|
void runTest(String path, List<int> requests, List<int> expectedResponses) {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:grpc/src/shared/streams.dart';
|
import 'package:grpc/src/shared/streams.dart';
|
||||||
import 'package:grpc/src/shared/message.dart';
|
|
||||||
import 'package:http2/transport.dart';
|
import 'package:http2/transport.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
@ -30,25 +29,26 @@ Map<String, String> headersToMap(List<Header> headers) =>
|
||||||
new Map.fromIterable(headers,
|
new Map.fromIterable(headers,
|
||||||
key: (h) => ascii.decode(h.name), value: (h) => ascii.decode(h.value));
|
key: (h) => ascii.decode(h.name), value: (h) => ascii.decode(h.value));
|
||||||
|
|
||||||
void validateRequestHeaders(Map<String, String> headers,
|
void validateRequestHeaders(List<Header> headers,
|
||||||
{String path,
|
{String path,
|
||||||
String authority = 'test',
|
String authority = 'test',
|
||||||
String timeout,
|
String timeout,
|
||||||
Map<String, String> customHeaders}) {
|
Map<String, String> customHeaders}) {
|
||||||
expect(headers[':method'], 'POST');
|
final headerMap = headersToMap(headers);
|
||||||
expect(headers[':scheme'], 'https');
|
expect(headerMap[':method'], 'POST');
|
||||||
|
expect(headerMap[':scheme'], 'https');
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
expect(headers[':path'], path);
|
expect(headerMap[':path'], path);
|
||||||
}
|
}
|
||||||
expect(headers[':authority'], authority);
|
expect(headerMap[':authority'], authority);
|
||||||
expect(headers['grpc-timeout'], timeout);
|
expect(headerMap['grpc-timeout'], timeout);
|
||||||
expect(headers['content-type'], 'application/grpc');
|
expect(headerMap['content-type'], 'application/grpc');
|
||||||
expect(headers['te'], 'trailers');
|
expect(headerMap['te'], 'trailers');
|
||||||
expect(headers['grpc-accept-encoding'], 'identity');
|
expect(headerMap['grpc-accept-encoding'], 'identity');
|
||||||
expect(headers['user-agent'], startsWith('dart-grpc/'));
|
expect(headerMap['user-agent'], startsWith('dart-grpc/'));
|
||||||
|
|
||||||
customHeaders?.forEach((key, value) {
|
customHeaders?.forEach((key, value) {
|
||||||
expect(headers[key], value);
|
expect(headerMap[key], value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,12 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:grpc/grpc.dart';
|
import 'package:grpc/grpc.dart';
|
||||||
|
import 'package:http2/transport.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'src/client_utils.dart';
|
import 'src/client_utils.dart';
|
||||||
import 'src/server_utils.dart';
|
import 'src/server_utils.dart';
|
||||||
|
import 'src/utils.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
const dummyValue = 0;
|
const dummyValue = 0;
|
||||||
|
@ -73,8 +75,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Calls time out if deadline is exceeded', () async {
|
test('Calls time out if deadline is exceeded', () async {
|
||||||
void handleRequest(List<int> message) {
|
void handleRequest(StreamMessage message) {
|
||||||
validateClientDataMessage(message);
|
validateDataMessage(message);
|
||||||
final Future delay = new Future.delayed(new Duration(milliseconds: 2));
|
final Future delay = new Future.delayed(new Duration(milliseconds: 2));
|
||||||
expect(delay, completes);
|
expect(delay, completes);
|
||||||
delay.then((_) {
|
delay.then((_) {
|
||||||
|
@ -140,5 +142,5 @@ void main() {
|
||||||
timeout: new Duration(microseconds: 1));
|
timeout: new Duration(microseconds: 1));
|
||||||
await harness.fromServer.done;
|
await harness.fromServer.done;
|
||||||
});
|
});
|
||||||
}, testOn: 'vm');
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue