I am having a C++ server listening to PHP clients. The client code is the following:
<?php
function connect_($message)
{
$port = 13;
$address = "127.0.0.1";//talk to localhost
$response = "";
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket !== false)
{
$result = socket_connect($socket, $address, $port);
if ($result !== false)
{
socket_write($socket, $message, strlen($message));//send the message
while ($out = socket_read($socket, 2048)) $response .= $out;//get the response
socket_close($socket);//exit
}
}
return $response;
}
echo connect_('hi');
?>
This code is called every time a user visits the site.
The c++ server's code is the following (from here: https://stackoverflow.com/a/26577384/4143251):
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using boost::asio::ip::tcp;
char complex_function()
{
//sleep to simulate a time consuming function
boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
return 'C';//return the result of the work
}
class session : public std::enable_shared_from_this<session> {
public:
session(tcp::socket socket) : socket_(std::move(socket)) {}
void start() { do_read(); }
~session()
{
std::cout << "USER GONE\n";
}
private:
void do_read() {
auto self(shared_from_this());
socket_.async_read_some(boost::asio::buffer(data_, max_length),
[this, self](boost::system::error_code ec, std::size_t length) {
if (!ec) {
data_[0] = complex_function();
length = 1;
do_write(length);//good, now go write the response
}
});
}
void do_write(std::size_t length) {
auto self(shared_from_this());
boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
[this, self](boost::system::error_code ec, std::size_t /*length*/) {
if (!ec) {
//do, nothing here
}
});
}
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server {
public:
server(boost::asio::io_service &io_service, short port)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), socket_(io_service) {
do_accept();
}
private:
void do_accept() {
acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
if (!ec) {
std::cout << "NEW USER\n";
std::make_shared<session>(std::move(socket_))->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
tcp::socket socket_;
};
int main() {
try {
std::string port = "13";
boost::asio::io_service io_service;
server s(io_service, std::atoi(port.c_str()));
boost::thread_group tg;
for (int i=0; i < 10; ++i)//handle up to 10 clients at the same time
tg.create_thread([&]{ io_service.run(); });
tg.join_all();
}
catch (std::exception &e) {
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
Now, if I open in multiple tabs the PHP webpage and try to connect to the server from 5 clients at the same time, the server process the requests with 10 seconds delay.
The question is: how to make the above code process multiple requests at the same time in parallel?