{"id":13748154,"url":"https://github.com/137-rick/Dora-RPC","last_synced_at":"2025-05-09T10:32:16.148Z","repository":{"id":33533810,"uuid":"37179914","full_name":"137-rick/Dora-RPC","owner":"137-rick","description":"DoraRPC is an RPC For the PHP MicroService by The Swoole","archived":false,"fork":false,"pushed_at":"2018-06-05T14:43:35.000Z","size":249,"stargazers_count":468,"open_issues_count":5,"forks_count":101,"subscribers_count":39,"default_branch":"master","last_synced_at":"2025-03-30T05:01:51.814Z","etag":null,"topics":["dora","dora-rpc","php","rpc","service-discovery","swoole","tcp"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/137-rick.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-10T06:36:29.000Z","updated_at":"2024-08-29T09:21:44.000Z","dependencies_parsed_at":"2022-09-06T23:31:02.400Z","dependency_job_id":null,"html_url":"https://github.com/137-rick/Dora-RPC","commit_stats":null,"previous_names":["xcl3721/dora-rpc"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/137-rick%2FDora-RPC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/137-rick%2FDora-RPC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/137-rick%2FDora-RPC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/137-rick%2FDora-RPC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/137-rick","download_url":"https://codeload.github.com/137-rick/Dora-RPC/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253234178,"owners_count":21875561,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dora","dora-rpc","php","rpc","service-discovery","swoole","tcp"],"created_at":"2024-08-03T07:00:35.760Z","updated_at":"2025-05-09T10:32:15.842Z","avatar_url":"https://github.com/137-rick.png","language":"PHP","funding_links":[],"categories":["Server"],"sub_categories":[],"readme":"# Dora RPC\n \n[![Build Status](https://travis-ci.org/xcl3721/Dora-RPC.svg?branch=master)](https://travis-ci.org/xcl3721/Dora-RPC) [![Latest Stable Version](https://poser.pugx.org/xcl3721/dora-rpc/v/stable)](https://packagist.org/packages/xcl3721/dora-rpc) [![Latest Unstable Version](https://poser.pugx.org/xcl3721/dora-rpc/v/unstable)](https://packagist.org/packages/xcl3721/dora-rpc) [![License](https://poser.pugx.org/xcl3721/dora-rpc/license)](https://packagist.org/packages/xcl3721/dora-rpc)\n## 简介(Introduction)\n\nDora RPC 是一款基础于Swoole定长包头通讯协议的最精简的RPC, 用于复杂项目前后端分离，分离后项目都通过API工作可更好的跟踪、升级、维护及管理。\n\n问题提交: [Issue](https://github.com/xcl3721/Dora-RPC/issues)\n\nFor complex projects separation, the project can be better maintained by the API project management.\n\u003e * Dora RPC is an Basic Swoole Fixed Header TCP Proctol tiny RPC\n\u003e * Now support an simple PHP version \n\u003e * If you find something wrong,please submit an issue\n\u003e * add the http protocol and KeepAlive for the other program language\n\n\n# 设计思路(Design)\n\u003e * http://blog.sina.com.cn/s/blog_54ef39890102vs3h.html 架构设计图\n\u003e * http://blog.sina.com.cn/s/blog_54ef39890102w8ff.html 端午升级介绍\n\u003e * http://wenku.baidu.com/view/ae8adf90e518964bce847c43.html Dora-RPC 思想介绍\n\n# 功能支持(Function)\n\u003e * 支持单API调用，多API并发调用\n\u003e * 支持同步调用，异步任务下发不等待结果，异步任务下发统一拿回结果\n\u003e * 其他相关知识请参考Swoole扩展\n\u003e * 客户端长链接，请求完毕后仍旧保留，减少握手消耗\n\u003e * guid收发一致性检测，避免发送和接收数据不一致\n\u003e * 基于redis制作的服务发现\n\n\u003e * Single API RPC \\ Multi API Concurrent RPC\n\u003e * Asynchronous，synchronization no need result， synchronization get result by manual\n\u003e * Please visit Swoole official for further infomation\n\u003e * keep the connection of client after the request finishe\n\u003e * check the guid when the send\u003c-\u003erecive\n\u003e * service discovery.\n\u003e * base on Redis. Service discovery for High available\n\n## 请安装依赖(depend)\n\u003e * Swoole 1.8.x+\n\u003e * PHP 5.4+\n\u003e * zlib for compress packet\n\n##Installation\n```\ncomposer require \"xcl3721/dora-rpc\"\n```\n\n## 文件功能简介(File)\n### dora-rpc/src/Client.php\n\u003e * 使用最简单的方式实现的客户端，通过这个框架可以轻松实现PHP的伪多线程，通过分布式加快接口响应速度及高可用\n\u003e * an simple client,it's easy adn simply to implement the multi fake thread,you can speed up you API by this distribute RPC\n\n### dora-rpc/src/BackEndServer.php\n\u003e * API服务端\n\u003e * 目前需要继承才能使用，继承后请实现dowork，这个函数是实际处理任务的函数参数为提交参数\n\u003e * 做这个只是为了减少大家启用RPC的开发时间\n\u003e * 开启服务发现功能，服务端在启动的时候，如果指定redis配置则会自动将当前服务器信息注册到Redis上\n\u003e * 返回结果是一个数组 分两部分，第一层是通讯状态code，第二层是处理状态 code\n\n\u003e * a powerful API server\n\u003e * you must extends the swserver and implement dowork function\n\u003e * it's use for decrease the dev cycle\n\u003e * when you setup the redis config the server will register this server to the redis for service discovery\n\u003e * the result will be a two-level arrayfirst is communicate state 'code field' ,second is dowork state\n\n### dora-rpc/src/Monitor.php\n\u003e * 服务发现客户端，通过扫描Redis获取到所有可用后端服务列表，并生成配置到指定路径\n\u003e * an discovery controller client that:scan all the redis and get the list of available service and general config file to special path\n\n### dora-rpc/src/groupclient.php (combined to client.php)\n\u003e * 服务发现monitor进程产生的配置可以用这个客户端直接引用，请求时可以指定使用哪个组的服务\n\u003e * an client for service discovery （monitor general the config from redis） that you can use the config directly \n\n## 使用方法(Example)\n### 任务下发模式介绍(task deploy mode)\n\u003e * 0 sync wait result 同步下发任务阻塞等待结果返回\n\u003e * 1 async no need result 下发异步任务，下发成功返回下发成功提示，不等待任务处理结果\n\u003e * 2 async get result by getAsyncData function 下发异步任务，下发成功返回下发成功提示，可以在后续调用getAsyncData 获取所有下发的异步结果\n\n### TCP客户端(TCP Client)\n```PHP\n\n$config = include(\"client.conf.php\");\n//define the mode\n$mode = array(\"type\" =\u003e 1, \"group\" =\u003e \"group1\");\n\n$maxrequest = 0;\n\n//new obj\n$obj = new \\DoraRPC\\Client($config);\n\n//change connect mode\n$obj-\u003echangeMode($mode);\n\nfor ($i = 0; $i \u003c 10000; $i++) {\n    //echo $i . PHP_EOL;\n\n    //single\n    $time = microtime(true);\n\n    //single \u0026\u0026 sync\n    $ret = $obj-\u003esingleAPI(\"/module_a/abc\" . $i, array(\"mark\" =\u003e 234, \"foo\" =\u003e $i), \\DoraRPC\\DoraConst::SW_MODE_WAITRESULT, 1);\n    var_dump(\"single sync\", $ret);\n\n    //single call \u0026\u0026 async\n    $ret = $obj-\u003esingleAPI(\"/module_b/abc\" . $i, array(\"yes\" =\u003e 21321, \"foo\" =\u003e $i), \\DoraRPC\\DoraConst::SW_MODE_NORESULT, 1);\n    var_dump(\"single async\", $ret);\n\n    //single call \u0026\u0026 async\n    $ret = $obj-\u003esingleAPI(\"/module_c/abd\" . $i, array(\"yes\" =\u003e 233, \"foo\" =\u003e $i), \\DoraRPC\\DoraConst::SW_MODE_ASYNCRESULT, 1);\n    var_dump(\"single async result\", $ret);\n\n    //multi\n\n    //multi \u0026\u0026 sync\n    $data = array(\n        \"oak\" =\u003e array(\"name\" =\u003e \"/module_c/dd\" . $i, \"param\" =\u003e array(\"uid\" =\u003e \"ff\")),\n        \"cd\" =\u003e array(\"name\" =\u003e \"/module_f/ef\" . $i, \"param\" =\u003e array(\"pathid\" =\u003e \"fds\")),\n    );\n    $ret = $obj-\u003emultiAPI($data, \\DoraRPC\\DoraConst::SW_MODE_WAITRESULT, 1);\n    var_dump(\"multi sync\", $ret);\n\n    //multi \u0026\u0026 async\n    $data = array(\n        \"oak\" =\u003e array(\"name\" =\u003e \"/module_d/oakdf\" . $i, \"param\" =\u003e array(\"dsaf\" =\u003e \"32111321\")),\n        \"cd\" =\u003e array(\"name\" =\u003e \"/module_e/oakdfff\" . $i, \"param\" =\u003e array(\"codo\" =\u003e \"f11ds\")),\n    );\n    $ret = $obj-\u003emultiAPI($data, \\DoraRPC\\DoraConst::SW_MODE_NORESULT, 1);\n    var_dump(\"multi async\", $ret);\n\n    //multi \u0026\u0026 async\n    $data = array(\n        \"oak\" =\u003e array(\"name\" =\u003e \"/module_a/oakdf\" . $i, \"param\" =\u003e array(\"dsaf\" =\u003e \"11\")),\n        \"cd\" =\u003e array(\"name\" =\u003e \"/module_b/oakdfff\" . $i, \"param\" =\u003e array(\"codo\" =\u003e \"f11ds\")),\n    );\n    $ret = $obj-\u003emultiAPI($data, \\DoraRPC\\DoraConst::SW_MODE_ASYNCRESULT, 1);\n    var_dump(\"multi async result\", $ret);\n\n    //get all the async result\n    $data = $obj-\u003egetAsyncData();\n    var_dump(\"allresult\", $data);\n    \n    //compare each request\n    $time = bcsub(microtime(true), $time, 5);\n    if ($time \u003e $maxrequest) {\n        $maxrequest = $time;\n    }\n    echo $i . \" cost:\" . $time . PHP_EOL;\n}\necho \"max:\" . $maxrequest . PHP_EOL;\n\n```\n\n### HTTP客户端(Http Client)\n\nhttp protocol for the other language use performance is common.suggest used tcp client\n```PHP\n\nfor ($i = 0; $i \u003c 10000; $i++) {\n    $time = microtime(true);\n\n    //mutil call sync wait result\n    $data = array(\n        \"guid\" =\u003e md5(mt_rand(1000000, 9999999) . mt_rand(1000000, 9999999) . microtime(true)),\n\n        \"api\" =\u003e array(\n            \"oak\" =\u003e array(\"name\" =\u003e \"/module_d/oakdf\", \"param\" =\u003e array(\"dsaf\" =\u003e \"32111321\")),\n            \"cd\" =\u003e array(\"name\" =\u003e \"/module_e/oakdfff\", \"param\" =\u003e array(\"codo\" =\u003e \"f11ds\")),\n        )\n    ,\n    );\n\n    $data_string = \"params=\" . urlencode(json_encode($data));\n\n    $ch = curl_init('http://127.0.0.1:9566/api/multisync');\n    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\n    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);\n    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($ch, CURLOPT_HTTPHEADER, array(\n            'Connection: Keep-Alive',\n            'Keep-Alive: 300',\n        )\n    );\n\n    $result = curl_exec($ch);\n    var_dump(json_decode($result, true));\n\n\n    //multi call no wait result\n    $data = array(\n        \"guid\" =\u003e md5(mt_rand(1000000, 9999999) . mt_rand(1000000, 9999999) . microtime(true)),\n\n        \"api\" =\u003e array(\n            \"oak\" =\u003e array(\"name\" =\u003e \"/module_d/oakdf\", \"param\" =\u003e array(\"dsaf\" =\u003e \"32111321\")),\n            \"cd\" =\u003e array(\"name\" =\u003e \"/module_e/oakdfff\", \"param\" =\u003e array(\"codo\" =\u003e \"f11ds\")),\n        )\n    ,\n    );\n\n    $data_string = \"params=\" . urlencode(json_encode($data));\n\n    $ch = curl_init('http://127.0.0.1:9566/api/multinoresult');\n    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, \"POST\");\n    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);\n    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n    curl_setopt($ch, CURLOPT_HTTPHEADER, array(\n            'Connection: Keep-Alive',\n            'Keep-Alive: 300',\n        )\n    );\n\n    $result = curl_exec($ch);\n    var_dump(json_decode($result, true));\n\n\n    $time = bcsub(microtime(true), $time, 5);\n    if ($time \u003e $maxrequest) {\n        $maxrequest = $time;\n    }\n    echo $i . \" cost:\" . $time . PHP_EOL;\n    //var_dump($ret);\n}\necho \"max:\" . $maxrequest . PHP_EOL;\n\n```\n\n### 服务端(Server)\n```PHP\n\nclass Server extends DoraRPCServer {\n\n    //all of this config for optimize performance\n    //以下配置为优化服务性能用，请实际压测调试\n    protected  $externalConfig = array(\n\n        //to improve the accept performance ,suggest the number of cpu X 2\n        //如果想提高请求接收能力，更改这个，推荐cpu个数x2\n        'reactor_num' =\u003e 32,\n\n        //packet decode process,change by condition\n        //包处理进程，根据情况调整数量\n        'worker_num' =\u003e 40,\n\n        //the number of task logical process progcessor run you business code\n        //实际业务处理进程，根据需要进行调整\n        'task_worker_num' =\u003e 20,\n    );\n\n    function initServer($server){\n        //the callback of the server init 附加服务初始化\n        //such as swoole atomic table or buffer 可以放置swoole的计数器，table等\n    }\n    function doWork($param){\n        //process you logical 业务实际处理代码仍这里\n        //return the result 使用return返回处理结果\n        return array(\"hehe\"=\u003e\"ohyes\");\n    }\n\n    function initTask($server, $worker_id){\n        //require_once() 你要加载的处理方法函数等 what's you want load (such as framework init)\n    }\n}\n\n$res = new Server();\n```\n###客户端监控器(Client Local Monitor)\n```PHP\ninclude \"src/Doraconst.php\";\ninclude \"src/Packet.php\";\ninclude \"src/Monitor.php\";\n\n\n//redis for service discovery register\n//when you on product env please prepare more redis to registe service for high available\n$redisconfig = array(\n    array(//first reporter\n        \"ip\" =\u003e \"127.0.0.1\",\n        \"port\" =\u003e \"6379\",\n    ),\n    array(//next reporter\n        \"ip\" =\u003e \"127.0.0.1\",\n        \"port\" =\u003e \"6379\",\n    ),\n);\n\n//ok start server\n$res = new \\DoraRPC\\Monitor(\"0.0.0.0\", 9569, $redisconfig, \"./client.conf.php\");\n//this server will auto get the node server list from redis and general the client config on special path\n```\n\n### 以上代码测试方法\ninclude以上两个文件，使用命令行启动即可（客户端支持在apache nginx fpm内执行，服务端只支持命令行启动）\n\u003e * php democlient.php\n\u003e * php demoserver.php\n\n## 错误码及含义(Error Code)\n\u003e * 0 Success work\n\u003e * 100001 async task success\n\u003e * 100002 unknow task type\n\u003e * 100003 you must fill the api parameter on you request\n\u003e * 100005 Signed check error\n\u003e * 100006 Pack decode type wrong\n\u003e * 100007 socket error the recive packet length is wrong\n\u003e * 100008 the return guid wrong may be the socket trasfer wrong data\n\u003e * 100009 the recive wrong or timeout\n\u003e * 100010 there is no server can connect\n\u003e * 100011 unknow cmd of controlle\n\u003e * 100012 Get Async Result Fail: Client Closed.\n\u003e * 100099 unknow communicate mode have been set\n\u003e * 100100 guid wront please retry..\n\n## 性能(Performance)\n\u003e * Mac I7 Intel 2.2Mhz \n\u003e * Vagrant with Vm 1 Core\n\u003e * 1G Memory\n\u003e * with example code (loop forever)\n\n### 测试结果Result\n\u003e * Network Cost:0.002~0.004/sec Per Request\n\u003e * CPU 10~25%\n以上还有很大优化空间\nThere is still a lot of optimization space\n\n### Optimize performance性能优化\n```\nvim demoserver.php\nto see $externalConfig var\nand swoole offcial document\n\n如果想优化性能请参考以上文件的$externalConfig配置\n```\n\n### Server Config Optimize\n\u003e * http://wiki.swoole.com/wiki/page/p-server/sysctl.html\n\n### License授权\nApache\n\n### QQ Group\nQQ Group:346840633\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F137-rick%2FDora-RPC","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F137-rick%2FDora-RPC","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F137-rick%2FDora-RPC/lists"}