mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
120 lines
4.0 KiB
C++
120 lines
4.0 KiB
C++
|
/* 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());
|
||
|
}
|