コード例 #1
0
bool PerformOp(Connection &con, string client, string file, vector<string> slaves) {
  if (slaves.empty()) {
    return false;
  }
  // Send message to master slave(first) to prepare for client operation
  Message slave_prep(kSlavePrepareOp, SAFE_MESS);
  slave_prep.SetContent(SlaveOp{file, client, "", slaves});
  if (!con.SendMessage(slave_prep, slaves.front())) {
    cout << "Failed to prepare slaves for operation." << endl;
    return false;
  }

  // Wait slave to confirm operation and to inform the handler
  bool confirmed = false;
  string op_handler;
  Message tmp(0,0);
  if (con.GetMessage(kSlaveConfirmOp, kCreateTimeout, tmp)) {
    SlaveOp cop;
    tmp.GetContent(cop);
    confirmed = cop.client == client && cop.file_name == file;
    op_handler = tmp.sender();
  }

  // Slaves are not responding to prepare op
  if (!confirmed) {
    cout << "Storage slaves did not respond." << endl;
    return false;
  }

  Message client_prep(kClientPrepareOp, SAFE_MESS);
  client_prep.SetContent(ClientOp{file, op_handler});
  if (!con.SendMessage(client_prep, client)) {
    cout << "Failed to prepare client for operation." << endl;
    return false;
  }

  // Wait slave to confirm operation and to inform the handler
  confirmed = false;
  if (con.GetMessage(kFileOpResult, kCreateTimeout, tmp)) {
    ResultFileOp result;
    tmp.GetContent(result);
    confirmed = result.ok;
  }

  // Slave did not confirm
  if (!confirmed) {
    cout << "Storage slaves did not confirm operation." << endl;
  }
  return confirmed;
}
コード例 #2
0
void DOTHeal::HandleGetLc(StringHash eventType, VariantMap& eventData)
{
	Node* sceneNode = (Node*)(eventData[GetLc::P_NODE].GetPtr());

	if (sceneNode == node_)
	{
		if (!targets_.Size())
		{
			return;
		}

		Connection* conn = (Connection*)(eventData[GetLc::P_CONNECTION].GetPtr());

		lc_->GetLagTime(conn);

		for (int x = 0; x < targets_.Size(); x++)
		{
			float timeRamp = targets_[x]->elapsedTime_ + lc_->lagTime_;

			lc_->msg_.Clear();
			lc_->msg_.WriteInt(lc_->clientID_);
			lc_->msg_.WriteString("DOTHeal");
			lc_->msg_.WriteInt(targets_[x]->clientID_);
			lc_->msg_.WriteFloat(timeRamp);
			conn->SendMessage(MSG_LCMSG, true, true, lc_->msg_);
		}
	}
}
コード例 #3
0
ファイル: Server.cpp プロジェクト: practicing01/DotsNetCrits
void Server::HandleClientConnect(StringHash eventType, VariantMap& eventData)
{
	//LOGERRORF("client connected to server");

	using namespace NetworkMessage;

	Connection* sender = static_cast<Connection*>(eventData[P_CONNECTION].GetPtr());

	ClientData* newClient = new ClientData(clientIDCount_, sender, false);

	//Synchronize client data.
	for (int x = 0; x < clientData_.Size(); x++)
	{
		//Send the new client an old clients data
		msg_.Clear();
		msg_.WriteInt(clientData_[x]->clientID_);
		msg_.WriteBool(false);
		sender->SendMessage(MSG_NEWCLIENT, true, true, msg_);

		//Send the old client the new clients data.
		msg_.Clear();
		msg_.WriteInt(clientIDCount_);
		msg_.WriteBool(false);
		clientData_[x]->connection_->SendMessage(MSG_NEWCLIENT, true, true, msg_);

	}

	//Send the new client its data.
	clientData_.Push(newClient);
	msg_.Clear();
	msg_.WriteInt(clientIDCount_);
	msg_.WriteBool(true);
	sender->SendMessage(MSG_NEWCLIENT, true, true, msg_);

	//Send the new client the gamemode to load.
	msg_.Clear();
	msg_.WriteString(gamemodeName_.CString());
	sender->SendMessage(MSG_LOADGAMEMODE, true, true, msg_);

	clientIDCount_++;
}
コード例 #4
0
bool HandleCreate(const Message &msg, Connection &con) {
  bool succeeded = false;
  CreateFileOp op;
  auto client = msg.sender();
  try {
    msg.GetContent(op);
    cout << msg.sender() << " requested createop with args: " << op.file_name
         << " and " << op.redundancy << endl;
    if (!gFileMap.LockFile(op.file_name)) {
      cout << "Failed to lock entry. File was locked in the meantime." << endl;
      goto finish;
    }
    // get slaves associated with the file
    vector<string> slaves = GetFileSlaves(op.file_name);
    if (!slaves.empty()) {
      cout << "Create request failed. File does exist." << endl;
    } else {
      gSlavesLock.lock();
      for (auto &entry : gSlaves) {
        slaves.push_back(entry.first);
        if (slaves.size() == op.redundancy) break;
      }
      gSlavesLock.unlock();
      if (slaves.size() == op.redundancy) {
        succeeded = PerformOp(con, client, op.file_name, slaves);
      }
    }
    if (succeeded) {
      // insert the file on slaves
      gSlavesLock.lock();
      for (auto & slave : gSlaves) {
        if (find(begin(slaves), end(slaves), slave.first) != end(slaves)) {
          slave.second.push_back(op.file_name);
        }
      }
      gSlavesLock.unlock();
      SortSlaves();
    }

  } catch (...) {
    cout << "Invalid create request from " << msg.sender() << endl;
  }
  gFileMap.UnlockFile(op.file_name);

finish:
  Message res_msg(kFileOpResult, SAFE_MESS);
  ResultFileOp res{op.file_name, succeeded};
  res_msg.SetContent(res);
  if (!con.SendMessage(res_msg, client)) {
    cout << "Failed to inform client of op result." << endl;
  }
  return succeeded;
}
コード例 #5
0
bool HandleRemove(const Message &msg, Connection &con) {
  bool succeeded = false;
  bool locked = false;
  RemoveFileOp op;
  auto client = msg.sender();
  vector<string> slaves;
  try {
    msg.GetContent(op);
    cout << msg.sender() << " requested removeop with arg: " << op.file_name
         << endl;
    if (!(locked = gFileMap.LockFile(op.file_name))) {
      cout << "Failed to lock entry. File was locked in the meantime." << endl;
      goto finish;
    }
    // get slaves associated with the file
    slaves = GetFileSlaves(op.file_name);
    if (slaves.empty()) {
      cout << "Remove request failed. File does not exist." << endl;
    } else {
      succeeded = PerformOp(con, client, op.file_name, slaves);
    }

    if (succeeded) {
      // erases the files from slaves
      gSlavesLock.lock();
      for (auto & slave : gSlaves) {
        if (find(begin(slaves), end(slaves), slave.first) != end(slaves)) {
          auto &files = slave.second;
          files.erase(remove(begin(files), end(files), op.file_name), end(files));
        }
      }
      gSlavesLock.unlock();
      SortSlaves();
    }
  } catch (...) {
    cout << "Invalid create request from " << msg.sender() << endl;
  }
  if (locked) {
    gFileMap.UnlockFile(op.file_name);
  }
finish:
  Message res_msg(kFileOpResult, SAFE_MESS);
  ResultFileOp res{op.file_name, succeeded};
  res_msg.SetContent(res);
  if (!con.SendMessage(res_msg, client)) {
    cout << "Failed to inform client of op result." << endl;
  }
  return succeeded;
}
コード例 #6
0
void Silence::HandleGetLc(StringHash eventType, VariantMap& eventData)
{
	Node* clientNode = (Node*)(eventData[GetLc::P_NODE].GetPtr());

	if (clientNode == node_)
	{
		Connection* conn = (Connection*)(eventData[GetLc::P_CONNECTION].GetPtr());

		msg_.Clear();
		msg_.WriteInt(clientID_);
		msg_.WriteString("Silence");
		msg_.WriteBool(silence_);
		conn->SendMessage(MSG_LCMSG, true, true, msg_);
	}
}
コード例 #7
0
ファイル: Chat.cpp プロジェクト: 3dicc/Urho3D
void Chat::HandleSend(StringHash eventType, VariantMap& eventData)
{
    String text = textEdit_->GetText();
    if (text.Empty())
        return; // Do not send an empty message
    
    Network* network = GetSubsystem<Network>();
    Connection* serverConnection = network->GetServerConnection();
    
    if (serverConnection)
    {
        // A VectorBuffer object is convenient for constructing a message to send
        VectorBuffer msg;
        msg.WriteString(text);
        // Send the chat message as in-order and reliable
        serverConnection->SendMessage(MSG_CHAT, true, true, msg);
        // Empty the text edit after sending
        textEdit_->SetText(String::EMPTY);
    }
}
コード例 #8
0
bool HandleRead(const Message &msg, Connection &con) {
  bool succeeded = false;
  bool locked = false;
  ReadFileOp op;
  auto client = msg.sender();
  vector<string> slaves;
  try {
    msg.GetContent(op);
    cout << msg.sender() << " requested readop with arg: " << op.file_name
         << endl;
    if (!(locked = gFileMap.LockFile(op.file_name))) {
      cout << "Failed to lock entry. File was locked in the meantime." << endl;
      goto finish;
    }
    // get slaves associated with the file
    slaves = GetFileSlaves(op.file_name);
    if (slaves.empty()) {
      cout << "Read request failed. File does not exist." << endl;
    } else {
      slaves.resize(1);
      succeeded = PerformOp(con, client, op.file_name, slaves);
    }
  } catch (...) {
    cout << "Invalid read request from " << msg.sender() << endl;
  }
  if (locked) {
    gFileMap.UnlockFile(op.file_name);
  }
finish:
  Message res_msg(kFileOpResult, SAFE_MESS);
  ResultFileOp res{op.file_name, succeeded};
  res_msg.SetContent(res);
  if (!con.SendMessage(res_msg, client)) {
    cout << "Failed to inform client of op result." << endl;
  }
  return succeeded;
}
void GameEconomicServerClientConsole::SendMessage(String Message)
{
    /// If sending message is empty
    if (Message.Empty())
    {
        return; // Do not send an empty message
    }

    /// Get connection
    Network* network = GetSubsystem<Network>();
    Connection* serverConnection = network->GetServerConnection();

    /// Send message only if serverconnection and connection is true
    if (serverConnection&&serverconnection)
    {
               // A VectorBuffer object is convenient for constructing a message to send
        VectorBuffer msg;
        msg.WriteString(Message);
        // Send the chat message as in-order and reliable
        serverConnection->SendMessage(NetMessageAdminClientSend, true, true, msg);
    }

    return;
}
コード例 #10
0
ファイル: ConnectionPool.cpp プロジェクト: ctz/rain
/** Accepts an outgoing message and sends it through the best
  * connection it currently has.  Note that this WILL NOT create a
  * connection if one does not exist (for direct messages).  Instead
  * it will convert the message to be a routable message and send it
  * on a random connection. 
  *
  * \param msg The RAIN::Message object to be sent
  */
