1"use strict";(globalThis.webpackChunkatsf4g_co_docs||=[]).push([[820],{4340(e,s,r){r.r(s),r.d(s,{assets:()=>o,contentTitle:()=>c,default:()=>p,frontMatter:()=>d,metadata:()=>n,toc:()=>a});const n=JSON.parse('{"id":"development/add-service","title":"Adding a Service","description":"Use echosvr as the minimal template (just a single app/echosvr_main.cpp); refer to lobbysvr for a","source":"@site/i18n/en/docusaurus-plugin-content-docs/current/development/add-service.md","sourceDirName":"development","slug":"/development/add-service","permalink":"/en/development/add-service","draft":false,"unlisted":false,"editUrl":"https://github.com/atframework/atsf4g-co/edit/main/doc/docs/development/add-service.md","tags":[],"version":"current","frontMatter":{"title":"Adding a Service"},"sidebar":"docs","previous":{"title":"Stress-Test Robot (robot)","permalink":"/en/services/robot"},"next":{"title":"Adding RPC and Task Actions","permalink":"/en/development/add-rpc-task"}}');var t=r(6070),i=r(3797);const d={title:"Adding a Service"},c="Adding a Service",o={},a=[{value:"Steps",id:"steps",level:2},{value:"Notes",id:"notes",level:2}];function l(e){const s={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"adding-a-service",children:"Adding a Service"})}),"\n",(0,t.jsxs)(s.p,{children:["Use ",(0,t.jsx)(s.code,{children:"echosvr"})," as the minimal template (just a single ",(0,t.jsx)(s.code,{children:"app/echosvr_main.cpp"}),"); refer to ",(0,t.jsx)(s.code,{children:"lobbysvr"})," for a\r\nstandard service."]}),"\n",(0,t.jsx)(s.h2,{id:"steps",children:"Steps"}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.strong,{children:"Define the protocol"}),": add services and messages in ",(0,t.jsx)(s.code,{children:"src/server_frame/protocol/"})," (or the component's\r\nown ",(0,t.jsx)(s.code,{children:"protocol/"}),"); annotate ",(0,t.jsx)(s.code,{children:"module_name"})," / ",(0,t.jsx)(s.code,{children:"api_name"})," / ",(0,t.jsx)(s.code,{children:"allow_no_wait"})," with\r\n",(0,t.jsx)(s.code,{children:"atframework.service_options"})," / ",(0,t.jsx)(s.code,{children:"rpc_options"}),"."]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.strong,{children:"Declare generation rules"}),": in the service's ",(0,t.jsx)(s.code,{children:"CMakeLists.txt"}),", use ",(0,t.jsx)(s.code,{children:"generate_for_pb_add_ss_service"})," (SS RPC) /\r\n",(0,t.jsx)(s.code,{children:"generate_for_pb_add_cs_service"})," (CS RPC) (see ",(0,t.jsx)(s.code,{children:"src/tools/generate_for_pb_utility.cmake"}),") to declare: proto\r\nfiles + templates (",(0,t.jsx)(s.code,{children:"handle_ss_rpc"})," / ",(0,t.jsx)(s.code,{children:"task_action_ss_rpc"})," / ",(0,t.jsx)(s.code,{children:"rpc_call_api_for_ss"})," / CS variants) + output paths."]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.strong,{children:"Write main"}),": follow ",(0,t.jsx)(s.code,{children:"src/lobbysvr/service/app/lobbysvr_main.cpp"}),":"]}),"\n"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:"int main(int argc, char *argv[]) {\r\n atfw::atapp::app app;\r\n // logic_config injects this service's configuration loading callbacks\r\n project::logic_server_setup_common(app);\r\n // Register the generated RPC handlers\r\n register_handles_for_<yourservice>();\r\n // Mount dispatchers and business modules\r\n app.add_module(atfw::cs_msg_dispatcher::me());\r\n app.add_module(atfw::ss_msg_dispatcher::me());\r\n app.add_module(atfw::db_msg_dispatcher::me());\r\n app.add_module(<business module>);\r\n return app.run(uv_default_loop(), argc, argv, nullptr);\r\n}\n"})}),"\n",(0,t.jsxs)(s.ol,{start:"4",children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.strong,{children:"Fill in task actions"}),": the generator produces ",(0,t.jsx)(s.code,{children:"logic/action/task_action_*"})," skeletons; write business\r\nlogic in ",(0,t.jsx)(s.code,{children:"operator()"}),"."]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.strong,{children:"Add to the build"}),": ",(0,t.jsx)(s.code,{children:"add_subdirectory(<name>svr)"})," in ",(0,t.jsx)(s.code,{children:"src/CMakeLists.txt"}),"."]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.strong,{children:"Deployment"}),": add the service chart under ",(0,t.jsx)(s.code,{children:"install/cloud-native/charts/"})," (you can copy an existing\r\nservice), and supplement parameters in each profile under ",(0,t.jsx)(s.code,{children:"values/"}),"; for local runs, supplement the\r\n",(0,t.jsx)(s.code,{children:"publish/tools/script/config.conf"})," template."]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"notes",children:"Notes"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["Generated artifacts (",(0,t.jsx)(s.code,{children:"*.atfw.gen.*"}),") must not be edited manually; regeneration is triggered by\r\nproto/template changes."]}),"\n",(0,t.jsxs)(s.li,{children:["Module assembly order follows the conventions of ",(0,t.jsx)(s.code,{children:"logic_server_setup_common"}),";
1 mount custom modules after\r\nthe dispatcher when they depend on it."]}),"\n",(0,t.jsx)(s.li,{children:"New services are included in all builds by default, with no separate switch."}),"\n"]})]})}function p(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.