| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- /* ASIO chat server client example
- This example code is in the Public Domain (or CC0 licensed, at your option.)
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
- */
- #include "protocol_examples_common.h"
- #include "esp_log.h"
- #include "esp_event.h"
- #include "nvs_flash.h"
- #include "server.hpp"
- #include "client.hpp"
- #include <thread>
- #include <pthread.h>
- using asio::ip::tcp;
- static const char *TAG = "asio-chat";
- // This variable is necessary for `python test` execution, it provides synchronisation between server/client(as server should be started before client)
- std::mutex server_ready;
- #ifdef CONFIG_EXAMPLE_CHAT_CLIENT
- static void get_string(char *line, size_t size)
- {
- int count = 0;
- while (count < size) {
- int c = fgetc(stdin);
- if (c == '\n') {
- line[count] = '\0';
- break;
- } else if (c > 0 && c < 127) {
- line[count] = c;
- ++count;
- }
- vTaskDelay(10 / portTICK_PERIOD_MS);
- }
- }
- void start_client(void)
- {
- const std::string port(CONFIG_EXAMPLE_CHAT_CLIENT_CONNECT_PORT);
- const std::string name(CONFIG_EXAMPLE_CHAT_CLIENT_CONNECT_ADDRESS);
- asio::io_context io_context;
- char line[128];
- tcp::resolver resolver(io_context);
- auto endpoints = resolver.resolve(name, port);
- chat_client c(io_context, endpoints);
- #ifdef CONFIG_EXAMPLE_CHAT_SERVER
- std::lock_guard<std::mutex> guard(server_ready);
- #endif
- std::thread t([&io_context]() { try {
- io_context.run();
- } catch (const std::exception &e) {
- ESP_LOGE(TAG, "Exception occured during client thread execution %s", e.what());
- }
- catch (...) {
- ESP_LOGE(TAG, "Unknown exception");
- }});
- do {
- ESP_LOGI(TAG, "CLIENT: Waiting for input");
- get_string(line, sizeof(line));
- chat_message msg;
- msg.body_length(std::strlen(line));
- std::memcpy(msg.body(), line, msg.body_length());
- msg.encode_header();
- c.write(msg);
- sleep(1);
- } while (strcmp(line, "exit") != 0);
- c.close();
- t.join();
- }
- #endif // CONFIG_EXAMPLE_CHAT_CLIENT
- extern "C" void app_main(void)
- {
- ESP_ERROR_CHECK(nvs_flash_init());
- esp_netif_init();
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
- * Read "Establishing Wi-Fi or Ethernet Connection" section in
- * examples/protocols/README.md for more information about this function.
- */
- ESP_ERROR_CHECK(example_connect());
- try {
- #ifdef CONFIG_EXAMPLE_CHAT_SERVER
- asio::io_context io_context;
- chat_server server(io_context, tcp::endpoint(tcp::v4(), std::atoi(CONFIG_EXAMPLE_CHAT_SERVER_BIND_PORT)));
- std::thread t = std::thread([&io_context]() { // Chat server starting here
- try {
- io_context.run();
- } catch (const std::exception &e) {
- ESP_LOGE(TAG, "Exception occured during server thread execution %s", e.what());
- }
- catch (...) {
- ESP_LOGE(TAG, "Unknown exception");
- }});;
- #endif
- #ifdef CONFIG_EXAMPLE_CHAT_CLIENT
- start_client();
- #endif
- #ifdef CONFIG_EXAMPLE_CHAT_SERVER
- t.join();
- #endif
- } catch (const std::exception &e) {
- ESP_LOGE(TAG, "Exception occured during run %s", e.what());
- } catch (...) {
- ESP_LOGE(TAG, "Unknown exception");
- }
- ESP_ERROR_CHECK(example_disconnect());
- }
|