1<?php 2/* 3 * 4 * Copyright 2020 gRPC authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 */ 19 20namespace Grpc; 21 22/** 23 * This is an experimental and incomplete implementation of gRPC server 24 * for PHP. APIs are _definitely_ going to be changed. 25 * 26 * DO NOT USE in production. 27 */ 28 29class ServerCallWriter 30{ 31 public function __construct($call, $serverContext) 32 { 33 $this->call_ = $call; 34 $this->serverContext_ = $serverContext; 35 } 36 37 public function start( 38 $data = null, 39 array $options = [] 40 ) { 41 $batch = []; 42 $this->addSendInitialMetadataOpIfNotSent( 43 $batch, 44 $this->serverContext_->initialMetadata() 45 ); 46 $this->addSendMessageOpIfHasData($batch, $data, $options); 47 $this->call_->startBatch($batch); 48 } 49 50 public function write( 51 $data, 52 array $options = [] 53 ) { 54 $batch = []; 55 $this->addSendInitialMetadataOpIfNotSent( 56 $batch, 57 $this->serverContext_->initialMetadata() 58 ); 59 $this->addSendMessageOpIfHasData($batch, $data, $options); 60 $this->call_->startBatch($batch); 61 } 62 63 public function finish( 64 $data = null, 65 array $options = [] 66 ) { 67 $batch = [ 68 OP_SEND_STATUS_FROM_SERVER => 69 $this->serverContext_->status() ?? Status::ok(), 70 OP_RECV_CLOSE_ON_SERVER => true, 71 ]; 72 $this->addSendInitialMetadataOpIfNotSent( 73 $batch, 74 $this->serverContext_->initialMetadata() 75 ); 76 $this->addSendMessageOpIfHasData($batch, $data, $options); 77 $this->call_->startBatch($batch); 78 } 79 80 //////////////////////////// 81 82 private function addSendInitialMetadataOpIfNotSent( 83 array &$batch, 84 array $initialMetadata = null 85 ) { 86 if (!$this->initialMetadataSent_) { 87 $batch[OP_SEND_INITIAL_METADATA] = $initialMetadata ?? []; 88 $this->initialMetadataSent_ = true; 89 } 90 } 91 92 private function addSendMessageOpIfHasData( 93 array &$batch, 94 $data = null, 95 array $options = [] 96 ) { 97 if ($data) { 98 $message_array = ['message' => $data->serializeToString()]; 99 if (array_key_exists('flags', $options)) { 100 $message_array['flags'] = $options['flags']; 101 } 102 $batch[OP_SEND_MESSAGE] = $message_array; 103 } 104 } 105 106 private $call_; 107 private $initialMetadataSent_ = false; 108 private $serverContext_; 109} 110