1*cc02d7e2SAndroid Build Coastguard Worker<?php 2*cc02d7e2SAndroid Build Coastguard Worker/* 3*cc02d7e2SAndroid Build Coastguard Worker * 4*cc02d7e2SAndroid Build Coastguard Worker * Copyright 2015 gRPC authors. 5*cc02d7e2SAndroid Build Coastguard Worker * 6*cc02d7e2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 7*cc02d7e2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 8*cc02d7e2SAndroid Build Coastguard Worker * You may obtain a copy of the License at 9*cc02d7e2SAndroid Build Coastguard Worker * 10*cc02d7e2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 11*cc02d7e2SAndroid Build Coastguard Worker * 12*cc02d7e2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 13*cc02d7e2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 14*cc02d7e2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*cc02d7e2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 16*cc02d7e2SAndroid Build Coastguard Worker * limitations under the License. 17*cc02d7e2SAndroid Build Coastguard Worker * 18*cc02d7e2SAndroid Build Coastguard Worker */ 19*cc02d7e2SAndroid Build Coastguard Worker 20*cc02d7e2SAndroid Build Coastguard Workernamespace Grpc; 21*cc02d7e2SAndroid Build Coastguard Worker 22*cc02d7e2SAndroid Build Coastguard Worker/** 23*cc02d7e2SAndroid Build Coastguard Worker * Base class for generated client stubs. Stub methods are expected to call 24*cc02d7e2SAndroid Build Coastguard Worker * _simpleRequest or _streamRequest and return the result. 25*cc02d7e2SAndroid Build Coastguard Worker */ 26*cc02d7e2SAndroid Build Coastguard Workerclass BaseStub 27*cc02d7e2SAndroid Build Coastguard Worker{ 28*cc02d7e2SAndroid Build Coastguard Worker private $hostname; 29*cc02d7e2SAndroid Build Coastguard Worker private $hostname_override; 30*cc02d7e2SAndroid Build Coastguard Worker private $channel; 31*cc02d7e2SAndroid Build Coastguard Worker private $call_invoker; 32*cc02d7e2SAndroid Build Coastguard Worker 33*cc02d7e2SAndroid Build Coastguard Worker // a callback function 34*cc02d7e2SAndroid Build Coastguard Worker private $update_metadata; 35*cc02d7e2SAndroid Build Coastguard Worker 36*cc02d7e2SAndroid Build Coastguard Worker /** 37*cc02d7e2SAndroid Build Coastguard Worker * @param string $hostname 38*cc02d7e2SAndroid Build Coastguard Worker * @param array $opts 39*cc02d7e2SAndroid Build Coastguard Worker * - 'update_metadata': (optional) a callback function which takes in a 40*cc02d7e2SAndroid Build Coastguard Worker * metadata array, and returns an updated metadata array 41*cc02d7e2SAndroid Build Coastguard Worker * - 'grpc.primary_user_agent': (optional) a user-agent string 42*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel An already created Channel or InterceptorChannel object (optional) 43*cc02d7e2SAndroid Build Coastguard Worker */ 44*cc02d7e2SAndroid Build Coastguard Worker public function __construct($hostname, $opts, $channel = null) 45*cc02d7e2SAndroid Build Coastguard Worker { 46*cc02d7e2SAndroid Build Coastguard Worker if (!method_exists('Grpc\ChannelCredentials', 'isDefaultRootsPemSet') || 47*cc02d7e2SAndroid Build Coastguard Worker !ChannelCredentials::isDefaultRootsPemSet()) { 48*cc02d7e2SAndroid Build Coastguard Worker $ssl_roots = file_get_contents( 49*cc02d7e2SAndroid Build Coastguard Worker dirname(__FILE__).'/../../../../etc/roots.pem' 50*cc02d7e2SAndroid Build Coastguard Worker ); 51*cc02d7e2SAndroid Build Coastguard Worker ChannelCredentials::setDefaultRootsPem($ssl_roots); 52*cc02d7e2SAndroid Build Coastguard Worker } 53*cc02d7e2SAndroid Build Coastguard Worker 54*cc02d7e2SAndroid Build Coastguard Worker $this->hostname = $hostname; 55*cc02d7e2SAndroid Build Coastguard Worker $this->update_metadata = null; 56*cc02d7e2SAndroid Build Coastguard Worker if (isset($opts['update_metadata'])) { 57*cc02d7e2SAndroid Build Coastguard Worker if (is_callable($opts['update_metadata'])) { 58*cc02d7e2SAndroid Build Coastguard Worker $this->update_metadata = $opts['update_metadata']; 59*cc02d7e2SAndroid Build Coastguard Worker } 60*cc02d7e2SAndroid Build Coastguard Worker unset($opts['update_metadata']); 61*cc02d7e2SAndroid Build Coastguard Worker } 62*cc02d7e2SAndroid Build Coastguard Worker if (!empty($opts['grpc.ssl_target_name_override'])) { 63*cc02d7e2SAndroid Build Coastguard Worker $this->hostname_override = $opts['grpc.ssl_target_name_override']; 64*cc02d7e2SAndroid Build Coastguard Worker } 65*cc02d7e2SAndroid Build Coastguard Worker if (isset($opts['grpc_call_invoker'])) { 66*cc02d7e2SAndroid Build Coastguard Worker $this->call_invoker = $opts['grpc_call_invoker']; 67*cc02d7e2SAndroid Build Coastguard Worker unset($opts['grpc_call_invoker']); 68*cc02d7e2SAndroid Build Coastguard Worker $channel_opts = $this->updateOpts($opts); 69*cc02d7e2SAndroid Build Coastguard Worker // If the grpc_call_invoker is defined, use the channel created by the call invoker. 70*cc02d7e2SAndroid Build Coastguard Worker $this->channel = $this->call_invoker->createChannelFactory($hostname, $channel_opts); 71*cc02d7e2SAndroid Build Coastguard Worker return; 72*cc02d7e2SAndroid Build Coastguard Worker } 73*cc02d7e2SAndroid Build Coastguard Worker $this->call_invoker = new DefaultCallInvoker(); 74*cc02d7e2SAndroid Build Coastguard Worker if ($channel) { 75*cc02d7e2SAndroid Build Coastguard Worker if (!is_a($channel, 'Grpc\Channel') && 76*cc02d7e2SAndroid Build Coastguard Worker !is_a($channel, 'Grpc\Internal\InterceptorChannel')) { 77*cc02d7e2SAndroid Build Coastguard Worker throw new \Exception('The channel argument is not a Channel object '. 78*cc02d7e2SAndroid Build Coastguard Worker 'or an InterceptorChannel object created by '. 79*cc02d7e2SAndroid Build Coastguard Worker 'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)'); 80*cc02d7e2SAndroid Build Coastguard Worker } 81*cc02d7e2SAndroid Build Coastguard Worker $this->channel = $channel; 82*cc02d7e2SAndroid Build Coastguard Worker return; 83*cc02d7e2SAndroid Build Coastguard Worker } 84*cc02d7e2SAndroid Build Coastguard Worker 85*cc02d7e2SAndroid Build Coastguard Worker $this->channel = static::getDefaultChannel($hostname, $opts); 86*cc02d7e2SAndroid Build Coastguard Worker } 87*cc02d7e2SAndroid Build Coastguard Worker 88*cc02d7e2SAndroid Build Coastguard Worker private static function updateOpts($opts) { 89*cc02d7e2SAndroid Build Coastguard Worker if (!empty($opts['grpc.primary_user_agent'])) { 90*cc02d7e2SAndroid Build Coastguard Worker $opts['grpc.primary_user_agent'] .= ' '; 91*cc02d7e2SAndroid Build Coastguard Worker } else { 92*cc02d7e2SAndroid Build Coastguard Worker $opts['grpc.primary_user_agent'] = ''; 93*cc02d7e2SAndroid Build Coastguard Worker } 94*cc02d7e2SAndroid Build Coastguard Worker if (defined('\Grpc\VERSION')) { 95*cc02d7e2SAndroid Build Coastguard Worker $version_str = \Grpc\VERSION; 96*cc02d7e2SAndroid Build Coastguard Worker } else { 97*cc02d7e2SAndroid Build Coastguard Worker if (!file_exists($composerFile = __DIR__.'/../../composer.json')) { 98*cc02d7e2SAndroid Build Coastguard Worker // for grpc/grpc-php subpackage 99*cc02d7e2SAndroid Build Coastguard Worker $composerFile = __DIR__.'/../composer.json'; 100*cc02d7e2SAndroid Build Coastguard Worker } 101*cc02d7e2SAndroid Build Coastguard Worker $package_config = json_decode(file_get_contents($composerFile), true); 102*cc02d7e2SAndroid Build Coastguard Worker $version_str = $package_config['version']; 103*cc02d7e2SAndroid Build Coastguard Worker } 104*cc02d7e2SAndroid Build Coastguard Worker $opts['grpc.primary_user_agent'] .= 'grpc-php/'.$version_str; 105*cc02d7e2SAndroid Build Coastguard Worker if (!array_key_exists('credentials', $opts)) { 106*cc02d7e2SAndroid Build Coastguard Worker throw new \Exception("The opts['credentials'] key is now ". 107*cc02d7e2SAndroid Build Coastguard Worker 'required. Please see one of the '. 108*cc02d7e2SAndroid Build Coastguard Worker 'ChannelCredentials::create methods'); 109*cc02d7e2SAndroid Build Coastguard Worker } 110*cc02d7e2SAndroid Build Coastguard Worker return $opts; 111*cc02d7e2SAndroid Build Coastguard Worker } 112*cc02d7e2SAndroid Build Coastguard Worker 113*cc02d7e2SAndroid Build Coastguard Worker /** 114*cc02d7e2SAndroid Build Coastguard Worker * Creates and returns the default Channel 115*cc02d7e2SAndroid Build Coastguard Worker * 116*cc02d7e2SAndroid Build Coastguard Worker * @param array $opts Channel constructor options 117*cc02d7e2SAndroid Build Coastguard Worker * 118*cc02d7e2SAndroid Build Coastguard Worker * @return Channel The channel 119*cc02d7e2SAndroid Build Coastguard Worker */ 120*cc02d7e2SAndroid Build Coastguard Worker public static function getDefaultChannel($hostname, array $opts) 121*cc02d7e2SAndroid Build Coastguard Worker { 122*cc02d7e2SAndroid Build Coastguard Worker $channel_opts = self::updateOpts($opts); 123*cc02d7e2SAndroid Build Coastguard Worker return new Channel($hostname, $channel_opts); 124*cc02d7e2SAndroid Build Coastguard Worker } 125*cc02d7e2SAndroid Build Coastguard Worker 126*cc02d7e2SAndroid Build Coastguard Worker /** 127*cc02d7e2SAndroid Build Coastguard Worker * @return string The URI of the endpoint 128*cc02d7e2SAndroid Build Coastguard Worker */ 129*cc02d7e2SAndroid Build Coastguard Worker public function getTarget() 130*cc02d7e2SAndroid Build Coastguard Worker { 131*cc02d7e2SAndroid Build Coastguard Worker return $this->channel->getTarget(); 132*cc02d7e2SAndroid Build Coastguard Worker } 133*cc02d7e2SAndroid Build Coastguard Worker 134*cc02d7e2SAndroid Build Coastguard Worker /** 135*cc02d7e2SAndroid Build Coastguard Worker * @param bool $try_to_connect (optional) 136*cc02d7e2SAndroid Build Coastguard Worker * 137*cc02d7e2SAndroid Build Coastguard Worker * @return int The grpc connectivity state 138*cc02d7e2SAndroid Build Coastguard Worker */ 139*cc02d7e2SAndroid Build Coastguard Worker public function getConnectivityState($try_to_connect = false) 140*cc02d7e2SAndroid Build Coastguard Worker { 141*cc02d7e2SAndroid Build Coastguard Worker return $this->channel->getConnectivityState($try_to_connect); 142*cc02d7e2SAndroid Build Coastguard Worker } 143*cc02d7e2SAndroid Build Coastguard Worker 144*cc02d7e2SAndroid Build Coastguard Worker /** 145*cc02d7e2SAndroid Build Coastguard Worker * @param int $timeout in microseconds 146*cc02d7e2SAndroid Build Coastguard Worker * 147*cc02d7e2SAndroid Build Coastguard Worker * @return bool true if channel is ready 148*cc02d7e2SAndroid Build Coastguard Worker * @throws Exception if channel is in FATAL_ERROR state 149*cc02d7e2SAndroid Build Coastguard Worker */ 150*cc02d7e2SAndroid Build Coastguard Worker public function waitForReady($timeout) 151*cc02d7e2SAndroid Build Coastguard Worker { 152*cc02d7e2SAndroid Build Coastguard Worker $new_state = $this->getConnectivityState(true); 153*cc02d7e2SAndroid Build Coastguard Worker if ($this->_checkConnectivityState($new_state)) { 154*cc02d7e2SAndroid Build Coastguard Worker return true; 155*cc02d7e2SAndroid Build Coastguard Worker } 156*cc02d7e2SAndroid Build Coastguard Worker 157*cc02d7e2SAndroid Build Coastguard Worker $now = Timeval::now(); 158*cc02d7e2SAndroid Build Coastguard Worker $delta = new Timeval($timeout); 159*cc02d7e2SAndroid Build Coastguard Worker $deadline = $now->add($delta); 160*cc02d7e2SAndroid Build Coastguard Worker 161*cc02d7e2SAndroid Build Coastguard Worker while ($this->channel->watchConnectivityState($new_state, $deadline)) { 162*cc02d7e2SAndroid Build Coastguard Worker // state has changed before deadline 163*cc02d7e2SAndroid Build Coastguard Worker $new_state = $this->getConnectivityState(); 164*cc02d7e2SAndroid Build Coastguard Worker if ($this->_checkConnectivityState($new_state)) { 165*cc02d7e2SAndroid Build Coastguard Worker return true; 166*cc02d7e2SAndroid Build Coastguard Worker } 167*cc02d7e2SAndroid Build Coastguard Worker } 168*cc02d7e2SAndroid Build Coastguard Worker // deadline has passed 169*cc02d7e2SAndroid Build Coastguard Worker $new_state = $this->getConnectivityState(); 170*cc02d7e2SAndroid Build Coastguard Worker 171*cc02d7e2SAndroid Build Coastguard Worker return $this->_checkConnectivityState($new_state); 172*cc02d7e2SAndroid Build Coastguard Worker } 173*cc02d7e2SAndroid Build Coastguard Worker 174*cc02d7e2SAndroid Build Coastguard Worker /** 175*cc02d7e2SAndroid Build Coastguard Worker * Close the communication channel associated with this stub. 176*cc02d7e2SAndroid Build Coastguard Worker */ 177*cc02d7e2SAndroid Build Coastguard Worker public function close() 178*cc02d7e2SAndroid Build Coastguard Worker { 179*cc02d7e2SAndroid Build Coastguard Worker $this->channel->close(); 180*cc02d7e2SAndroid Build Coastguard Worker } 181*cc02d7e2SAndroid Build Coastguard Worker 182*cc02d7e2SAndroid Build Coastguard Worker /** 183*cc02d7e2SAndroid Build Coastguard Worker * @param $new_state Connect state 184*cc02d7e2SAndroid Build Coastguard Worker * 185*cc02d7e2SAndroid Build Coastguard Worker * @return bool true if state is CHANNEL_READY 186*cc02d7e2SAndroid Build Coastguard Worker * @throws Exception if state is CHANNEL_FATAL_FAILURE 187*cc02d7e2SAndroid Build Coastguard Worker */ 188*cc02d7e2SAndroid Build Coastguard Worker private function _checkConnectivityState($new_state) 189*cc02d7e2SAndroid Build Coastguard Worker { 190*cc02d7e2SAndroid Build Coastguard Worker if ($new_state == \Grpc\CHANNEL_READY) { 191*cc02d7e2SAndroid Build Coastguard Worker return true; 192*cc02d7e2SAndroid Build Coastguard Worker } 193*cc02d7e2SAndroid Build Coastguard Worker if ($new_state == \Grpc\CHANNEL_FATAL_FAILURE) { 194*cc02d7e2SAndroid Build Coastguard Worker throw new \Exception('Failed to connect to server'); 195*cc02d7e2SAndroid Build Coastguard Worker } 196*cc02d7e2SAndroid Build Coastguard Worker 197*cc02d7e2SAndroid Build Coastguard Worker return false; 198*cc02d7e2SAndroid Build Coastguard Worker } 199*cc02d7e2SAndroid Build Coastguard Worker 200*cc02d7e2SAndroid Build Coastguard Worker /** 201*cc02d7e2SAndroid Build Coastguard Worker * constructs the auth uri for the jwt. 202*cc02d7e2SAndroid Build Coastguard Worker * 203*cc02d7e2SAndroid Build Coastguard Worker * @param string $method The method string 204*cc02d7e2SAndroid Build Coastguard Worker * 205*cc02d7e2SAndroid Build Coastguard Worker * @return string The URL string 206*cc02d7e2SAndroid Build Coastguard Worker */ 207*cc02d7e2SAndroid Build Coastguard Worker private function _get_jwt_aud_uri($method) 208*cc02d7e2SAndroid Build Coastguard Worker { 209*cc02d7e2SAndroid Build Coastguard Worker // TODO(jtattermusch): This is not the correct implementation 210*cc02d7e2SAndroid Build Coastguard Worker // of extracting JWT "aud" claim. We should rely on 211*cc02d7e2SAndroid Build Coastguard Worker // grpc_metadata_credentials_plugin which 212*cc02d7e2SAndroid Build Coastguard Worker // also provides the correct value of "aud" claim 213*cc02d7e2SAndroid Build Coastguard Worker // in the grpc_auth_metadata_context.service_url field. 214*cc02d7e2SAndroid Build Coastguard Worker // Trying to do the construction of "aud" field ourselves 215*cc02d7e2SAndroid Build Coastguard Worker // is bad. 216*cc02d7e2SAndroid Build Coastguard Worker $last_slash_idx = strrpos($method, '/'); 217*cc02d7e2SAndroid Build Coastguard Worker if ($last_slash_idx === false) { 218*cc02d7e2SAndroid Build Coastguard Worker throw new \InvalidArgumentException( 219*cc02d7e2SAndroid Build Coastguard Worker 'service name must have a slash' 220*cc02d7e2SAndroid Build Coastguard Worker ); 221*cc02d7e2SAndroid Build Coastguard Worker } 222*cc02d7e2SAndroid Build Coastguard Worker $service_name = substr($method, 0, $last_slash_idx); 223*cc02d7e2SAndroid Build Coastguard Worker 224*cc02d7e2SAndroid Build Coastguard Worker if ($this->hostname_override) { 225*cc02d7e2SAndroid Build Coastguard Worker $hostname = $this->hostname_override; 226*cc02d7e2SAndroid Build Coastguard Worker } else { 227*cc02d7e2SAndroid Build Coastguard Worker $hostname = $this->hostname; 228*cc02d7e2SAndroid Build Coastguard Worker } 229*cc02d7e2SAndroid Build Coastguard Worker 230*cc02d7e2SAndroid Build Coastguard Worker // Remove the port if it is 443 231*cc02d7e2SAndroid Build Coastguard Worker // See https://github.com/grpc/grpc/blob/07c9f7a36b2a0d34fcffebc85649cf3b8c339b5d/src/core/lib/security/transport/client_auth_filter.cc#L205 232*cc02d7e2SAndroid Build Coastguard Worker if ((strlen($hostname) > 4) && (substr($hostname, -4) === ":443")) { 233*cc02d7e2SAndroid Build Coastguard Worker $hostname = substr($hostname, 0, -4); 234*cc02d7e2SAndroid Build Coastguard Worker } 235*cc02d7e2SAndroid Build Coastguard Worker 236*cc02d7e2SAndroid Build Coastguard Worker return 'https://'.$hostname.$service_name; 237*cc02d7e2SAndroid Build Coastguard Worker } 238*cc02d7e2SAndroid Build Coastguard Worker 239*cc02d7e2SAndroid Build Coastguard Worker /** 240*cc02d7e2SAndroid Build Coastguard Worker * validate and normalize the metadata array. 241*cc02d7e2SAndroid Build Coastguard Worker * 242*cc02d7e2SAndroid Build Coastguard Worker * @param array $metadata The metadata map 243*cc02d7e2SAndroid Build Coastguard Worker * 244*cc02d7e2SAndroid Build Coastguard Worker * @return array $metadata Validated and key-normalized metadata map 245*cc02d7e2SAndroid Build Coastguard Worker * @throws InvalidArgumentException if key contains invalid characters 246*cc02d7e2SAndroid Build Coastguard Worker */ 247*cc02d7e2SAndroid Build Coastguard Worker private function _validate_and_normalize_metadata($metadata) 248*cc02d7e2SAndroid Build Coastguard Worker { 249*cc02d7e2SAndroid Build Coastguard Worker $metadata_copy = []; 250*cc02d7e2SAndroid Build Coastguard Worker foreach ($metadata as $key => $value) { 251*cc02d7e2SAndroid Build Coastguard Worker if (!preg_match('/^[.A-Za-z\d_-]+$/', $key)) { 252*cc02d7e2SAndroid Build Coastguard Worker throw new \InvalidArgumentException( 253*cc02d7e2SAndroid Build Coastguard Worker 'Metadata keys must be nonempty strings containing only '. 254*cc02d7e2SAndroid Build Coastguard Worker 'alphanumeric characters, hyphens, underscores and dots' 255*cc02d7e2SAndroid Build Coastguard Worker ); 256*cc02d7e2SAndroid Build Coastguard Worker } 257*cc02d7e2SAndroid Build Coastguard Worker $metadata_copy[strtolower($key)] = $value; 258*cc02d7e2SAndroid Build Coastguard Worker } 259*cc02d7e2SAndroid Build Coastguard Worker 260*cc02d7e2SAndroid Build Coastguard Worker return $metadata_copy; 261*cc02d7e2SAndroid Build Coastguard Worker } 262*cc02d7e2SAndroid Build Coastguard Worker 263*cc02d7e2SAndroid Build Coastguard Worker /** 264*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create UnaryCall 265*cc02d7e2SAndroid Build Coastguard Worker * 266*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 267*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 268*cc02d7e2SAndroid Build Coastguard Worker * 269*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 270*cc02d7e2SAndroid Build Coastguard Worker */ 271*cc02d7e2SAndroid Build Coastguard Worker private function _GrpcUnaryUnary($channel) 272*cc02d7e2SAndroid Build Coastguard Worker { 273*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 274*cc02d7e2SAndroid Build Coastguard Worker $argument, 275*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 276*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 277*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 278*cc02d7e2SAndroid Build Coastguard Worker $call = $this->call_invoker->UnaryCall( 279*cc02d7e2SAndroid Build Coastguard Worker $channel, 280*cc02d7e2SAndroid Build Coastguard Worker $method, 281*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 282*cc02d7e2SAndroid Build Coastguard Worker $options 283*cc02d7e2SAndroid Build Coastguard Worker ); 284*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri = $this->_get_jwt_aud_uri($method); 285*cc02d7e2SAndroid Build Coastguard Worker if (is_callable($this->update_metadata)) { 286*cc02d7e2SAndroid Build Coastguard Worker $metadata = call_user_func( 287*cc02d7e2SAndroid Build Coastguard Worker $this->update_metadata, 288*cc02d7e2SAndroid Build Coastguard Worker $metadata, 289*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri 290*cc02d7e2SAndroid Build Coastguard Worker ); 291*cc02d7e2SAndroid Build Coastguard Worker } 292*cc02d7e2SAndroid Build Coastguard Worker $metadata = $this->_validate_and_normalize_metadata( 293*cc02d7e2SAndroid Build Coastguard Worker $metadata 294*cc02d7e2SAndroid Build Coastguard Worker ); 295*cc02d7e2SAndroid Build Coastguard Worker $call->start($argument, $metadata, $options); 296*cc02d7e2SAndroid Build Coastguard Worker return $call; 297*cc02d7e2SAndroid Build Coastguard Worker }; 298*cc02d7e2SAndroid Build Coastguard Worker } 299*cc02d7e2SAndroid Build Coastguard Worker 300*cc02d7e2SAndroid Build Coastguard Worker /** 301*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create ServerStreamingCall 302*cc02d7e2SAndroid Build Coastguard Worker * 303*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 304*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 305*cc02d7e2SAndroid Build Coastguard Worker * 306*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 307*cc02d7e2SAndroid Build Coastguard Worker */ 308*cc02d7e2SAndroid Build Coastguard Worker private function _GrpcStreamUnary($channel) 309*cc02d7e2SAndroid Build Coastguard Worker { 310*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 311*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 312*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 313*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 314*cc02d7e2SAndroid Build Coastguard Worker $call = $this->call_invoker->ClientStreamingCall( 315*cc02d7e2SAndroid Build Coastguard Worker $channel, 316*cc02d7e2SAndroid Build Coastguard Worker $method, 317*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 318*cc02d7e2SAndroid Build Coastguard Worker $options 319*cc02d7e2SAndroid Build Coastguard Worker ); 320*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri = $this->_get_jwt_aud_uri($method); 321*cc02d7e2SAndroid Build Coastguard Worker if (is_callable($this->update_metadata)) { 322*cc02d7e2SAndroid Build Coastguard Worker $metadata = call_user_func( 323*cc02d7e2SAndroid Build Coastguard Worker $this->update_metadata, 324*cc02d7e2SAndroid Build Coastguard Worker $metadata, 325*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri 326*cc02d7e2SAndroid Build Coastguard Worker ); 327*cc02d7e2SAndroid Build Coastguard Worker } 328*cc02d7e2SAndroid Build Coastguard Worker $metadata = $this->_validate_and_normalize_metadata( 329*cc02d7e2SAndroid Build Coastguard Worker $metadata 330*cc02d7e2SAndroid Build Coastguard Worker ); 331*cc02d7e2SAndroid Build Coastguard Worker $call->start($metadata); 332*cc02d7e2SAndroid Build Coastguard Worker return $call; 333*cc02d7e2SAndroid Build Coastguard Worker }; 334*cc02d7e2SAndroid Build Coastguard Worker } 335*cc02d7e2SAndroid Build Coastguard Worker 336*cc02d7e2SAndroid Build Coastguard Worker /** 337*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create ClientStreamingCall 338*cc02d7e2SAndroid Build Coastguard Worker * 339*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 340*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 341*cc02d7e2SAndroid Build Coastguard Worker * 342*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 343*cc02d7e2SAndroid Build Coastguard Worker */ 344*cc02d7e2SAndroid Build Coastguard Worker private function _GrpcUnaryStream($channel) 345*cc02d7e2SAndroid Build Coastguard Worker { 346*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 347*cc02d7e2SAndroid Build Coastguard Worker $argument, 348*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 349*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 350*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 351*cc02d7e2SAndroid Build Coastguard Worker $call = $this->call_invoker->ServerStreamingCall( 352*cc02d7e2SAndroid Build Coastguard Worker $channel, 353*cc02d7e2SAndroid Build Coastguard Worker $method, 354*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 355*cc02d7e2SAndroid Build Coastguard Worker $options 356*cc02d7e2SAndroid Build Coastguard Worker ); 357*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri = $this->_get_jwt_aud_uri($method); 358*cc02d7e2SAndroid Build Coastguard Worker if (is_callable($this->update_metadata)) { 359*cc02d7e2SAndroid Build Coastguard Worker $metadata = call_user_func( 360*cc02d7e2SAndroid Build Coastguard Worker $this->update_metadata, 361*cc02d7e2SAndroid Build Coastguard Worker $metadata, 362*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri 363*cc02d7e2SAndroid Build Coastguard Worker ); 364*cc02d7e2SAndroid Build Coastguard Worker } 365*cc02d7e2SAndroid Build Coastguard Worker $metadata = $this->_validate_and_normalize_metadata( 366*cc02d7e2SAndroid Build Coastguard Worker $metadata 367*cc02d7e2SAndroid Build Coastguard Worker ); 368*cc02d7e2SAndroid Build Coastguard Worker $call->start($argument, $metadata, $options); 369*cc02d7e2SAndroid Build Coastguard Worker return $call; 370*cc02d7e2SAndroid Build Coastguard Worker }; 371*cc02d7e2SAndroid Build Coastguard Worker } 372*cc02d7e2SAndroid Build Coastguard Worker 373*cc02d7e2SAndroid Build Coastguard Worker /** 374*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create BidiStreamingCall 375*cc02d7e2SAndroid Build Coastguard Worker * 376*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 377*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 378*cc02d7e2SAndroid Build Coastguard Worker * 379*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 380*cc02d7e2SAndroid Build Coastguard Worker */ 381*cc02d7e2SAndroid Build Coastguard Worker private function _GrpcStreamStream($channel) 382*cc02d7e2SAndroid Build Coastguard Worker { 383*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 384*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 385*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 386*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 387*cc02d7e2SAndroid Build Coastguard Worker $call = $this->call_invoker->BidiStreamingCall( 388*cc02d7e2SAndroid Build Coastguard Worker $channel, 389*cc02d7e2SAndroid Build Coastguard Worker $method, 390*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 391*cc02d7e2SAndroid Build Coastguard Worker $options 392*cc02d7e2SAndroid Build Coastguard Worker ); 393*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri = $this->_get_jwt_aud_uri($method); 394*cc02d7e2SAndroid Build Coastguard Worker if (is_callable($this->update_metadata)) { 395*cc02d7e2SAndroid Build Coastguard Worker $metadata = call_user_func( 396*cc02d7e2SAndroid Build Coastguard Worker $this->update_metadata, 397*cc02d7e2SAndroid Build Coastguard Worker $metadata, 398*cc02d7e2SAndroid Build Coastguard Worker $jwt_aud_uri 399*cc02d7e2SAndroid Build Coastguard Worker ); 400*cc02d7e2SAndroid Build Coastguard Worker } 401*cc02d7e2SAndroid Build Coastguard Worker $metadata = $this->_validate_and_normalize_metadata( 402*cc02d7e2SAndroid Build Coastguard Worker $metadata 403*cc02d7e2SAndroid Build Coastguard Worker ); 404*cc02d7e2SAndroid Build Coastguard Worker $call->start($metadata); 405*cc02d7e2SAndroid Build Coastguard Worker 406*cc02d7e2SAndroid Build Coastguard Worker return $call; 407*cc02d7e2SAndroid Build Coastguard Worker }; 408*cc02d7e2SAndroid Build Coastguard Worker } 409*cc02d7e2SAndroid Build Coastguard Worker 410*cc02d7e2SAndroid Build Coastguard Worker /** 411*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create UnaryCall 412*cc02d7e2SAndroid Build Coastguard Worker * 413*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 414*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 415*cc02d7e2SAndroid Build Coastguard Worker * 416*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 417*cc02d7e2SAndroid Build Coastguard Worker */ 418*cc02d7e2SAndroid Build Coastguard Worker private function _UnaryUnaryCallFactory($channel) 419*cc02d7e2SAndroid Build Coastguard Worker { 420*cc02d7e2SAndroid Build Coastguard Worker if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { 421*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 422*cc02d7e2SAndroid Build Coastguard Worker $argument, 423*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 424*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 425*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 426*cc02d7e2SAndroid Build Coastguard Worker return $channel->getInterceptor()->interceptUnaryUnary( 427*cc02d7e2SAndroid Build Coastguard Worker $method, 428*cc02d7e2SAndroid Build Coastguard Worker $argument, 429*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 430*cc02d7e2SAndroid Build Coastguard Worker $this->_UnaryUnaryCallFactory($channel->getNext()), 431*cc02d7e2SAndroid Build Coastguard Worker $metadata, 432*cc02d7e2SAndroid Build Coastguard Worker $options 433*cc02d7e2SAndroid Build Coastguard Worker ); 434*cc02d7e2SAndroid Build Coastguard Worker }; 435*cc02d7e2SAndroid Build Coastguard Worker } 436*cc02d7e2SAndroid Build Coastguard Worker return $this->_GrpcUnaryUnary($channel); 437*cc02d7e2SAndroid Build Coastguard Worker } 438*cc02d7e2SAndroid Build Coastguard Worker 439*cc02d7e2SAndroid Build Coastguard Worker /** 440*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create ServerStreamingCall 441*cc02d7e2SAndroid Build Coastguard Worker * 442*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 443*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 444*cc02d7e2SAndroid Build Coastguard Worker * 445*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 446*cc02d7e2SAndroid Build Coastguard Worker */ 447*cc02d7e2SAndroid Build Coastguard Worker private function _UnaryStreamCallFactory($channel) 448*cc02d7e2SAndroid Build Coastguard Worker { 449*cc02d7e2SAndroid Build Coastguard Worker if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { 450*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 451*cc02d7e2SAndroid Build Coastguard Worker $argument, 452*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 453*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 454*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 455*cc02d7e2SAndroid Build Coastguard Worker return $channel->getInterceptor()->interceptUnaryStream( 456*cc02d7e2SAndroid Build Coastguard Worker $method, 457*cc02d7e2SAndroid Build Coastguard Worker $argument, 458*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 459*cc02d7e2SAndroid Build Coastguard Worker $this->_UnaryStreamCallFactory($channel->getNext()), 460*cc02d7e2SAndroid Build Coastguard Worker $metadata, 461*cc02d7e2SAndroid Build Coastguard Worker $options 462*cc02d7e2SAndroid Build Coastguard Worker ); 463*cc02d7e2SAndroid Build Coastguard Worker }; 464*cc02d7e2SAndroid Build Coastguard Worker } 465*cc02d7e2SAndroid Build Coastguard Worker return $this->_GrpcUnaryStream($channel); 466*cc02d7e2SAndroid Build Coastguard Worker } 467*cc02d7e2SAndroid Build Coastguard Worker 468*cc02d7e2SAndroid Build Coastguard Worker /** 469*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create ClientStreamingCall 470*cc02d7e2SAndroid Build Coastguard Worker * 471*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 472*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 473*cc02d7e2SAndroid Build Coastguard Worker * 474*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 475*cc02d7e2SAndroid Build Coastguard Worker */ 476*cc02d7e2SAndroid Build Coastguard Worker private function _StreamUnaryCallFactory($channel) 477*cc02d7e2SAndroid Build Coastguard Worker { 478*cc02d7e2SAndroid Build Coastguard Worker if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { 479*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 480*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 481*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 482*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 483*cc02d7e2SAndroid Build Coastguard Worker return $channel->getInterceptor()->interceptStreamUnary( 484*cc02d7e2SAndroid Build Coastguard Worker $method, 485*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 486*cc02d7e2SAndroid Build Coastguard Worker $this->_StreamUnaryCallFactory($channel->getNext()), 487*cc02d7e2SAndroid Build Coastguard Worker $metadata, 488*cc02d7e2SAndroid Build Coastguard Worker $options 489*cc02d7e2SAndroid Build Coastguard Worker ); 490*cc02d7e2SAndroid Build Coastguard Worker }; 491*cc02d7e2SAndroid Build Coastguard Worker } 492*cc02d7e2SAndroid Build Coastguard Worker return $this->_GrpcStreamUnary($channel); 493*cc02d7e2SAndroid Build Coastguard Worker } 494*cc02d7e2SAndroid Build Coastguard Worker 495*cc02d7e2SAndroid Build Coastguard Worker /** 496*cc02d7e2SAndroid Build Coastguard Worker * Create a function which can be used to create BidiStreamingCall 497*cc02d7e2SAndroid Build Coastguard Worker * 498*cc02d7e2SAndroid Build Coastguard Worker * @param Channel|InterceptorChannel $channel 499*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 500*cc02d7e2SAndroid Build Coastguard Worker * 501*cc02d7e2SAndroid Build Coastguard Worker * @return \Closure 502*cc02d7e2SAndroid Build Coastguard Worker */ 503*cc02d7e2SAndroid Build Coastguard Worker private function _StreamStreamCallFactory($channel) 504*cc02d7e2SAndroid Build Coastguard Worker { 505*cc02d7e2SAndroid Build Coastguard Worker if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { 506*cc02d7e2SAndroid Build Coastguard Worker return function ($method, 507*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 508*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 509*cc02d7e2SAndroid Build Coastguard Worker array $options = []) use ($channel) { 510*cc02d7e2SAndroid Build Coastguard Worker return $channel->getInterceptor()->interceptStreamStream( 511*cc02d7e2SAndroid Build Coastguard Worker $method, 512*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 513*cc02d7e2SAndroid Build Coastguard Worker $this->_StreamStreamCallFactory($channel->getNext()), 514*cc02d7e2SAndroid Build Coastguard Worker $metadata, 515*cc02d7e2SAndroid Build Coastguard Worker $options 516*cc02d7e2SAndroid Build Coastguard Worker ); 517*cc02d7e2SAndroid Build Coastguard Worker }; 518*cc02d7e2SAndroid Build Coastguard Worker } 519*cc02d7e2SAndroid Build Coastguard Worker return $this->_GrpcStreamStream($channel); 520*cc02d7e2SAndroid Build Coastguard Worker } 521*cc02d7e2SAndroid Build Coastguard Worker 522*cc02d7e2SAndroid Build Coastguard Worker /* This class is intended to be subclassed by generated code, so 523*cc02d7e2SAndroid Build Coastguard Worker * all functions begin with "_" to avoid name collisions. */ 524*cc02d7e2SAndroid Build Coastguard Worker /** 525*cc02d7e2SAndroid Build Coastguard Worker * Call a remote method that takes a single argument and has a 526*cc02d7e2SAndroid Build Coastguard Worker * single output. 527*cc02d7e2SAndroid Build Coastguard Worker * 528*cc02d7e2SAndroid Build Coastguard Worker * @param string $method The name of the method to call 529*cc02d7e2SAndroid Build Coastguard Worker * @param mixed $argument The argument to the method 530*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 531*cc02d7e2SAndroid Build Coastguard Worker * @param array $metadata A metadata map to send to the server 532*cc02d7e2SAndroid Build Coastguard Worker * (optional) 533*cc02d7e2SAndroid Build Coastguard Worker * @param array $options An array of options (optional) 534*cc02d7e2SAndroid Build Coastguard Worker * 535*cc02d7e2SAndroid Build Coastguard Worker * @return UnaryCall The active call object 536*cc02d7e2SAndroid Build Coastguard Worker */ 537*cc02d7e2SAndroid Build Coastguard Worker protected function _simpleRequest( 538*cc02d7e2SAndroid Build Coastguard Worker $method, 539*cc02d7e2SAndroid Build Coastguard Worker $argument, 540*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 541*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 542*cc02d7e2SAndroid Build Coastguard Worker array $options = [] 543*cc02d7e2SAndroid Build Coastguard Worker ) { 544*cc02d7e2SAndroid Build Coastguard Worker $call_factory = $this->_UnaryUnaryCallFactory($this->channel); 545*cc02d7e2SAndroid Build Coastguard Worker $call = $call_factory($method, $argument, $deserialize, $metadata, $options); 546*cc02d7e2SAndroid Build Coastguard Worker return $call; 547*cc02d7e2SAndroid Build Coastguard Worker } 548*cc02d7e2SAndroid Build Coastguard Worker 549*cc02d7e2SAndroid Build Coastguard Worker /** 550*cc02d7e2SAndroid Build Coastguard Worker * Call a remote method that takes a stream of arguments and has a single 551*cc02d7e2SAndroid Build Coastguard Worker * output. 552*cc02d7e2SAndroid Build Coastguard Worker * 553*cc02d7e2SAndroid Build Coastguard Worker * @param string $method The name of the method to call 554*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the response 555*cc02d7e2SAndroid Build Coastguard Worker * @param array $metadata A metadata map to send to the server 556*cc02d7e2SAndroid Build Coastguard Worker * (optional) 557*cc02d7e2SAndroid Build Coastguard Worker * @param array $options An array of options (optional) 558*cc02d7e2SAndroid Build Coastguard Worker * 559*cc02d7e2SAndroid Build Coastguard Worker * @return ClientStreamingCall The active call object 560*cc02d7e2SAndroid Build Coastguard Worker */ 561*cc02d7e2SAndroid Build Coastguard Worker protected function _clientStreamRequest( 562*cc02d7e2SAndroid Build Coastguard Worker $method, 563*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 564*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 565*cc02d7e2SAndroid Build Coastguard Worker array $options = [] 566*cc02d7e2SAndroid Build Coastguard Worker ) { 567*cc02d7e2SAndroid Build Coastguard Worker $call_factory = $this->_StreamUnaryCallFactory($this->channel); 568*cc02d7e2SAndroid Build Coastguard Worker $call = $call_factory($method, $deserialize, $metadata, $options); 569*cc02d7e2SAndroid Build Coastguard Worker return $call; 570*cc02d7e2SAndroid Build Coastguard Worker } 571*cc02d7e2SAndroid Build Coastguard Worker 572*cc02d7e2SAndroid Build Coastguard Worker /** 573*cc02d7e2SAndroid Build Coastguard Worker * Call a remote method that takes a single argument and returns a stream 574*cc02d7e2SAndroid Build Coastguard Worker * of responses. 575*cc02d7e2SAndroid Build Coastguard Worker * 576*cc02d7e2SAndroid Build Coastguard Worker * @param string $method The name of the method to call 577*cc02d7e2SAndroid Build Coastguard Worker * @param mixed $argument The argument to the method 578*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the responses 579*cc02d7e2SAndroid Build Coastguard Worker * @param array $metadata A metadata map to send to the server 580*cc02d7e2SAndroid Build Coastguard Worker * (optional) 581*cc02d7e2SAndroid Build Coastguard Worker * @param array $options An array of options (optional) 582*cc02d7e2SAndroid Build Coastguard Worker * 583*cc02d7e2SAndroid Build Coastguard Worker * @return ServerStreamingCall The active call object 584*cc02d7e2SAndroid Build Coastguard Worker */ 585*cc02d7e2SAndroid Build Coastguard Worker protected function _serverStreamRequest( 586*cc02d7e2SAndroid Build Coastguard Worker $method, 587*cc02d7e2SAndroid Build Coastguard Worker $argument, 588*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 589*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 590*cc02d7e2SAndroid Build Coastguard Worker array $options = [] 591*cc02d7e2SAndroid Build Coastguard Worker ) { 592*cc02d7e2SAndroid Build Coastguard Worker $call_factory = $this->_UnaryStreamCallFactory($this->channel); 593*cc02d7e2SAndroid Build Coastguard Worker $call = $call_factory($method, $argument, $deserialize, $metadata, $options); 594*cc02d7e2SAndroid Build Coastguard Worker return $call; 595*cc02d7e2SAndroid Build Coastguard Worker } 596*cc02d7e2SAndroid Build Coastguard Worker 597*cc02d7e2SAndroid Build Coastguard Worker /** 598*cc02d7e2SAndroid Build Coastguard Worker * Call a remote method with messages streaming in both directions. 599*cc02d7e2SAndroid Build Coastguard Worker * 600*cc02d7e2SAndroid Build Coastguard Worker * @param string $method The name of the method to call 601*cc02d7e2SAndroid Build Coastguard Worker * @param callable $deserialize A function that deserializes the responses 602*cc02d7e2SAndroid Build Coastguard Worker * @param array $metadata A metadata map to send to the server 603*cc02d7e2SAndroid Build Coastguard Worker * (optional) 604*cc02d7e2SAndroid Build Coastguard Worker * @param array $options An array of options (optional) 605*cc02d7e2SAndroid Build Coastguard Worker * 606*cc02d7e2SAndroid Build Coastguard Worker * @return BidiStreamingCall The active call object 607*cc02d7e2SAndroid Build Coastguard Worker */ 608*cc02d7e2SAndroid Build Coastguard Worker protected function _bidiRequest( 609*cc02d7e2SAndroid Build Coastguard Worker $method, 610*cc02d7e2SAndroid Build Coastguard Worker $deserialize, 611*cc02d7e2SAndroid Build Coastguard Worker array $metadata = [], 612*cc02d7e2SAndroid Build Coastguard Worker array $options = [] 613*cc02d7e2SAndroid Build Coastguard Worker ) { 614*cc02d7e2SAndroid Build Coastguard Worker $call_factory = $this->_StreamStreamCallFactory($this->channel); 615*cc02d7e2SAndroid Build Coastguard Worker $call = $call_factory($method, $deserialize, $metadata, $options); 616*cc02d7e2SAndroid Build Coastguard Worker return $call; 617*cc02d7e2SAndroid Build Coastguard Worker } 618*cc02d7e2SAndroid Build Coastguard Worker} 619