|
| 1 | +/* |
| 2 | + * .============. |
| 3 | + * // M A K E / \ |
| 4 | + * // C++ DEV / \ |
| 5 | + * // E A S Y / \/ \ |
| 6 | + * ++ ----------. \/\ . |
| 7 | + * \\ \ \ /\ / |
| 8 | + * \\ \ \ / |
| 9 | + * \\ \ \ / |
| 10 | + * -============' |
| 11 | + * |
| 12 | + * Copyright (c) 2023 Hevake and contributors, all rights reserved. |
| 13 | + * |
| 14 | + * This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox) |
| 15 | + * Use of this source code is governed by MIT license that can be found |
| 16 | + * in the LICENSE file in the root of the source tree. All contributing |
| 17 | + * project authors may be found in the CONTRIBUTORS.md file in the root |
| 18 | + * of the source tree. |
| 19 | + */ |
| 20 | + |
| 21 | +/** |
| 22 | + * 这是JsonRpc模块ping/pong示例中pong的一方 |
| 23 | + * |
| 24 | + * 它绑定Unix Domain Sock: /tmp/ping_pong.sock,等待被连接。 |
| 25 | + * 当收到ping请求后,将参数中的count提取出来作为结果直接回复。 |
| 26 | + */ |
| 27 | + |
| 28 | +#include <tbox/base/log.h> //! 打印日志 |
| 29 | +#include <tbox/base/log_output.h> //! LogOutput_Enable() |
| 30 | +#include <tbox/base/scope_exit.hpp> //! SetScopeExitAction() |
| 31 | +#include <tbox/base/json.hpp> //! 操作JSON对象用 |
| 32 | +#include <tbox/util/buffer.h> //! 对Buffer进行操作 |
| 33 | +#include <tbox/util/json.h> //! util::json::GetField() |
| 34 | +#include <tbox/event/loop.h> //! 事件循环 |
| 35 | +#include <tbox/event/signal_event.h> //! ctrl+c信号事件 |
| 36 | +#include <tbox/network/tcp_server.h> //! TcpServer |
| 37 | +#include <tbox/jsonrpc/protos/raw_stream_proto.h> //! jsonrpc::RawStreamProto |
| 38 | +#include <tbox/jsonrpc/str_id_rpc.h> //! jsonrpc::StrIdRpc |
| 39 | + |
| 40 | +using namespace tbox; |
| 41 | + |
| 42 | +int main(int argc, char **argv) |
| 43 | +{ |
| 44 | + LogOutput_Enable(); |
| 45 | + |
| 46 | + LogInfo("enter"); |
| 47 | + |
| 48 | + auto loop = event::Loop::New(); |
| 49 | + auto sig_event = loop->newSignalEvent(); |
| 50 | + |
| 51 | + //! 设置退出时,要释放loop与sig_event |
| 52 | + SetScopeExitAction( |
| 53 | + [=] { |
| 54 | + delete sig_event; |
| 55 | + delete loop; |
| 56 | + } |
| 57 | + ); |
| 58 | + |
| 59 | + network::TcpServer tcp_server(loop); |
| 60 | + jsonrpc::RawStreamProto proto; |
| 61 | + jsonrpc::StrIdRpc rpc(loop); |
| 62 | + |
| 63 | + rpc.initialize(&proto, 3); |
| 64 | + std::string srv_addr = "/tmp/ping_pong.sock"; |
| 65 | + |
| 66 | + network::TcpServer::ConnToken curr_client_token; //! 当前的客户端 |
| 67 | + |
| 68 | + tcp_server.initialize(network::SockAddr::FromString(srv_addr), 2); |
| 69 | + //! 设置接收到连接后的动作:保存curr_client_token |
| 70 | + tcp_server.setConnectedCallback([&] (network::TcpServer::ConnToken client_token) { |
| 71 | + tcp_server.disconnect(curr_client_token); |
| 72 | + curr_client_token = client_token; |
| 73 | + }); |
| 74 | + //! 设置连接断开后的动作:清除curr_client_token |
| 75 | + tcp_server.setDisconnectedCallback([&] (network::TcpServer::ConnToken client_token) { |
| 76 | + curr_client_token.reset(); |
| 77 | + }); |
| 78 | + //! 设置接收到数据后的处理 |
| 79 | + tcp_server.setReceiveCallback([&] (network::TcpServer::ConnToken client_token, network::Buffer &buff) { |
| 80 | + while (buff.readableSize() > 0) { |
| 81 | + //! 将buff中的数据交给proto进行解析 |
| 82 | + auto ret = proto.onRecvData(buff.readableBegin(), buff.readableSize()); |
| 83 | + if (ret > 0) { |
| 84 | + buff.hasRead(ret); |
| 85 | + } else if (ret < 0) { //! 有错误 |
| 86 | + tcp_server.disconnect(curr_client_token); |
| 87 | + curr_client_token.reset(); |
| 88 | + } else |
| 89 | + break; |
| 90 | + } |
| 91 | + }, 0); |
| 92 | + |
| 93 | + //! 设置proto发送数据的方法 |
| 94 | + proto.setSendCallback([&] (const void* data_ptr, size_t data_size) { |
| 95 | + tcp_server.send(curr_client_token, data_ptr, data_size); |
| 96 | + }); |
| 97 | + |
| 98 | + tcp_server.start(); //! 启动tcp服务 |
| 99 | + |
| 100 | + //! 注册ping的服务处理函数 |
| 101 | + rpc.addService("ping", [&] (const std::string &id, const Json &js_params, int &, Json &) { |
| 102 | + int ping_count = 0; |
| 103 | + util::json::GetField(js_params, "count", ping_count); |
| 104 | + LogDbg("id: %s, got ping_count: %d", id.c_str(), ping_count); |
| 105 | + rpc.notify("pong", js_params); |
| 106 | + return false; //! 表示不回复 |
| 107 | + }); |
| 108 | + |
| 109 | + //! 设置程序安全退出条件 |
| 110 | + sig_event->initialize(SIGINT, event::Event::Mode::kPersist); |
| 111 | + sig_event->enable(); |
| 112 | + |
| 113 | + //! 设置程序退出动作 |
| 114 | + sig_event->setCallback( |
| 115 | + [&] (int) { |
| 116 | + tcp_server.stop(); |
| 117 | + loop->exitLoop(); |
| 118 | + } |
| 119 | + ); |
| 120 | + |
| 121 | + LogInfo("start"); |
| 122 | + loop->runLoop(); |
| 123 | + LogInfo("stop"); |
| 124 | + |
| 125 | + rpc.cleanup(); |
| 126 | + tcp_server.cleanup(); |
| 127 | + return 0; |
| 128 | +} |
0 commit comments