├── .gitignore
├── tests
├── composer.json
├── TestServiceClient.php
└── testClient.php
├── proto
├── rpc.proto
├── message.proto
└── generate.sh
├── README.md
├── composer.json
├── GPBMetadata
├── Rpc.php
└── Message.php
├── App
├── Message
│ ├── TestResponse.php
│ └── TestRequest.php
└── Service
│ ├── TestServiceService.php
│ └── TestService.php
├── config
└── debug
│ └── config.php
├── grpc
├── Entrance.php
└── server
│ └── MainServer.php
├── grpc_generator
├── php_generator.h
├── php_generator_helpers.h
├── php_plugin.cc
└── php_generator.cc
├── run.php
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | composer.lock
3 | vendor/
4 | *.pid
5 | test/vendor
6 | test/composer.lock
7 |
--------------------------------------------------------------------------------
/tests/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "google/protobuf": "^3.3.0",
4 | "grpc/grpc": "^1.3.4"
5 | }
6 | }
--------------------------------------------------------------------------------
/proto/rpc.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package App.Service;
4 |
5 | import "message.proto";
6 |
7 | service TestService
8 | {
9 | rpc Test(Message.TestRequest) returns (Message.TestResponse) {}
10 | }
--------------------------------------------------------------------------------
/proto/message.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package App.Message;
4 |
5 | message TestRequest {
6 | bytes name = 1;
7 | int64 id = 2;
8 | bool flag = 3;
9 | }
10 |
11 | message TestResponse {
12 | int64 status = 1;
13 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # swoole-grpc
2 | Grpc Implement base on Swoole Http2 Server
3 |
4 | # Document
5 |
6 | # Require
7 |
8 | * protobuf 3.3 +
9 | * grpc
10 | * Swoole 1.9.9 +
11 |
12 | # Install
13 |
14 | ## 安装Swoole扩展
15 |
16 | 需要开启Swoole扩展的http2和openssl支持
17 |
18 | ```bash
19 | ./configure --enable-async-redis --enable-http2 --enable-openssl
20 | make clean && make && make install
21 | ```
22 |
23 | # GRPC生成器
24 |
25 | 由于GRPC本身不支持PHP Server,因此原本的生成器也不支持生成Server端的代码。因此我修改了grpc php generator的代码,使用时,将grpc_generator目录下的文件复制到grpc的`src/compiler`目录下,然后重新编译安装即可。
--------------------------------------------------------------------------------
/proto/generate.sh:
--------------------------------------------------------------------------------
1 | CURRENT_PATH=`pwd`
2 | PROJECT_PATH=$(dirname $(pwd))
3 |
4 | PROTO_PATH=$CURRENT_PATH
5 | PHP_OUT=$PROJECT_PATH
6 | GRPC_OUT=$PROJECT_PATH
7 |
8 | GRPC_PLUGIN_PATH=/Users/lidanyang/Software/lib/grpc/bins/opt/grpc_php_plugin
9 | PROTOC_PATH=/usr/local/protobuf/bin/protoc
10 |
11 |
12 | for file in $PROTO_PATH/*
13 | do
14 | if [ "${file##*.}" = "proto" ];
15 | then
16 | FILE_LIST=${FILE_LIST}" ${file}";
17 | fi
18 | done
19 |
20 | $PROTOC_PATH --proto_path=$PROTO_PATH --php_out=$PHP_OUT --grpc_out=$GRPC_OUT --plugin=protoc-gen-grpc=$GRPC_PLUGIN_PATH $FILE_LIST
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cat-sys/swoole-grpc",
3 | "description": "Grpc Implement base on Swoole Http2 Server",
4 | "authors": [
5 | {
6 | "name": "lidanyang",
7 | "email": "lancelot2014@foxmail.com"
8 | }
9 | ],
10 | "require": {
11 | "php": ">=7",
12 | "ext-swoole": ">=1.9.10",
13 | "google/protobuf": "^3.3.0",
14 | "cat-sys/cat-core": "dev-master"
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "grpc\\":"grpc/",
19 | "App\\":"App/",
20 | "GPBMetadata\\":"GPBMetadata/"
21 | },
22 | "classmap": [
23 | "proto"
24 | ]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/GPBMetadata/Rpc.php:
--------------------------------------------------------------------------------
1 | internalAddGeneratedFile(hex2bin(
19 | "0a6e0a097270632e70726f746f120b4170702e53657276696365324c0a0b" .
20 | "5465737453657276696365123d0a045465737412182e4170702e4d657373" .
21 | "6167652e54657374526571756573741a192e4170702e4d6573736167652e" .
22 | "54657374526573706f6e73652200620670726f746f33"
23 | ));
24 |
25 | static::$is_initialized = true;
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/GPBMetadata/Message.php:
--------------------------------------------------------------------------------
1 | internalAddGeneratedFile(hex2bin(
18 | "0a7b0a0d6d6573736167652e70726f746f120b4170702e4d657373616765" .
19 | "22350a0b5465737452657175657374120c0a046e616d6518012001280c12" .
20 | "0a0a026964180220012803120c0a04666c6167180320012808221e0a0c54" .
21 | "657374526573706f6e7365120e0a06737461747573180120012803620670" .
22 | "726f746f33"
23 | ));
24 |
25 | static::$is_initialized = true;
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/tests/TestServiceClient.php:
--------------------------------------------------------------------------------
1 | _simpleRequest('/App.Service.TestService/Test',
25 | $argument,
26 | ['\App\Message\TestResponse', 'decode'],
27 | $metadata, $options);
28 | }
29 |
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/App/Message/TestResponse.php:
--------------------------------------------------------------------------------
1 | App.Message.TestResponse
13 | */
14 | class TestResponse extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * int64 status = 1;
18 | */
19 | private $status = 0;
20 |
21 | public function __construct() {
22 | \GPBMetadata\Message::initOnce();
23 | parent::__construct();
24 | }
25 |
26 | /**
27 | * int64 status = 1;
28 | */
29 | public function getStatus()
30 | {
31 | return $this->status;
32 | }
33 |
34 | /**
35 | * int64 status = 1;
36 | */
37 | public function setStatus($var)
38 | {
39 | GPBUtil::checkInt64($var);
40 | $this->status = $var;
41 | }
42 |
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/App/Service/TestServiceService.php:
--------------------------------------------------------------------------------
1 | decode($data);
25 | } else {
26 | $argument->mergeFromString($data);
27 | }
28 | $output = $this->Test($argument);
29 | if (method_exists($output, 'encode')) {
30 | return $output->encode();
31 | } else if(method_exists($output, 'serializeToString')){
32 | return $output->serializeToString();
33 | }
34 | return '';
35 | }
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/App/Service/TestService.php:
--------------------------------------------------------------------------------
1 | .
18 | *******************************************************************************
19 | * Author: Lidanyang
20 | ******************************************************************************/
21 |
22 | namespace App\Service;
23 |
24 | use App\Message\TestRequest;
25 | use App\Message\TestResponse;
26 |
27 | class TestService extends TestServiceService
28 | {
29 | /**
30 | * @param TestRequest $argument input argument
31 | * @return \App\Message\TestResponse output argument
32 | **/
33 | protected function Test(TestRequest $argument)
34 | {
35 | var_dump($argument->getName());
36 | $response = new TestResponse();
37 | $response->setStatus(200);
38 | return $response;
39 | }
40 | }
--------------------------------------------------------------------------------
/tests/testClient.php:
--------------------------------------------------------------------------------
1 | .
17 | *******************************************************************************
18 | * Author: Lidanyang
19 | ******************************************************************************/
20 |
21 | require_once __DIR__ . "/vendor/autoload.php";
22 | require_once __DIR__ . "/../vendor/autoload.php";
23 |
24 | require_once __DIR__ . "/TestServiceClient.php";
25 |
26 | $client = new \App\Service\TestServiceClient("0.0.0.0:9501", [
27 | 'credentials' => \Grpc\ChannelCredentials::createInsecure(),
28 | ]);
29 |
30 | $request = new \App\Message\TestRequest();
31 | $request->setName("Name");
32 | $request->setId(1);
33 | $request->setFlag(true);
34 |
35 | list($reply, $status) = $client->Test($request)->wait();
36 | var_dump($reply);
37 | var_dump($reply->getStatus());
--------------------------------------------------------------------------------
/config/debug/config.php:
--------------------------------------------------------------------------------
1 | .
17 | *******************************************************************************
18 | * Author: Lidanyang
19 | ******************************************************************************/
20 |
21 |
22 | return [
23 | 'project' => [
24 | 'project_name' => 'swoole-grpc',
25 | 'pid_path' => dirname(dirname(__DIR__)),
26 |
27 | 'main_server' => '\\grpc\\server\\MainServer',
28 | ],
29 |
30 | 'server' => [
31 | 'host' => '0.0.0.0',
32 | 'port' => '9501',
33 | 'socket_type' => 'http2',
34 | 'enable_ssl' => false,
35 |
36 | 'setting' => [
37 | 'worker_num' => 1,
38 | 'dispatch_mode' => 2,
39 |
40 | 'daemonize' => 0,
41 | ]
42 | ]
43 | ];
--------------------------------------------------------------------------------
/App/Message/TestRequest.php:
--------------------------------------------------------------------------------
1 | App.Message.TestRequest
13 | */
14 | class TestRequest extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * bytes name = 1;
18 | */
19 | private $name = '';
20 | /**
21 | * int64 id = 2;
22 | */
23 | private $id = 0;
24 | /**
25 | * bool flag = 3;
26 | */
27 | private $flag = false;
28 |
29 | public function __construct() {
30 | \GPBMetadata\Message::initOnce();
31 | parent::__construct();
32 | }
33 |
34 | /**
35 | * bytes name = 1;
36 | */
37 | public function getName()
38 | {
39 | return $this->name;
40 | }
41 |
42 | /**
43 | * bytes name = 1;
44 | */
45 | public function setName($var)
46 | {
47 | GPBUtil::checkString($var, False);
48 | $this->name = $var;
49 | }
50 |
51 | /**
52 | * int64 id = 2;
53 | */
54 | public function getId()
55 | {
56 | return $this->id;
57 | }
58 |
59 | /**
60 | * int64 id = 2;
61 | */
62 | public function setId($var)
63 | {
64 | GPBUtil::checkInt64($var);
65 | $this->id = $var;
66 | }
67 |
68 | /**
69 | * bool flag = 3;
70 | */
71 | public function getFlag()
72 | {
73 | return $this->flag;
74 | }
75 |
76 | /**
77 | * bool flag = 3;
78 | */
79 | public function setFlag($var)
80 | {
81 | GPBUtil::checkBool($var);
82 | $this->flag = $var;
83 | }
84 |
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/grpc/Entrance.php:
--------------------------------------------------------------------------------
1 | .
17 | *******************************************************************************
18 | * Author: Lidanyang
19 | ******************************************************************************/
20 |
21 | namespace grpc;
22 |
23 | use core\component\config\Config;
24 | use core\server\IServer;
25 | use core\server\SwooleServer;
26 |
27 | class Entrance
28 | {
29 | public static function run()
30 | {
31 | $server = new SwooleServer(Config::get('server'));
32 |
33 | $main_server_class = Config::getField('project', 'main_server');
34 | if(!class_exists($main_server_class))
35 | {
36 | throw new \Exception("No class {$main_server_class}");
37 | }
38 | $main_server = new $main_server_class(
39 | Config::getField('project', 'project_name'),
40 | Config::getField('project', 'pid_path')
41 | );
42 | if(!($main_server instanceof IServer))
43 | {
44 | throw new \Exception("{$main_server_class} is not IServer");
45 | }
46 | $server->run($main_server);
47 | }
48 | }
--------------------------------------------------------------------------------
/grpc_generator/php_generator.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2016, Google Inc.
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are
8 | * met:
9 | *
10 | * * Redistributions of source code must retain the above copyright
11 | * notice, this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above
13 | * copyright notice, this list of conditions and the following disclaimer
14 | * in the documentation and/or other materials provided with the
15 | * distribution.
16 | * * Neither the name of Google Inc. nor the names of its
17 | * contributors may be used to endorse or promote products derived from
18 | * this software without specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 |
34 | #ifndef GRPC_INTERNAL_COMPILER_PHP_GENERATOR_H
35 | #define GRPC_INTERNAL_COMPILER_PHP_GENERATOR_H
36 |
37 | #include "src/compiler/config.h"
38 |
39 | namespace grpc_php_generator {
40 |
41 | grpc::string GenerateFile(const grpc::protobuf::FileDescriptor *file,
42 | const grpc::protobuf::ServiceDescriptor *service);
43 |
44 | grpc::string GenerateServer(const grpc::protobuf::FileDescriptor *file,
45 | const grpc::protobuf::ServiceDescriptor *service);
46 |
47 | } // namespace grpc_php_generator
48 | #endif // GRPC_INTERNAL_COMPILER_PHP_GENERATOR_H
49 |
--------------------------------------------------------------------------------
/run.php:
--------------------------------------------------------------------------------
1 | .
17 | *******************************************************************************
18 | * Author: Lidanyang
19 | ******************************************************************************/
20 |
21 | require_once __DIR__ . "/vendor/autoload.php";
22 |
23 | use grpc\Entrance;
24 |
25 | function usage()
26 | {
27 | echo "php run.php start | restart | stop | reload [-c config_path]\n";
28 | }
29 |
30 | if( !isset($argv[1]) )
31 | {
32 | usage();
33 | exit;
34 | }
35 |
36 | $cmd = $argv[1];
37 |
38 | if( isset($argv[2]) && $argv[2] == '-c' ) {
39 | $debug = $argv[3];
40 | } else {
41 | $debug = "debug";
42 | }
43 |
44 | \core\component\config\Config::load(__DIR__ . "/config/{$debug}/");
45 |
46 | $config = \core\component\config\Config::get('project');
47 |
48 | $pid_path = $config['pid_path'] . '/' . $config['project_name'] . '_master.pid';
49 | $manager_pid_path = $config['pid_path'] . '/' . $config['project_name'] . '_manager.pid';
50 |
51 | switch($cmd)
52 | {
53 | case 'start':
54 | {
55 |
56 | Entrance::run();
57 | break;
58 | }
59 | case 'restart':
60 | {
61 |
62 | shell_exec("kill -15 `cat {$manager_pid_path}`");
63 | shell_exec("kill -15 `cat {$pid_path}`");
64 | echo "restarting...\n";
65 | sleep(3);
66 |
67 | Entrance::run();
68 | break;
69 | }
70 | case 'stop':
71 | {
72 | shell_exec("kill -15 `cat {$manager_pid_path}`");
73 | shell_exec("kill -15 `cat {$pid_path}`");
74 | break;
75 | }
76 | case 'reload':
77 | {
78 | shell_exec("kill -USR1 `cat {$manager_pid_path}`");
79 | shell_exec("kill -USR1 `cat {$pid_path}`");
80 | break;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/grpc_generator/php_generator_helpers.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2016, Google Inc.
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are
8 | * met:
9 | *
10 | * * Redistributions of source code must retain the above copyright
11 | * notice, this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above
13 | * copyright notice, this list of conditions and the following disclaimer
14 | * in the documentation and/or other materials provided with the
15 | * distribution.
16 | * * Neither the name of Google Inc. nor the names of its
17 | * contributors may be used to endorse or promote products derived from
18 | * this software without specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 |
34 | #ifndef GRPC_INTERNAL_COMPILER_PHP_GENERATOR_HELPERS_H
35 | #define GRPC_INTERNAL_COMPILER_PHP_GENERATOR_HELPERS_H
36 |
37 | #include
38 |
39 | #include "src/compiler/config.h"
40 | #include "src/compiler/generator_helpers.h"
41 |
42 | namespace grpc_php_generator {
43 |
44 | inline grpc::string GetPHPServiceFilename(
45 | const grpc::protobuf::FileDescriptor *file,
46 | const grpc::protobuf::ServiceDescriptor *service) {
47 | std::vector tokens =
48 | grpc_generator::tokenize(file->package(), ".");
49 | std::ostringstream oss;
50 | for (unsigned int i = 0; i < tokens.size(); i++) {
51 | oss << (i == 0 ? "" : "/")
52 | << grpc_generator::CapitalizeFirstLetter(tokens[i]);
53 | }
54 | return oss.str() + "/" + service->name() + "Client.php";
55 | }
56 |
57 | inline grpc::string GetPHPServerFilename(
58 | const grpc::protobuf::FileDescriptor *file,
59 | const grpc::protobuf::ServiceDescriptor *service) {
60 | std::vector tokens =
61 | grpc_generator::tokenize(file->package(), ".");
62 | std::ostringstream oss;
63 | for (unsigned int i = 0; i < tokens.size(); i++) {
64 | oss << (i == 0 ? "" : "/")
65 | << grpc_generator::CapitalizeFirstLetter(tokens[i]);
66 | }
67 | return oss.str() + "/" + service->name() + "Service.php";
68 | }
69 |
70 | // Get leading or trailing comments in a string. Comment lines start with "// ".
71 | // Leading detached comments are put in in front of leading comments.
72 | template
73 | inline grpc::string GetPHPComments(const DescriptorType *desc,
74 | grpc::string prefix) {
75 | return grpc_generator::GetPrefixedComments(desc, true, prefix);
76 | }
77 |
78 | } // namespace grpc_php_generator
79 |
80 | #endif // GRPC_INTERNAL_COMPILER_PHP_GENERATOR_HELPERS_H
81 |
--------------------------------------------------------------------------------
/grpc_generator/php_plugin.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2016, Google Inc.
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are
8 | * met:
9 | *
10 | * * Redistributions of source code must retain the above copyright
11 | * notice, this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above
13 | * copyright notice, this list of conditions and the following disclaimer
14 | * in the documentation and/or other materials provided with the
15 | * distribution.
16 | * * Neither the name of Google Inc. nor the names of its
17 | * contributors may be used to endorse or promote products derived from
18 | * this software without specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 |
34 | // Generates PHP gRPC service interface out of Protobuf IDL.
35 |
36 | #include
37 |
38 | #include "src/compiler/config.h"
39 | #include "src/compiler/php_generator.h"
40 | #include "src/compiler/php_generator_helpers.h"
41 |
42 | using grpc_php_generator::GenerateFile;
43 | using grpc_php_generator::GetPHPServiceFilename;
44 | using grpc_php_generator::GetPHPServerFilename;
45 | using grpc_php_generator::GenerateServer;
46 |
47 | class PHPGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
48 | public:
49 | PHPGrpcGenerator() {}
50 | ~PHPGrpcGenerator() {}
51 |
52 | bool Generate(const grpc::protobuf::FileDescriptor *file,
53 | const grpc::string ¶meter,
54 | grpc::protobuf::compiler::GeneratorContext *context,
55 | grpc::string *error) const {
56 | if (file->service_count() == 0) {
57 | return true;
58 | }
59 |
60 | for (int i = 0; i < file->service_count(); i++) {
61 | grpc::string code = GenerateFile(file, file->service(i));
62 |
63 | // Get output file name
64 | grpc::string file_name = GetPHPServiceFilename(file, file->service(i));
65 |
66 | std::unique_ptr output(
67 | context->Open(file_name));
68 | grpc::protobuf::io::CodedOutputStream coded_out(output.get());
69 | coded_out.WriteRaw(code.data(), code.size());
70 | }
71 |
72 | for (int i = 0; i < file->service_count(); i++) {
73 | grpc::string code = GenerateServer(file, file->service(i));
74 |
75 | // Get output file name
76 | grpc::string file_name = GetPHPServerFilename(file, file->service(i));
77 |
78 | std::unique_ptr output(
79 | context->Open(file_name));
80 | grpc::protobuf::io::CodedOutputStream coded_out(output.get());
81 | coded_out.WriteRaw(code.data(), code.size());
82 | }
83 |
84 | return true;
85 | }
86 | };
87 |
88 | int main(int argc, char *argv[]) {
89 | PHPGrpcGenerator generator;
90 | return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
91 | }
92 |
--------------------------------------------------------------------------------
/grpc/server/MainServer.php:
--------------------------------------------------------------------------------
1 | .
17 | *******************************************************************************
18 | * Author: Lidanyang
19 | ******************************************************************************/
20 |
21 | namespace grpc\server;
22 |
23 | use core\common\Globals;
24 | use core\component\log\Log;
25 | use core\server\adapter\HttpServer;
26 |
27 | class MainServer extends HttpServer
28 | {
29 | /**
30 | * 初始化函数,在swoole_server启动前执行
31 | * @param $server
32 | */
33 | public function init(\swoole_server $server)
34 | {
35 |
36 | }
37 |
38 |
39 | /**
40 | * 服务器接收到Http完整数据包后回调此函数
41 | * @param \swoole_http_request $request swoole封装的http请求对象
42 | * @param \swoole_http_response $response swoole封装的http应答对象
43 | */
44 | public function onRequest(\swoole_http_request $request, \swoole_http_response $response)
45 | {
46 | $uri = $request->server['request_uri'];
47 | $uris = explode("/", $uri);
48 |
49 | $class = str_replace("." , '\\', $uris[1]);
50 | $method = "run" . $uris[2];
51 |
52 | if(!class_exists($class))
53 | {
54 | Log::ERROR("System", "$class not found");
55 | $response->status(403);
56 | $response->end();
57 | return;
58 | }
59 |
60 | $rawContent = $data = substr($request->rawContent(), 5);
61 |
62 | try {
63 | $service = new $class();
64 |
65 | $result = $service->$method($rawContent);
66 |
67 | $data = pack('CN', 0, strlen($result)) . $result;
68 | $response->end($data);
69 | } catch (\Exception $e) {
70 | Log::ERROR("System", $e->getMessage());
71 | $response->status(500);
72 | $response->end($e->getMessage());
73 | } catch (\Error $e) {
74 | Log::ERROR("System", $e->getMessage());
75 | $response->status(500);
76 | $response->end($e->getMessage());
77 | }
78 | }
79 |
80 |
81 | /**
82 | * Worker进程启动前回调此函数
83 | * @param \swoole_server $server swoole_server对象
84 | * @param int $workerId Worker进程ID
85 | */
86 | public function onWorkerStart(\swoole_server $server, $workerId)
87 | {
88 | Globals::$server = $server;
89 | }
90 |
91 | /**
92 | * 当Worker进程投递任务到Task Worker进程时调用此函数
93 | * @param \swoole_server $server swoole_server对象
94 | * @param int $task_id 任务ID
95 | * @param int $src_worker_id 发起任务的Worker进程ID
96 | * @param mixed $data 任务数据
97 | */
98 | public function onTask(\swoole_server $server, $task_id, $src_worker_id, $data)
99 | {
100 | // TODO: Implement onTask() method.
101 | }
102 |
103 | /**
104 | * Swoole进程间通信的回调函数
105 | * @param \swoole_server $server swoole_server对象
106 | * @param int $from_worker_id 来源Worker进程ID
107 | * @param mixed $message 消息内容
108 | */
109 | public function onPipeMessage(\swoole_server $server, $from_worker_id, $message)
110 | {
111 | // TODO: Implement onPipeMessage() method.
112 | }
113 | }
--------------------------------------------------------------------------------
/grpc_generator/php_generator.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2016, Google Inc.
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are
8 | * met:
9 | *
10 | * * Redistributions of source code must retain the above copyright
11 | * notice, this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above
13 | * copyright notice, this list of conditions and the following disclaimer
14 | * in the documentation and/or other materials provided with the
15 | * distribution.
16 | * * Neither the name of Google Inc. nor the names of its
17 | * contributors may be used to endorse or promote products derived from
18 | * this software without specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 |
34 | #include