81 lines
2.3 KiB
C++
81 lines
2.3 KiB
C++
#include <boost/beast/core.hpp>
|
|
#include <boost/beast/websocket.hpp>
|
|
#include <boost/asio/ip/tcp.hpp>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <mutex>
|
|
|
|
namespace beast = boost::beast;
|
|
namespace http = beast::http;
|
|
namespace websocket = beast::websocket;
|
|
namespace net = boost::asio;
|
|
using tcp = net::ip::tcp;
|
|
|
|
class Session : public std::enable_shared_from_this<Session> {
|
|
websocket::stream<beast::tcp_stream> ws_;
|
|
beast::flat_buffer buffer_;
|
|
int id_;
|
|
|
|
public:
|
|
explicit Session(tcp::socket&& socket, int id)
|
|
: ws_(std::move(socket)), id_(id) {
|
|
}
|
|
|
|
void run() {
|
|
ws_.async_accept([self = shared_from_this()](beast::error_code ec) {
|
|
if (ec) return;
|
|
std::cout << "Client " << self->id_ << " connected\n";
|
|
// Ñðàçó îòïðàâëÿåì ID êëèåíòó
|
|
self->send_message("ID:" + std::to_string(self->id_));
|
|
self->do_read();
|
|
});
|
|
}
|
|
|
|
private:
|
|
void do_read() {
|
|
ws_.async_read(buffer_, [self = shared_from_this()](beast::error_code ec, std::size_t) {
|
|
if (ec) return;
|
|
std::string msg = beast::buffers_to_string(self->buffer_.data());
|
|
|
|
if (msg == "PING") {
|
|
self->send_message("PONG");
|
|
}
|
|
|
|
self->buffer_.consume(self->buffer_.size());
|
|
self->do_read();
|
|
});
|
|
}
|
|
|
|
void send_message(std::string msg) {
|
|
auto ss = std::make_shared<std::string>(std::move(msg));
|
|
ws_.async_write(net::buffer(*ss), [ss](beast::error_code, std::size_t) {});
|
|
}
|
|
};
|
|
|
|
int main() {
|
|
try {
|
|
net::io_context ioc;
|
|
tcp::acceptor acceptor{ ioc, {tcp::v4(), 8080} };
|
|
int next_id = 1000;
|
|
|
|
std::cout << "Server started on port 8080...\n";
|
|
|
|
auto do_accept = [&](auto& self_fn) -> void {
|
|
acceptor.async_accept([&, self_fn](beast::error_code ec, tcp::socket socket) {
|
|
if (!ec) {
|
|
std::make_shared<Session>(std::move(socket), next_id++)->run();
|
|
}
|
|
self_fn(self_fn);
|
|
});
|
|
};
|
|
|
|
do_accept(do_accept);
|
|
ioc.run();
|
|
}
|
|
catch (std::exception const& e) {
|
|
std::cerr << "Error: " << e.what() << std::endl;
|
|
}
|
|
return 0;
|
|
} |