| <?php |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| * |
| * @package thrift.processor |
| */ |
| |
| namespace Thrift; |
| |
| use Thrift\Exception\TException; |
| use Thrift\Protocol\TProtocol; |
| use Thrift\Protocol\TMultiplexedProtocol; |
| use Thrift\Type\TMessageType; |
| |
| /** |
| * <code>TMultiplexedProcessor</code> is a Processor allowing |
| * a single <code>TServer</code> to provide multiple services. |
| * |
| * <p>To do so, you instantiate the processor and then register additional |
| * processors with it, as shown in the following example:</p> |
| * |
| * <blockquote><code> |
| * $processor = new TMultiplexedProcessor(); |
| * |
| * processor->registerProcessor( |
| * "Calculator", |
| * new \tutorial\CalculatorProcessor(new CalculatorHandler())); |
| * |
| * processor->registerProcessor( |
| * "WeatherReport", |
| * new \tutorial\WeatherReportProcessor(new WeatherReportHandler())); |
| * |
| * $processor->process($protocol, $protocol); |
| * </code></blockquote> |
| */ |
| |
| class TMultiplexedProcessor |
| { |
| private $serviceProcessorMap_; |
| |
| /** |
| * 'Register' a service with this <code>TMultiplexedProcessor</code>. This |
| * allows us to broker requests to individual services by using the service |
| * name to select them at request time. |
| * |
| * @param serviceName Name of a service, has to be identical to the name |
| * declared in the Thrift IDL, e.g. "WeatherReport". |
| * @param processor Implementation of a service, usually referred to |
| * as "handlers", e.g. WeatherReportHandler implementing WeatherReport.Iface. |
| */ |
| public function registerProcessor($serviceName, $processor) |
| { |
| $this->serviceProcessorMap_[$serviceName] = $processor; |
| } |
| |
| /** |
| * This implementation of <code>process</code> performs the following steps: |
| * |
| * <ol> |
| * <li>Read the beginning of the message.</li> |
| * <li>Extract the service name from the message.</li> |
| * <li>Using the service name to locate the appropriate processor.</li> |
| * <li>Dispatch to the processor, with a decorated instance of TProtocol |
| * that allows readMessageBegin() to return the original Message.</li> |
| * </ol> |
| * |
| * @throws TException If the message type is not CALL or ONEWAY, if |
| * the service name was not found in the message, or if the service |
| * name was not found in the service map. |
| */ |
| public function process(TProtocol $input, TProtocol $output) |
| { |
| /* |
| Use the actual underlying protocol (e.g. TBinaryProtocol) to read the |
| message header. This pulls the message "off the wire", which we'll |
| deal with at the end of this method. |
| */ |
| $input->readMessageBegin($fname, $mtype, $rseqid); |
| |
| if ($mtype !== TMessageType::CALL && $mtype != TMessageType::ONEWAY) { |
| throw new TException("This should not have happened!?"); |
| } |
| |
| // Extract the service name and the new Message name. |
| if (strpos($fname, TMultiplexedProtocol::SEPARATOR) === false) { |
| throw new TException("Service name not found in message name: {$fname}. Did you " . |
| "forget to use a TMultiplexProtocol in your client?"); |
| } |
| list($serviceName, $messageName) = explode(':', $fname, 2); |
| if (!array_key_exists($serviceName, $this->serviceProcessorMap_)) { |
| throw new TException("Service name not found: {$serviceName}. Did you forget " . |
| "to call registerProcessor()?"); |
| } |
| |
| // Dispatch processing to the stored processor |
| $processor = $this->serviceProcessorMap_[$serviceName]; |
| |
| return $processor->process( |
| new StoredMessageProtocol($input, $messageName, $mtype, $rseqid), |
| $output |
| ); |
| } |
| } |