bool SessionImpl::Join() { // Cannot join a session while we're joined or currently attempting to join. if (MachineSessionState::DISCONNECTED == m_curState) { LogInfo("Attempting to join session %s at %s:%i", m_name->GetString().c_str(), m_address.c_str(), m_port); // Verify that no other sessions are already in a joining state. int sessionCount = m_sessionMgr->GetSessionCount(); for (int i = 0; i < sessionCount; i++) { SessionPtr curSession = m_sessionMgr->GetSession(i); // Fail if any sessions are in a pending state. // TODO: Instead, we should just auto leave all non-disconnected sessions. if (curSession->GetMachineSessionState() == MachineSessionState::JOINING) { LogError("SessionImpl::Join called while another session %s was in a joining state", curSession->GetName()->GetString().c_str()); curSession->Leave(); XTASSERT(curSession->GetMachineSessionState() == MachineSessionState::DISCONNECTED); return false; } } SessionPtr oldSession = m_sessionMgr->GetCurrentSession(); if (oldSession) { LogInfo("Automatically leaving existing session %s", oldSession->GetName()->GetString().c_str()); oldSession->Leave(); XTASSERT(oldSession->GetMachineSessionState() == MachineSessionState::DISCONNECTED); XTASSERT(m_sessionMgr->GetCurrentSession() == NULL); } // Set out state to joining SetState(MachineSessionState::JOINING); // Set this as the current session for this machine m_sessionMgr->SetCurrentSession(this); // Attempting to join a new session; notify the listeners m_listenerList->NotifyListeners(&SessionListener::OnJoiningSession); // Attempt to open a connection to this session XSocketPtr socket = m_context->GetXSocketManager()->OpenConnection(m_address, m_port); if (XTVERIFY(socket)) { // Initiate the handshake HandshakeCallback callback = CreateCallback3(this, &SessionImpl::OnHandshakeComplete); m_handshake = new NetworkHandshake(socket, new SessionHandshakeLogic(false), callback); return true; } else { LogError("Join failed we failed to create a socket to the session at %s:%u.", m_address.c_str(), m_port); } } else { LogError("Join failed because the current state is %s instead of DISCONNECTED", (m_curState == MachineSessionState::JOINING) ? "JOINING" : "JOINED"); } return false; }