void RAIN::ConnectionPool::DispatchMessage(RAIN::Message *msg)
{
	wxLogVerbose("ConnectionPool::DispatchMessage");
	if (msg->status != MSG_STATUS_OUTGOING)
		return;

	BENC_SAFE_CAST(msg->headers["Destination"], msgdest, String);
	BENC_SAFE_CAST(msg->headers["Event"], msgevent, String);

	wxLogVerbose("ConnectionPool::DispatchMessage with msg for %s - %s", msgdest->getString().c_str(),
		msgevent->getString().c_str());

	if (msgdest->getString().Cmp("Broadcast") == 0)
	{
		this->app->router->ImportBroadcast(msg);

		BEnc::Value *via = msg->headers["Via"];
		BEnc::Dictionary *myval = NULL;
		wxString myhash = globalCredentialManager->GetMyPeerID()->hash;

		wxArrayString alreadyto;

		// we flatten the via to a list of peers already sent-to
		std::vector<BEnc::Value *> children;
		children.push_back(via);

		while (children.size() > 0)
		{
			BENC_SAFE_CAST(children.at(0), v, Dictionary);
			children.erase(children.begin());

			// via is always a dict of dicts
			std::map<wxString, RAIN::BEnc::Value*, BEnc::Cmp>::iterator it = v->hash.begin();

			while (it != v->hash.end())
			{
				BENC_SAFE_CAST(it->second, h, Dictionary);

				alreadyto.Add(it->first);

				if (RAIN::SafeStringsEq(it->first, myhash))
				{
					myval = h;
				}

				if (h->hash.size() > 0)
				{
					children.push_back(h);
				}

				it++;
			}
		}

		if (myval == NULL)
		{
			/* this is an error, because it means we got a message
			 * without the sender modifying the message to indicate
			 * we were sent it */
			wxLogVerbose("Warning: Message received without our hash in Via");
			return;
		}

		std::vector <RAIN::Connection *> local_sendto;
		int i = 0, n = 0;

		wxLogVerbose("Rebroadcasting message already sent to %d peers", alreadyto.GetCount());

		// TODO: optimise this search
		/* now we search through our connected peers to determine if we can
		 * further distribute this message to peers who haven't yet seen it */
        for (i = 0; i < this->pool.size(); i++)
		{
			if (!this->pool.at(i)->isConnected)
				continue;
			
			wxString fp_hash = this->pool.at(i)->pid->hash;
			bool sendToThisPeer = true;

			/* has this message been seen by this peer? */
			for (n = 0; n < alreadyto.GetCount(); n++)
			{
				if (RAIN::SafeStringsEq(fp_hash, alreadyto[n]))
				{
					/* yes, so don't resend */
					sendToThisPeer = false;
					break;
				}
			}

			if (sendToThisPeer)
			{
				local_sendto.push_back(this->pool.at(i));
			}
		}

		if (local_sendto.size() == 0)
		{
			wxLogVerbose("we cannot further distribute this broadcast");
			/* we have nothing to do */
			return;
		}

		/* prepare the message */
		for (i = 0; i < local_sendto.size(); i++)
		{
			RAIN::Connection *c = local_sendto.at(i);

			/* myval is a pointer into msg's via hash at the node containing our hash */
			myval->hash[c->pid->hash] = new BEnc::Dictionary();
		}

		/* now send it */
		for (i = 0; i < local_sendto.size(); i++)
		{
			wxLogVerbose("dispatching to %d (%s)", i, local_sendto.at(i)->pid->address.c_str());
			local_sendto.at(i)->SendMessage(msg);
		}
	} else if (msgdest->getString().Cmp("Peer") == 0) {
		BENC_SAFE_CAST(msg->headers["To"], msgto, String);
		if (!msgto)
			return;
		wxString to = msgto->getString();

		wxLogVerbose("    peer routing - to %s - searching local connections", CryptoHelper::HashToHex(to, true).c_str());

		for (int i = 0; i < this->pool.size(); i++)
		{
			if (this->pool.at(i) && this->pool.at(i)->isConnected)
			{
				if (RAIN::SafeStringsEq(this->pool.at(i)->pid->hash, to))
				{
					wxLogVerbose("        found connection");
					this->pool.at(i)->SendMessage(msg);
					return;
				}
			}
		}

		/* we're still here :(
		 * this implies we're not connected to the recipient of this message
		 * so we need to route it */
		if (!msg->headers.count("Route-Preload"))
		{
			/* we need to consult our routing manager to see if we know
			 * of a route to this host */
			RoutePath *rp;

			if (rp = this->app->router->GetBestRoute(to))
			{
				rp->PreloadMessage(msg);
			} else {
				wxLogVerbose("Warning: route to %s unknown", CryptoHelper::HashToHex(to, true).c_str());
				msgdest->str = "Broadcast";
				this->DispatchMessage(msg);
				return;
			}
		}
		
		/* walk the route-preload looking for our hash */
		wxString myHash = globalCredentialManager->GetMyPeerID()->hash;
		wxString target = "";
		BENC_SAFE_CAST(msg->headers["Route-Preload"], preload, List);

		for (size_t i = 0; i < preload->getListSize(); i++)
		{
			BENC_SAFE_CAST(preload->getListItem(i), listitem, String);

			if (RAIN::SafeStringsEq(listitem->getString(), myHash))
			{
				if (i + 1 == preload->getListSize())
				{
					/* our target is actually To because we're last in the routelist */
					target = to;
				} else {
					BENC_SAFE_CAST(preload->getListItem(i + 1), nextlistitem, String);
					target = nextlistitem->getString();
				}

				break;
			}
		}

		if (target == "")
		{
			/* this should never happen - we got a message preloaded with a route
			 * not including us, or the message is to nowhere! */
			return;
		} else {
			for (size_t i = 0; i < this->pool.size(); i++)
			{
				if (this->pool.at(i) && this->pool.at(i)->isConnected)
				{
					if (RAIN::SafeStringsEq(this->pool.at(i)->pid->hash, to))
					{
						if (msg->headers.count("Via"))
						{
							BENC_SAFE_CAST(msg->headers["Via"], msgvia, List);
							msgvia->pushList(new BEnc::String(myHash));
						} else {
							BEnc::List *msgvia = new BEnc::List();
							msgvia->pushList(new BEnc::String(myHash));
							msg->headers["Via"] = msgvia;
						}

						this->pool.at(i)->SendMessage(msg);
						return;
					}
				}
			}

			/* we got a message with an old/invalid route - default to broadcast */
			msgdest->str = "Broadcast";
			this->DispatchMessage(msg);
			return;
		}
	} else if (msgdest->getString().Cmp("Random") == 0) {
		if (!this->AnyConnections())
		{
			wxLogVerbose("Warning: Tried to send message to random peer with no connections - ignored");
			return;
		}

		Connection *c = NULL;

		while (c == NULL)
		{
			size_t i = (size_t) this->pool.size() * (float) rand() / (float) RAND_MAX;
			wxLogVerbose("ConnectionPool: chose connection %d/%d for random dest", i, pool.size());

			if (i < this->pool.size())
				c = this->pool.at(i);

			if (!c->isConnected)
				c = NULL;
		}

		wxLogVerbose("Sending random message to connection %08x (%s)", c, c->pid->address.c_str());

		msgdest->str = "Peer";
		msg->headers["To"] = new BEnc::String(c->pid->hash);
		c->SendMessage(msg);
	}
}
コード例 #11
0
ファイル: PvPGM.cpp プロジェクト: practicing01/DotsNetCrits
void PvPGM::ServerHandleNetworkMessage(StringHash eventType, VariantMap& eventData)
{
	using namespace NetworkMessage;

	int msgID = eventData[P_MESSAGEID].GetInt();

	Connection* sender = static_cast<Connection*>(eventData[P_CONNECTION].GetPtr());

	if (msgID == MSG_GAMEMODELOADED)
	{
		ServerSynchronizeScene(sender);
	}
	else if (msgID == MSG_GAMEMODEMSG)
	{
		const PODVector<unsigned char>& data = eventData[P_DATA].GetBuffer();
		MemoryBuffer msg(data);
		int messageID = msg.ReadInt();
		if (messageID == MSG_SCENELOADED_)
		{
			PlayerSB* player;

			//Create player on server.
			for (int x = 0; x < server_->clientData_.Size(); x++)
			{
				if (server_->clientData_[x]->connection_ == sender)
				{
					int index = Random( 0, spawnPoints_.Size() );
					victoria_ = spawnPoints_[index]->GetPosition();
					quarterOnion_ = spawnPoints_[index]->GetRotation();
					player = NewPlayer(server_->clientData_[x], "Witch3", victoria_, quarterOnion_);//Witch3 is the default model.
					break;
				}
			}

			for (int x = 0; x < players_.Size(); x++)
			{
				//Send client the existing players.
				msg_.Clear();
				msg_.WriteInt(MSG_NEWPLAYER_);
				msg_.WriteInt(players_[x]->clientData_->clientID_);
				msg_.WriteString(players_[x]->modelFilename_);
				msg_.WriteVector3(players_[x]->player_->GetPosition());
				msg_.WriteQuaternion(players_[x]->player_->GetRotation());

				sender->SendMessage(MSG_GAMEMODEMSG, true, true, msg_);

				if (sender != players_[x]->clientData_->connection_)
				{
					((GameMechanic*)(players_[x]))->receiver_ = sender;
					((GameMechanic*)(players_[x]))->clientID_ = players_[x]->clientData_->clientID_;
					players_[x]->ServerSync();

					//Send the existing players the client.
					msg_.Clear();
					msg_.WriteInt(MSG_NEWPLAYER_);
					msg_.WriteInt(player->clientData_->clientID_);
					msg_.WriteString(player->modelFilename_);
					msg_.WriteVector3(player->player_->GetPosition());
					msg_.WriteQuaternion(player->player_->GetRotation());

					players_[x]->clientData_->connection_->SendMessage(MSG_GAMEMODEMSG, true, true, msg_);
				}
			}
		}
		else if (messageID == MSG_RequestMechanicExecute_)
		{
			for (int x = 0; x < players_.Size(); x++)
			{
				if (players_[x]->clientData_->connection_ == sender)
				{
					float lagTime = ServerGetSenderLagTime(sender);
					lagTime += ServerGetSenderLagTime(sender);
					((GameMechanic*)(players_[x]))->message_ = &msg;
					((GameMechanic*)(players_[x]))->clientID_ = players_[x]->clientData_->clientID_;
					((GameMechanic*)(players_[x]))->lagTime_ = lagTime;
					players_[x]->RequestMechanicExecute();
					break;
				}
			}
		}
	}
}