Jump to content

mark1234

New Members
  • Posts

    5
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

mark1234's Achievements

Newbie

Newbie (1/5)

0

Reputation

  1. Sorry for the triple post. The program seems to be working about 3/4th's of the time, but 25% of the time the users get sent into the wrong rooms because memcache didn't store the variable apparently? I have the logging going with memcache. As you see in the 2 highlighted lines, there's "no cached data" 2 times in a row. This is the malfunction whereby the users are sent into two different rooms, instead of the same. With it's every other one cached/not cached, it works fine. Any ideas what could be causing this behavior? I just started using memcache for the first time so I'm not super familiar.
  2. There's possibly some issues in my front end javascript causing additional bugs/gremlins, but I'd like to focus on the back-end PHP code causing state misconnections for multiple requests happening <5s if anyone has suggestions how to remedy that.
  3. EDIT: Yes. When there's >2 users requesting within 5 seconds, this is where the script seems to be having trouble with misconnections. If it's just 2 users requesting in 5s, it's fine. If the other users are connected in rooms, it's fine. But handling >2 requests in a short period (5 seconds) seems to be the challenge here. Although I'd add, sometimes just 2 users requesting in <5 results in a room misconnection. MYSQL and MEMCACHE are both ATOMIC, but perhaps mixing the 2 to manage state - isn't going to be ATOMIC anymore. But it seems that that's not the primary issue, since I'm only QA testing this with 2 or 3 users max. It's not like it's getting hundreds of hits per minute causing strange issues. I have a logging table the looks something like this 281 - NOT CACHED DATA3 - 40981446 282 - NOT CACHED DATA3 - 64097845 283 - NOT CACHED DATA3 - 95710375 284 - NOT CACHED DATA3 - 599601 285 - CACHED DATA3 - 599601 The # is the row, the CACHED/NOT CACHED DATA is depending on which script block it's triggering, and the last # is the generated room number. Whether it's trigging this script block: if ($cachedData) { //echo "cached data found"; //echo "USER 2"; // $room = see_if_exists($mysqli, $formatted_users); logmyfolly("CACHED DATA".$idvariables[0],$idvariables[1], $cachedData, $mysqli); //ensure we don't direct user into an occupied room if(check_if_users_joined_room_three($mysqli, $idvariables[0], $idvariables[1]) != true){ // echo "occupied room"; $arr = array('status' => 1, 'roomID' => $cachedData); echo json_encode($arr); // update room being occupied room_joined_log($idvariables[0], $idvariables[1], $mysqli); $memcached->delete($idvariables[0].$idvariables[1]); //43291624 - did connect //26481673 dind't connect //32970404 dind't connect //42537685 did connect } } or this one: if (!$cachedData) { // logmyfolly("NOT CACHED DATA".$idvariables[0],$idvariables[1], $roomIDinsert, $mysqli); //6370375 didnt work , 73342033 didn't work logmyfolly("NOT CACHED DATA".$idvariables[0],$idvariables[1], $roomIDinsert, $mysqli); deleteIfExists($mysqli, $formatted_users); insert_stuff($formatted_users, $roomIDinsert, $idvariables[0], $idvariables[1], $mysqli); $arr = array('status' => 1, 'roomID' => $roomIDinsert); echo json_encode($arr); if (!$memcached->set($idvariables[0].$idvariables[1], $roomIDinsert, $expiration)) { echo "Failed to set key '$key' in Memcached."; } if (!$memcached->set($roomIDinsert, $roomIDinsert, $expiration)) { echo "Failed to set key '$key' in Memcached."; } } Perhaps there's a memcached library or something else which would be helpful for managing state? By the way, this is FIFO. First in first out. There's multiple requests to the script, I want the fastest request gets the room assignment. And the rest to be disappointed. It's because I want the fastest/nearest internet connection to connect with these users. Anything I much appreciate your eagerness to help! I puzzled on this all day yesterday, it's going to take a minor-miracle to fix it in the time I need it for! But that's my fault lol.
  4. THANKS for the reply! I am using memcache to store state for 5 seconds. And I'm using a SQL update statement when a room becomes "occupied" with 2 users, as not to direct a 3rd user into an occupied room & have an error. I kind of have it working now, but it's buggy so question both my application architecture & whether I actually have this business logic right. The way this works, is both users are making a request to AJAX request to $_POST['user'] and $_POST['number'] to speak to each other, within 5 seconds. (Hence the memcache variable lifetime.) So if I'm user 3, and you're user 4. You request 3 & 4 to speak with me. Just as I request 3 and 4 to speak with you. This code sometimes works, but again it's buggy so I'm not satisfied with it. I may need to refactor quite a bit. See anything obvious by chance that pops out? $user = $_POST['user']; $number = $_POST['number']; $memcached = new Memcached(); // Add a server (you may need to adjust this depending on your Memcached setup) $memcached->addServer('localhost', 11211); $expiration = 5; // Time in seconds $memcached->set($user, $number, $expiration); function check_if_users_joined_room_three($mysqli, $low_user, $high_user){ $one = 1; $query = "SELECT `joined_log` FROM `rooms` WHERE `low_user` = ? AND `high_user` = ? AND `joined_log` = ?"; $stmt = $mysqli->prepare($query); $stmt->bind_param("sss", $low_user, $high_user, $one); $stmt->execute(); $stmt->store_result(); if ($stmt->num_rows > 0) { // $stmt->bind_result($joined_log); // $stmt->fetch(); return true; } else { return false; // Return null if no rows are found } } function room_joined_log($low_user, $high_user, $mysqli){ $joined = 1; $stmt = $mysqli->prepare("UPDATE `rooms` SET `joined_log` =? WHERE `low_user` = ? AND `high_user` = ?"); $stmt->bind_param("iss", $joined, $low_user, $high_user); $stmt->execute(); $stmt->store_result(); if (!$stmt) { echo "error:".mysqli_error($mysqli); } } function deleteIfExists($mysqli, $users) { $query = "DELETE FROM `rooms` WHERE `users` LIKE ?"; $stmt = $mysqli->prepare($query); if (!$stmt) { echo 'Error: ', $mysqli->error; return false; } $stmt->bind_param("s", $users); if (!$stmt->execute()) { echo 'Error: ', $stmt->error; return false; } else { // Check if any rows were affected (deleted) $rowsAffected = $stmt->affected_rows; // Close the statement $stmt->close(); return $rowsAffected; // Return the number of rows deleted } } function see_if_exists($mysqli, $users){ $query = "SELECT `room_id` FROM `rooms` WHERE `users` LIKE ?"; $stmt = $mysqli->prepare($query); if (!$stmt) { echo 'Error: ', $mysqli->error; return false; } $stmt->bind_param("s", $users); if (!$stmt->execute()) { echo 'Error: ', $stmt->error; return false; } $stmt->store_result(); if ($stmt->num_rows > 0) { $stmt->bind_result($room_id); $stmt->fetch(); return $room_id; } else { return null; // Return null if no rows are found } } function insert_stuff($users, $room_id, $low_user, $high_user, $mysqli){ $time = date("Y-m-d H:i:s", time()); $stmt = $mysqli->prepare("INSERT INTO rooms (users, room_id, inserttime, low_user, high_user, unixtimestamp) VALUES (?,?,?,?,?,?)"); $stmt->bind_param("ssssss", $users, $room_id, $time, $low_user, $high_user, time()); $stmt->execute(); if (!$stmt) { echo "error:".mysqli_error($mysqli); } } function insert_log($low_user, $high_user, $mysqli){ $stmt = $mysqli->prepare("INSERT INTO push_notifications (low_user, high_user) VALUES (?,?)"); $stmt->bind_param("ss", $low_user, $high_user); $stmt->execute(); if (!$stmt) { echo "error:".mysqli_error($mysqli); } } function logmyfolly($low_user,$high_user, $room_id, $mysqli){ $stmt = $mysqli->prepare("INSERT INTO log_table (low_user, high_user, room_id) VALUES (?,?,?)"); $stmt->bind_param("sss", $low_user, $high_user, $room_id); $stmt->execute(); if (!$stmt) { echo "error:".mysqli_error($mysqli); } } $randomNumber = rand(0, 99999999); $roomIDinsert = (string)$randomNumber; $idvariables = array($user, $number); sort($idvariables); $formatted_users = trim($idvariables[0]).",". trim($idvariables[1]); $cachedData = $memcached->get($idvariables[0].$idvariables[1]); // your friend has already requested to talk to you if ($cachedData) { //echo "cached data found"; //echo "USER 2"; $room = see_if_exists($mysqli, $formatted_users); // logmyfolly($idvariables[0],$idvariables[1], $room, $mysqli); //ensure we don't direct user into an occupied room if(check_if_users_joined_room_three($mysqli, $idvariables[0], $idvariables[1]) != true){ // echo "occupied room"; $arr = array('status' => 1, 'roomID' => $room); echo json_encode($arr); // update room being occupied room_joined_log($idvariables[0], $idvariables[1], $mysqli); } } if (!$cachedData) { deleteIfExists($mysqli, $formatted_users); insert_stuff($formatted_users, $roomIDinsert, $idvariables[0], $idvariables[1], $mysqli); $arr = array('status' => 1, 'roomID' => $roomIDinsert); echo json_encode($arr); $memcached->set($idvariables[0].$idvariables[1], $idvariables[0].$idvariables[1], $expiration); // key, user }
  5. Hi Forum, I'm building a random chat application. So far, it works great. Here's the problem though. It only works for 2 simultaneously connected users. As soon as I have 3 users trying to connect to the "swarm" to get a random chat assignment, well, all calamity ensures. Essentially, the random room assignments then malfunction, creating a terrible user experience. Essentially, I'm struggling to manage state for multiple connected users in a LAMP environment. I'm using Ably websockets and the PHP SDK for messages, and a few other APIs for video/chat. In addition, I'm using AJAX callbacks in jQuery. I'm also (as an experiment) using PHP Memcached. I thought it would be simple enough to use it to manage the state of all users across the application using Memcached, but it's harder than I thought. I'm also using the standard php_sessions to manage whether the user is logged in (and authorized to chat) or not. I realize PHP is perhaps not the ideal language/stack for something like this, perhaps something asynchronous would be better. But it's what I got and am trying to make it work, I don't have time to refactor everything and learn something new. So my question is how the heck do I do this? Here's the crux of the issue. Suppose: There's 3 users trying to connect simultaneously for a random chat. User 1 immediately gets paired with user 2, and user 3 should simply wait until patiently until there's another user that joins the swarm. The issue is user 1, 2, and 3 are currently all being assigned to a room, that can only hold 2 users at maximum. I know it sounds awfully simple to manage a swarm of users like this concurrently, but it's not in my experience in part because: When users connect, they need to connect quickly in say 1-2 or 3 seconds maximum, otherwise people may leave the application or no longer be interested or no longer have internet connectivity. This means a way to check and re-check the user's internet connectivity. Currently I'm using an AJAX callback to the server to do this, which then responds with a RoomID to the users. The issue is the server can't tell whether the user doing the callback is user 1 or user 2, or even user 3. It all responds similarly. I've tried to solve this with Memcached by storing an array of all user's requests in the past 5 seconds, and referencing it with the current user. This might be a viable approach, but I'm seeking some guidance from the community before I continue down that rabbit hole. I'm probably thinking about this wrongly in some way. But in your opinion, how would you most simply, and most robustly manage state for a swarm of connected users, using AJAX callbacks of a swarm of users? Websockets are a possibility as well, but only publicly broadcasting to all connected users via a REST API. I don't have access to private channels or connected user lists currently. Thanks for any help/suggestions!
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.