/** * The main function sets up the TP reactor. The code is basically taken from * the solution to exercise 4c of the ACE course. */ int ACE_TMAIN(int, ACE_TCHAR **) { // create a reactor from a TP reactor ACE_TP_Reactor tpReactor; ACE_Reactor reactor(&tpReactor); // create a new accept handler using that reactor AcceptHandler *acceptHandler = 0; ACE_NEW_NORETURN (acceptHandler, AcceptHandler(&reactor)); if (acceptHandler == 0) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to allocate ") ACE_TEXT ("accept handler. (errno = %i: %m)\n"), ACE_ERRNO_GET), -1); // open the accept handler if (acceptHandler->open() == -1) { delete acceptHandler; ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to open accept ") ACE_TEXT ("handler. Exiting.\n")), -1); } // spawn some threads which run the reactor event loop(s) ACE_Thread_Manager::instance()->spawn_n(9, threadFunc, &reactor); // let the thread manager wait for all threads ACE_Thread_Manager::instance()->wait(); ACE_DEBUG((LM_DEBUG, ACE_TEXT("Bye. Bye.\n"))); return 0; }
Server::Server(tcp::endpoint& endpoint) : acceptor(io_service, endpoint), socket(io_service) { // Create a simple greeting chat message that all clients get. std::string message("Hello from server\n"); this->greeting_msg.SetBodyLength(message.size()); memcpy(this->greeting_msg.GetBodyPTR(), message.c_str(), this->greeting_msg.GetBodyLength()); this->greeting_msg.encode_header(); AcceptHandler(); }
void Server::AcceptHandler() { acceptor.async_accept(socket, [this] (std::error_code error) { if (!error) { asio::write(socket, asio::buffer(greeting_msg.GetDataPTR(), greeting_msg.length())); std::shared_ptr<ClientConnection> client = std::make_shared<ClientConnection>(std::move(socket), this); // self_protopack does contain a renderable component static FilePath others_protopack = FilePath::GetAssetPath("protopacks/others.proto"); proto::Entity other_entity; LoadProtoPack(other_entity, others_protopack); client->SetID(++base_id); client->DoJoin(); static ServerMessage connecting_client_entity_msg; other_entity.set_id(client->GetID()); connecting_client_entity_msg.SetBodyLength(other_entity.ByteSize()); other_entity.SerializeToArray(connecting_client_entity_msg.GetBodyPTR(), connecting_client_entity_msg.GetBodyLength()); connecting_client_entity_msg.SetMessageType(ENTITY_CREATE); connecting_client_entity_msg.encode_header(); static ServerMessage other_client_entity_msg; for (auto other_client : clients) { other_entity.set_id(other_client->GetID()); other_client_entity_msg.SetBodyLength(other_entity.ByteSize()); other_entity.SerializeToArray(other_client_entity_msg.GetBodyPTR(), other_client_entity_msg.GetBodyLength()); other_client_entity_msg.SetMessageType(ENTITY_CREATE); other_client_entity_msg.encode_header(); client->QueueWrite(other_client_entity_msg); other_client->QueueWrite(connecting_client_entity_msg); } LockClientList(); clients.insert(client); UnlockClientList(); { std::lock_guard<std::mutex> lock(recent_msgs_mutex); for (auto msg : this->recent_msgs) { client->QueueWrite(msg); } } client->StartRead(); } std::this_thread::sleep_for(std::chrono::milliseconds(1)); AcceptHandler(); }); }