Project: userver (App Definition and Development / Streaming & Messaging)
File: tcp_service.md

Make sure that you can compile and run core tests as described at @ref scripts/docs/en/userver/tutorial/build.md. Let's write a simple TCP server that accepts incoming connections, and as long as the client sends "hi" responds with greeting from configuration file. Derive from components::TcpAcceptorBase and override the `ProcessSocket` function to get the new sockets: @snippet samples/tcpservice/tcpservice.cpp TCP sample - component @warning `ProcessSocket` functions are invoked concurrently on the same instance of the class. Use @ref scripts/docs/en/userver/synchronization.md "synchronization primitives" or do not modify shared data in `ProcessSocket`. Our new "tcp-hello" component should support the options of the components::TcpAcceptorBase and the "greeting" option. To achieve that we would need the following implementation of the `GetStaticConfigSchema` function: @snippet samples/tcpservice/tcpservice.cpp TCP sample - GetStaticConfigSchema Now lets configure our component in the `components` section: @snippet samples/tcpservice/staticconfig.yaml TCP component It's time to deal with new sockets. The code is quite straightforward: @snippet samples/tcpservice/tcpservice.cpp TCP sample - ProcessSocket Finally, add the component to the `components::MinimalComponentList()`, and start the server with static configuration file passed from command line. @snippet samples/tcpservice/tcpservice.cpp TCP sample - main To build the sample, execute the following build steps at the userver root directory: ``` mkdir build_release cd build_release cmake -DCMAKEBUILDTYPE=Release .. make userver-samples-tcp_service ``` The sample could be started by running `make start-userver-samples-tcp_service`. The command would invoke @ref scripts/docs/en/userver/functional_testing.md "testsuite start target" that sets proper paths in the configuration files and starts the service. To start the service manually run `./samples/tcpservice/userver-samples-tcpservice -c </path/to/static_config.yaml>`. Now you can send a request to your server from another terminal: ``` bash $ nc localhost 8180 hi hello ``` @ref scripts/docs/en/userver/functional_testing.md "Functional tests" for the service could be implemented using the testsuite in the following way: @snippet samples/tcpservice/tests/testtcp.py Functional test Note that in this case testsuite requires some help to detect that the service is ready to accept requests. To do that, override the pytestuserver.plugins.service.servicenonhttphealth_checks : @snippet samples/tcpservice/tests/conftest.py servicenonhttphealth_checker See the full example at: @ref samples/tcpservice/tcpservice.cpp @ref samples/tcpservice/staticconfig.yaml @ref samples/tcp_service/CMakeLists.txt @ref samples/tcp_service/tests/conftest.py @ref samples/tcpservice/tests/testtcp.py @htmlonly <div class="bottom-nav"> @endhtmlonly @ref scripts/docs/en/userver/tutorial/productionservice.md | @ref scripts/docs/en/userver/tutorial/tcpfull.md @htmlonly </div> @endhtmlonly @example samples/tcpservice/tcpservice.cpp @example samples/tcpservice/staticconfig.yaml @example samples/tcp_service/CMakeLists.txt @example samples/tcp_service/tests/conftest.py @example samples/tcpservice/tests/testtcp.py