1: <?php
2: /*
3: *
4: * Copyright 2015, Google Inc.
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions are
9: * met:
10: *
11: * * Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * * Redistributions in binary form must reproduce the above
14: * copyright notice, this list of conditions and the following disclaimer
15: * in the documentation and/or other materials provided with the
16: * distribution.
17: * * Neither the name of Google Inc. nor the names of its
18: * contributors may be used to endorse or promote products derived from
19: * this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: *
33: */
34:
35: namespace Grpc;
36:
37: /**
38: * Represents an active call that allows for sending and recieving messages
39: * in streams in any order.
40: */
41: class BidiStreamingCall extends AbstractCall
42: {
43: /**
44: * Start the call.
45: *
46: * @param array $metadata Metadata to send with the call, if applicable
47: * (optional)
48: */
49: public function start(array $metadata = [])
50: {
51: $this->call->startBatch([
52: OP_SEND_INITIAL_METADATA => $metadata,
53: ]);
54: }
55:
56: /**
57: * Reads the next value from the server.
58: *
59: * @return mixed The next value from the server, or null if there is none
60: */
61: public function read()
62: {
63: $batch = [OP_RECV_MESSAGE => true];
64: if ($this->metadata === null) {
65: $batch[OP_RECV_INITIAL_METADATA] = true;
66: }
67: $read_event = $this->call->startBatch($batch);
68: if ($this->metadata === null) {
69: $this->metadata = $read_event->metadata;
70: }
71:
72: return $this->_deserializeResponse($read_event->message);
73: }
74:
75: /**
76: * Write a single message to the server. This cannot be called after
77: * writesDone is called.
78: *
79: * @param ByteBuffer $data The data to write
80: * @param array $options An array of options, possible keys:
81: * 'flags' => a number (optional)
82: */
83: public function write($data, array $options = [])
84: {
85: $message_array = ['message' => $this->_serializeMessage($data)];
86: if (array_key_exists('flags', $options)) {
87: $message_array['flags'] = $options['flags'];
88: }
89: $this->call->startBatch([
90: OP_SEND_MESSAGE => $message_array,
91: ]);
92: }
93:
94: /**
95: * Indicate that no more writes will be sent.
96: */
97: public function writesDone()
98: {
99: $this->call->startBatch([
100: OP_SEND_CLOSE_FROM_CLIENT => true,
101: ]);
102: }
103:
104: /**
105: * Wait for the server to send the status, and return it.
106: *
107: * @return \stdClass The status object, with integer $code, string
108: * $details, and array $metadata members
109: */
110: public function getStatus()
111: {
112: $status_event = $this->call->startBatch([
113: OP_RECV_STATUS_ON_CLIENT => true,
114: ]);
115:
116: $this->trailing_metadata = $status_event->status->metadata;
117:
118: return $status_event->status;
119: }
120: }
121: