diff --git a/test/src/realtime/test_chat.cpp b/test/src/realtime/test_chat.cpp index 4f1420a7..d4c782bd 100644 --- a/test/src/realtime/test_chat.cpp +++ b/test/src/realtime/test_chat.cpp @@ -52,7 +52,7 @@ namespace Nakama { NSessionPtr session = test.client->authenticateCustomAsync(TestGuid::newGuid(), std::string(), true).get(); bool createStatus = false; test.rtClient->connectAsync(session, createStatus, NTest::RtProtocol).get(); - const NGroup group = test.client->createGroupAsync(session, "group chat " + session->getAuthToken(), "a group for chatting", "", "", false, {}).get(); + const NGroup group = test.client->createGroupAsync(session, TestGuid::newGuid(), "a group for chatting", "", "", false, {}).get(); const NChannelPtr channelPtr = test.rtClient->joinChatAsync(group.id, NChannelType::GROUP, {}, {}).get(); test.stopTest(true); } diff --git a/test/src/realtime/test_lifecycle.cpp b/test/src/realtime/test_lifecycle.cpp index 7c92af9d..4741e254 100644 --- a/test/src/realtime/test_lifecycle.cpp +++ b/test/src/realtime/test_lifecycle.cpp @@ -171,6 +171,51 @@ namespace Nakama { test.stopTest(connected); } + // requires session.single_socket to be true. + void test_rt_simultaneous_connect() + { + bool threadedTick = true; + + NTest test(__func__, threadedTick); + test.runTest(); + + NSessionPtr session = test.client->authenticateCustomAsync(TestGuid::newGuid(), std::string(), true).get(); + + test.rtClient->connectAsync(session, true).get(); + + bool disconnected = false; + std::mutex disconnectedMtx; + std::condition_variable disconnectedCV; + + test.listener.setDisconnectCallback([&](const NRtClientDisconnectInfo& info) { + std::unique_lock lock(disconnectedMtx); + disconnected = true; + disconnectedCV.notify_one(); + }); + + std::atomic rtClient2Tick(true); + auto rtClient2 = test.client->createRtClient(); + rtClient2->connect(session, true); + + std::thread tickThread([&]() { + while (rtClient2Tick.load()) { + rtClient2->tick(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + }); + + { + std::unique_lock lock(disconnectedMtx); + disconnectedCV.wait(lock, [&](){ return disconnected; }); // Wait until rtClient1 disconnects due to new connect. + } + + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // see if any tick() from rtClient2 causes exceptions to get thrown. + rtClient2Tick.store(false); + tickThread.join(); + + test.stopTest(true); + } + void test_connectivity_loss() { bool threadedTick = true; diff --git a/test/src/realtime/test_realtime.cpp b/test/src/realtime/test_realtime.cpp index d323bfe0..5eb29669 100644 --- a/test/src/realtime/test_realtime.cpp +++ b/test/src/realtime/test_realtime.cpp @@ -37,6 +37,8 @@ void test_rt_reconnect(); void test_rt_connect_callback(); void test_rt_double_connect(); void test_rt_double_connect_async(); +void test_rt_simultaneous_connect(); + void test_connectivity_loss(); void run_realtime_tests() @@ -58,6 +60,8 @@ void test_realtime() test_rt_connect_callback(); test_rt_double_connect(); test_rt_double_connect_async(); + // optional test. requires session.single_socket to be true in server configuration. + // test_rt_simultaneous_connect(); // optional "test". run websocket for a full minute. useful for testing connection loss with network link conditioner. // test_connectivity_loss();