Esempio n. 1
0
void SessionImpl::OnConnected(const NetworkConnectionPtr& connection)
{
	// We have successfully connected to this session.  
	// Now send it information about us so it lets us in all the way

	XTASSERT(m_curState == MachineSessionState::JOINING);

	JoinSessionRequest request(
		m_context->GetLocalUser()->GetName()->GetString(),
		m_context->GetLocalUser()->GetID(),
        m_context->GetLocalUser()->GetMuteState()
		);

	NetworkOutMessagePtr msg = connection->CreateMessage(MessageID::SessionControl);

	msg->Write(new XString(request.ToJSONString()));

	connection->Send(msg);
}
Esempio n. 2
0
void SessionServer::OnListSessionsRequest(const ListSessionsRequest&, const NetworkConnectionPtr& connection)
{
	// Fill in a message with a list of all the sessions and send it

	ListSessionsReply reply;

	reply.SetSessionCount(static_cast<int32>(m_sessions.size()));

	for (size_t i = 0; i < m_sessions.size(); ++i)
	{
		XSessionImplPtr currentSession = m_sessions[i];

		reply.SetSessionDescriptor((int32)i, currentSession->GetSessionDescription(connection->GetSocket()));
	}

	NetworkOutMessagePtr msg = connection->CreateMessage(MessageID::SessionControl);
	msg->Write(reply.ToJSONString());

	connection->Send(msg);
}
void SendToForwarder::OnMessageReceived(const NetworkConnectionPtr& connection, NetworkInMessage& message)
{
	const byte* inMsg = message.GetData();
	const uint32 inMsgSize = message.GetSize();

	// Get the sendto header
	const SendToNetworkHeader* sendToHeader = reinterpret_cast<const SendToNetworkHeader*>(inMsg);

	// Extract the payload from the sendto message and put in a new outgoing message
	const byte* payload = inMsg + sizeof(SendToNetworkHeader);
	const uint32 payloadSize = inMsgSize - sizeof(SendToNetworkHeader);

	if (payloadSize > 0)
	{
		NetworkOutMessagePtr outMsg = connection->CreateMessage(*payload);
		outMsg->WriteArray(payload + 1, payloadSize - 1);

		// Send the payload to the correct remote peer
		auto userConnectionItr = m_connections.find(sendToHeader->m_userID);
		if (userConnectionItr != m_connections.end())
		{
			ClientRole role = sendToHeader->m_deviceRole;

			if (role == ClientRole::Primary ||
				role == ClientRole::Unspecified)
			{
				// Forward the message on with the same settings that it was sent here with
				userConnectionItr->second.m_primaryConnection ->Send(outMsg, sendToHeader->m_priority, sendToHeader->m_reliability, sendToHeader->m_channel, false);
			}

			if (role == ClientRole::Secondary ||
				role == ClientRole::Unspecified)
			{
				// Forward the message on with the same settings that it was sent here with
				userConnectionItr->second.m_secondaryConnection->Send(outMsg, sendToHeader->m_priority, sendToHeader->m_reliability, sendToHeader->m_channel, false);
			}
		}

		connection->ReturnMessage(outMsg);
	}
}
Esempio n. 4
0
void SessionServer::OnNewSessionRequest(const NewSessionRequest& request, const NetworkConnectionPtr& connection)
{
	std::string name = request.GetSessionName();

	XSessionImplPtr session;
	std::string failureReason;

	// Cannot create a session with a name that is too short
	if (name.length() < kMinSessionNameLength)
	{
		failureReason = "Session name must have at least " + std::to_string(kMinSessionNameLength) + " letters";
	}

	// Cannot create a session with a name that is too long
	else if (name.length() > kMaxSessionNameLength)
	{
		failureReason = "Session name cannot be more than " + std::to_string(kMaxSessionNameLength) + " letters";
	}
	else
	{
		// Check to make sure that the requested session name is not already taken
		for (size_t i = 0; i < m_sessions.size(); ++i)
		{
			if (m_sessions[i]->GetName() == name)
			{
				failureReason = "A session with that name already exists";
				break;
			}
		}
	}

	if (failureReason.empty())
	{
		session = CreateNewSession(name, request.GetSessionType());
	}
	
	// If the session was successfully created...
	if (session)
	{
		// Report success.
		std::string address = m_socketMgr->GetLocalAddressForRemoteClient(connection->GetSocket());
		uint16 port = session->GetPort();

		NewSessionReply reply(
			session->GetId(), 
			session->GetType(),
			name, 
			address, 
			port);

		NetworkOutMessagePtr response = connection->CreateMessage(MessageID::SessionControl);

		response->Write(reply.ToJSONString());

		connection->Send(response);
	}
	else
	{
		// Report failure
		NewSessionReply reply(failureReason);

		NetworkOutMessagePtr response = connection->CreateMessage(MessageID::SessionControl);

		response->Write(reply.ToJSONString());

		connection->Send(response);
	}
}
Esempio n. 5
0
void XSessionImpl::OnJoinSessionRequest(const JoinSessionRequest& request, const NetworkConnectionPtr& connection)
{
	// Note: this call will remove the remote client from the list of pending connections
	RemoteClientPtr remoteClient = GetPendingClientForConnection(connection);

	if (remoteClient)
	{
		// Fill in the rest of the info about the user
		remoteClient->m_userName = request.GetUserName();
		remoteClient->m_userID = request.GetUserID();
		remoteClient->m_userMuteState = request.GetMuteState();

		// Check to see if this userID is already in use by someone in the session
		bool bDuplicateUserID = false;
		for (size_t clientIndex = 0; clientIndex < m_clients.size(); ++clientIndex)
		{
			if (m_clients[clientIndex]->m_userID == remoteClient->m_userID)
			{
				bDuplicateUserID = true;
				LogError("UserID %i in session join request is a duplicate of a user already in this session.  ", remoteClient->m_userID);
				break;
			}
		}

		// Check to see if the userID is valid
		bool bIsInvalidUserID = false;
		if (remoteClient->m_userID == User::kInvalidUserID)
		{
			LogError("Received invalid userID");
			bIsInvalidUserID = true;
		}

		// If the connecting user is invalid, then send a failure response and shut down the connection
		if (bIsInvalidUserID || bDuplicateUserID)
		{
			// Reply to the user that they have failed to join the session
			{
				JoinSessionReply reply(false);

				NetworkOutMessagePtr msg = connection->CreateMessage(MessageID::SessionControl);
				msg->Write(reply.ToJSONString());
				connection->Send(msg);
			}

			// Disconnect
			connection->Disconnect();
		}
		else
		{
			LogInfo("User %s at address %s joined session %s", remoteClient->m_userName.c_str(), remoteClient->m_primaryConnection->GetRemoteAddress()->GetString().c_str(), GetName().c_str());

			// Add the user to the real list of clients in the session
			m_clients.push_back(remoteClient);

			// Reply to the user that they have now joined the session successfully
			{
				JoinSessionReply reply(true);

				NetworkOutMessagePtr msg = connection->CreateMessage(MessageID::SessionControl);
				msg->Write(reply.ToJSONString());
				connection->Send(msg);
			}

			// Add the remoteClient to the list that can send and receive broadcasts
			m_broadcaster->AddConnection(remoteClient->m_primaryConnection);
			m_broadcaster->AddConnection(remoteClient->m_secondaryConnection);

			// Add the remoteClient to the sendto forwarder
			m_sendToForwarder->AddConnection(remoteClient->m_userID, remoteClient->m_primaryConnection, remoteClient->m_secondaryConnection);

			// Add the remoteClient to the audio packet processor
			m_audioSessionProcessor->AddConnection(remoteClient->m_primaryConnection);
			m_audioSessionProcessor->AddConnection(remoteClient->m_secondaryConnection);

			// Add the connections to the room manager
			m_roomMgr->AddConnection(remoteClient->m_primaryConnection);
			m_roomMgr->AddConnection(remoteClient->m_secondaryConnection);

			// Add the remoteClient to the list that can share the session's sync data
			m_syncMgr->AddConnection(remoteClient->m_primaryConnection);
			m_internalSyncMgr->AddConnection(remoteClient->m_primaryConnection);

			// Notify the session server to tell all the clients that the new user has joined this session
			m_callback->OnUserJoinedSession(m_id, remoteClient->m_userName, remoteClient->m_userID, remoteClient->m_userMuteState);
		}
	}
}