void consume_command() // runs in its own thread { try { while (true) { ClientCommand command {queue.get()}; // will block here unless there are still command objects in the queue shared_ptr<Socket> client {command.get_client()}; shared_ptr<Player> player {command.get_player()}; try { m_g->handleCommand(player, command.get_cmd()); // TODO handle command here //*client << player->get_name() << ", you wrote: '" << command.get_cmd() << "', but I'll ignore that for now.\r\n" << machiavelli::prompt; } catch (const exception& ex) { cerr << "*** exception in consumer thread for player " << player->get_name() << ": " << ex.what() << '\n'; if (client->is_open()) { client->write("Sorry, something went wrong during handling of your request.\r\n"); } } catch (...) { cerr << "*** exception in consumer thread for player " << player->get_name() << '\n'; if (client->is_open()) { client->write("Sorry, something went wrong during handling of your request.\r\n"); } } } } catch (...) { cerr << "consume_command crashed\n"; } }
void ServerController::consume_command() { is_consuming = true; while (is_consuming) { ClientCommand command; client_queue.get(command); std::shared_ptr<Socket> client = command.get_client(); if (client) { game_controller->consume_command(command, client); } else std::cerr << "Client has disappeared" << "\n"; } }
int ServerSP::Run() { cout << "\nCreating server for single player...\n"; sockaddr_in addr; char buf[MAX_MSG_LENGTH]; int bytes_read; bool connected = false; addr.sin_family = AF_INET; inet_aton("127.0.0.1", &addr.sin_addr); PortsPool* ports = PortsPool::GetInstance(1); int CheckedPorts[1000]; int i = 0; while (!connected) { _port = htons(ports -> GetPort()); if (_port < 0) { for (int j = 0; j < i; ++j) ports -> RetPort(CheckedPorts[j]); throw new ENoPortsAvailable(); } _listener = socket(AF_INET, SOCK_STREAM, 0); if (_listener < 0) { for (int j = 0; j < i; ++j) ports -> RetPort(CheckedPorts[j]); throw new EConnectionFailed(); } addr.sin_family = AF_INET; addr.sin_port = _port; inet_aton("127.0.0.1", &addr.sin_addr); if (bind(_listener, (sockaddr*)&addr, sizeof(addr)) < 0) { CheckedPorts[i++] = _port; close (_listener); } else { connected = true; } } for (int j = 0; j < i; ++j) ports -> RetPort(CheckedPorts[j]); cout << "Connection port: " << this -> _port << '\n'; listen(_listener, 1); cout << "Waiting for client...\n"; _sockdesc1 = accept(_listener, NULL, NULL); if (_sockdesc1 < 0) { cout << "Error first connection"; throw new EConnectionFailedFirst(); } ServerCommand scmd1 = ServerCommand(); scmd1.SetCommand(SConnectPermissionFirst); char* scmdb1 = scmd1.ToString(); send (_sockdesc1,scmdb1, MAX_MSG_LENGTH, 0); delete[] scmdb1; cout << "Connected.\n"; ServerCommand scmd3 = ServerCommand(); scmd3.SetCommand(SGameBegin); char* scmdb3 = scmd3.ToString(); send (_sockdesc1,scmdb3, MAX_MSG_LENGTH, 0); delete[] scmdb3; fcntl(_listener, F_SETFL, O_NONBLOCK); _game -> SwitchState(); while(true) { fd_set readset; FD_ZERO(&readset); FD_SET(_listener, &readset); FD_SET(_sockdesc1, &readset); timeval timeout; timeout.tv_sec = 10; timeout.tv_usec = 0; if (select(this -> _sockdesc1+1, &readset, NULL, NULL, &timeout ) <= 0) { continue; } if ( FD_ISSET(_sockdesc1, &readset)) { bytes_read = recv(_sockdesc1, buf, MAX_MSG_LENGTH, 0); if (bytes_read <= 0) { cout << "Receiving from 1 error\n"; throw new EConnectionFailedFirst(); } cout << "Received from client: " << bytes_read << " bytes\n"; ClientCommand ccmd = ClientCommand(buf); ServerCommand scmd = _game -> GetAnswer(ccmd); char* scmdbytes = scmd.ToString(); send(_sockdesc1, scmdbytes, MAX_MSG_LENGTH, 0); if (scmd.GetWinner()!=0) { cout << "Winner: " << scmd.GetWinner() << '\n'; scmd.SetCommand(SGameEnd); scmdbytes = scmd.ToString(); send(_sockdesc1, scmdbytes, MAX_MSG_LENGTH, 0); close (_listener); close (_sockdesc1); ports -> RetPort(this -> _port); break; } if (scmd.GetCmd() == SInvalideAction) continue; sleep(1); ServerCommand scmd2; switch (ccmd.GetPlayer()) { case First: scmd2 = this -> _game -> GetAnswerMove(Second); break; case Second: scmd2 = this -> _game -> GetAnswerMove(First); break; } scmdbytes = scmd2.ToString(); send(_sockdesc1, scmdbytes, MAX_MSG_LENGTH, 0); if (scmd.GetWinner()!=0) { cout << "Winner: " << scmd.GetWinner() << '\n'; scmd.SetCommand(SGameEnd); scmdbytes = scmd.ToString(); send(_sockdesc1, scmdbytes, MAX_MSG_LENGTH, 0); close (_sockdesc1); close (_listener); ports -> RetPort(this -> _port); break; } delete[] scmdbytes; } } }
void * ServerProxy::run() { while (! isCanceled() ) { std::stringstream msg; unsigned int msgLen; std::string commandName; std::string commandXml; std::cerr<< std::endl << "################################"<< std::endl<<"ServerProxy leyendo encabezado " << std::endl; // deshardcodear este 32 //EL CLIENTE ESPERA ACA!!!! msg << getSocket()->full_read(32); msg >> msgLen; msg >> commandName; std::cerr << "longitud " << msgLen << " nombre " << commandName << std::endl; commandXml = getSocket()->full_read(msgLen); //std::cerr << "serializacion: " << commandXml << std::endl; //aca entran los comandos que modifican el modelo en el cliente if (commandHydrator.isClientCommand(commandName)) { std::cerr << "Invocando ClientCommandHydrator::createCommand(" << commandName << ", " << commandXml << ");" << std::endl; ClientCommand* command = commandHydrator.createCommand(commandName, commandXml); std::cerr << "Ejecutando comando..." << std::endl; if (command != NULL) { if (command->isValid()) { command->execute(); } } std::cerr << "Se pudo ejecutar comando..." << std::endl; notifyCommandExecuted(*command); std::cerr << "Se notifico comando..." << std::endl; std::cerr << "salio de mostarr cambios" << std::endl; } else{ Command* command = messageHydrator.createCommand(commandName, commandXml); if ( command == NULL ) std::cerr<<"el comando devuelto por messageHydrator es NULL....."<<std::endl; else std::cerr << "Se pudo crear comando con messageHydrator" << std::endl; std::cerr << "Se esta por notificar comando" << std::endl; notifyCommandExecuted(*command); std::cerr << "Se notifico comando" << std::endl; if ( command->getName() == "mapList" ) dispatcherMapList.emit(); if ( command->getName() == "readyToPlay" ) dispatcherReadyToPlay.emit(); if ( command->getName() == "noRoom" ){ dispatcherNoRoom.emit(); // doy tiempo a que el emit del dispatcher informe antes de matar thread. sleep(3); //cancelo thread. this->cancel(); this->join(); this->kill(); } //si llego un YouAre y NO es para el 1er jugador if ( command->getName() == "youAre" && command->getTo() > 1 ){ std::cerr << "Verificando si comando es un YouAre....y lo es" << std::endl; dispatcherYouAre.emit(); } } } return 0; }