PHP + MySQL + Socket.io - Realtime online status of friends - node.js

I have created a realtime chat application similar to facebook using PHP/MySQL and node.js (socket.io) but i am now facing the following problem.
Scenario The logged in user has a list of friends similar to facebook and when any of his friends becomes away, offline, online etc. i would like his friends list to be updated with this in realtime without reloading the entire friends list with for example ajax polling every x seconds.
Every action the logged in user makes on the website like for example the change of page, new chat window, search or whatever i have a column named last_active that updates with the current unix_timestamp.
This is done to keep track of the user being online or away. If the timestamp is bigger than 300 seconds the user i away.
Every thirty seconds the database updates the column last_online with unix_timestamp for the logged in user.
This is done to keep track of the user being online. If the timestamp is bigger than 35 seconds we can assume he has closed the window and will be seen as offline and not away.
The user can also set his online status manually to busy, invisible etc. and this is set to the column custom_status for the logged in user.
Everything above is working as it should provided that the user always reload the page to see what online status his friends have but i would like this to be updated in realtime and not when reloading the entire page or using ajax polling to reload the entire friends list.
I was thinking about comparing the current online status on the client side and when a change occurs emit this to socket.io. I then loop through all connected clients and emit the users new online status to all connected friends.
But i guess there will be performance issues with this when say for example 1000 users are connected?
How would you handle this?

Related

No XEP-0333 Chat Markers in XMMPP Openfire backend - how to solve it?

We have an Openfire XMPP/Jabber server setup (with a NodeJs backend and React frontend).
Chat is a feature embedded in the app (NOT an overlay or window that is always visible). So the user has to navigate to a specific page to access the chat interface.
It is working via websockets and messaging sending is working fine. We have a React frontend.
The challenge is that XEP-0333 Chat Markers is not supported by Openfire (the spec never become production ready).
Therefore we need to know how can we implement this feature so that :
A users knows when they are online that they have an unread message (and later, how many unread message they have). For example, if they are not in the chat window and messages are arriving, we need to indicate that in the header of the app so they see it)
if a user goes offline, and comes back online but NOT into the chat window, how can we know if they have unread messages and notify them of that?
My understanding is that somehow we have to keep track of unread messages (eg perhaps in indexedb or local storage or even in postgres backend) and after the user reads a message, we delete it from storage. If the storage still has records for that user then clearly those are the unread messages.
Obviously we don't know if they actually READ the message, but we can assume that if the chat window is open and visible (ie. active tab in their browser) that any messages delivered have been read.
So if our application tab is active, but user is not in chat, and a message arrives, we store it. When they open chat and click on the sender, we remove it from storage.
Has anyone solved it this way? (looking for links to React or JS/TS code)
Is there a better way? (links to other solutions would be helpful, esp. code)

Real-time notification feature in MERN stack

I am trying to build a web app where users can receive notifications if their posts get likes. This functionality is actually working but the notification component renders only when the page reloads. But I want it to re-render the notification component as soon as there is a change that occurs with it. I am trying to make this work with SocketIO both in client and server but it feels like there should be a way easier way to solve this issue. How?
One way to achieve this is to use server-sent events (SSE), which can be seen as a uni-directional
and simplified version of WebSocket (only server can send data to clients). You might need route param or query string so that users can connect to different channels.
If it doesn't have to be so real-time (i.e. receiving notifications 1 minute after somebody liked the post is okay), you could also try (long)polling.
However, since post-like table may contain a huge amount of data, constantly querying it is expected to result in bad performance on the server. Also, adding an extra column to mark if the user has been notified about a specific like is trivial.
A possible workaround might be to create a new table, say pending-like-notification, which is used to stored all pending like notifications. Whenever a post is liked, we insert a new record into this table.
Therefore, when a user tries to query if any of his posts is liked recently, in the backend we lookup this table instead of the post-like table, and delete the selected rows after the user has been notified so that the amount of data in this table can stay low (hopefully).
All in all, in this scenario, I think SSE and WebSocket will be better choices.

Is it possible to store messages in a socketio chat app

Let's say I made a complete UI of a chat app. We have a panel which contains all the recently contacted. We have react on the front-end and node, express on the backend. The real time data transfer chat is carried out using socketio.
The real question is how do I store all the messages that I have with each user. Let's say I chatted with user A for a while, closed the tab and moved to user B. Then the next day I moved back to the user A, I want all my previous chats with that user to be available to me.
How is that achievable?
One way I can wrap my head around is that I use mongoDB to create a chat room with two specific user and a id. Then I store that room on mongo with all the chats stored in an array.
On the client side, I check the db if a specific chat room exists. If it does, I send all the messages in to the client side, if not it create a new chat room.
This is by far the most sensible thing I've thought.
Any guidance as to what other techniques I can use?
Much appreciated.

Best way to track how many times a user has logged in

I'm looking for advice on tracking user logins on my site. I had built a counter that increments on logins but it increments for all users not just one user. I only need it to increment when a specific user logs in. The purpose is to have a welcome message display the first time a user logs into the site. My site is built using ReactJs for the front end and NodeJs for the back. So far I tried using a state with a count set at 0 and then when the login function is run update the count by one. This works but it isn't relative to a user, just to the login function itself. Any advice?

Is it possible to check if anyone has a certain browser link open and if not execute a function?

I am making a web app that involves the creation of several rooms (users create them). These rooms are then stored on an array on the server. Using react router each of these rooms are given their own unique url /roomCodeGoesHere. I want to periodically check the rooms to see if anyone is in it(I guess in this case has the browser open?) and if there is no one in it, to have the room be deleted from the array.
Is there any way I can go about doing this? (the only ways I can think of seem hacky and are probably not good practice)
You can monitor the user count within your server array (via put request or websocket on mount/unmount), and if the room empties conditionally delete it within the controller. A room should by default start with 1 occupancy since it needs a creator. If you don't want to delete the room right away, then do the same thing but create a setTimeout that conditionally clears itself unless someone new enters.
This chat app I made deletes a room at 0 users using the above method:
http://astral-chat-app.herokuapp.com/

Resources