This is my Firebase database structure:
// Registered users
users{
9BKlHH11NvU1kQdpwSaFshNJn8C2{
foo: foo
bar: bar
B5Lq9RquOvcK7CLhh1Mdq0qWCqO2{
foo: foo
bar: bar
// Connected users inside the lobby
Lobby{
9BKlHH11NvU1kQdpwSaFshNJn8C2,
B5Lq9RquOvcK7CLhh1Mdq0qWCqO2
So everytime a registered user logs in and enters the lobby, his uid is added to the lobby list so everybody sees him. If he logs out there's a process to remove him from the lobby list.
Now the problem is; what would be the best approach to remove a user that has closed the browser/app without leaving the lobby so the rest of the users don't see someone that is not actually connected in that list? Is there a timeout function maybe?
There is no timeout function.
Though on the application end, you can add and check the entry in Lobby, and send the beacon request in every 10 or 30 sec or more to make the entry in lobby valid.
And in the UI, while listing Users in the Lobby, if Lobby entry is older than the beacon time, you can either not list them or send a request to remove them.
It will be better to just skip the addition of that User in the UI, let the old entries be there. Sending the removal request will be contradicting, and will arise conflicts if more front ends are sending request to remove same User from Lobby. But, its all up to your app structure and Use Case.
Related
I'm trying to implement a ready button in my lobby and depending on whether the player is ready or not I change the status image from red to green. For example, the Call of Duty Black Ops 1 zombie lobby sums up what i would like to do.
In the GameMode of my lobby, there is an array of player controller that feeds on each player that connects to the session.
In the GameState, I have all the names of the players that are ready in an array that is replicated:
https://i.stack.imgur.com/HpfjS.png
In the widget, by clicking the ready button, I send the name of the client who is ready to the server:
https://i.stack.imgur.com/eoAga.png
When I click ready on the host client, all the other clients get the information and can update their UIs to see who is ready. But when I get ready on a non-host client, the array of player names that are ready (GameState) does not update because of "Has Autority" but if I remove it, it fits only for the client and not for all clients.
I have seen a lot of solutions but none that help me. So how could i get a non-host client to send its player name to the server, so the server can update my ready player name array and not the non-host client update himself ?
Thanks you in advance for any help provided.
I have clients connecting to the database with javascript.
I also have code running on my server and I'm trying to do a transaction following example as shown here:
https://firebase.google.com/docs/database/server/save-data#section-transactions
Here's a simplified structure of my data
users:
userguid
resource : "room1"
printer : "printer1"
resources
rooms
room1
printers
printer1
counter : 15
The web client would write a request to their own node under "users".
The server is watching for those request and updates the counter for that resource.
If i have the transaction watching for child added I get null for counter so I can't increment the number. If I also watch for child modified the I will get the correct counter value.
I understand from the documentation that the value in transaction can be null but I'm not sure how I can fix my use case to do what I need.
Basically I don't want the client touching the counter, I want the server to read and update that value.
I've gone thru this post
Firebase runTransaction not working
but I'm not clear on how to structure my code to deal with this.
I have a chat app powered by Firebase, and I'd like to get a timestamp from Firebase before pushing any data.
Specifically, I'd like to get the time that a user pushes the send button for a voice message. I don't actually push the message to Firebase until the upload was successful (so that the audio file is guaranteed to be there when a recipient receives the message). If I were to simply use Firebase.ServerValue.TIMESTAMP, there could be an ordering issue due to different upload durations. (A very short message following a very long one, for example.)
Is there anyway to ping Firebase for a timestamp that I'm not seeing in the docs? Thank you!
If you want to separate the click, from the actual writing of the data:
var newItemRef = ref.push();
uploadAudioAndThen(audioFile, function(downloadURL) {
newItemRef.set({
url: downloadURL,
savedTimestamp: Firebase.ServerValue.TIMESTAMP
});
});
This does a few things:
it creates a reference for the item item before uploading. This reference will have a push ID based on when the upload started. Nothing is written to the database at this point, but the key of the new location is determined.
it then does the upload and "waits for it" to complete.
in the completion handler of the upload, it writes to the new location it determine in step 1.
it writes the server timestamp at this moment, which is when the upload is finished
So you now have two timestamps. One is when the upload started and is encoded into the key/push id of the new item, the other is when the upload completed and is in the savedTimestamp property.
To get the 3 most recently started uploads that have already completed:
ref.orderByKey().limitToLast(3).on(...
To get the 3 most recently finished uploads:
ref.orderByChild('savedTimestamp').limitToLast(3).on(...
I am working on web application , in my project there is some type of testing and task assignment to employees.
Now when an employee complete a task and assigned to a user the user automatically get the message on his page ( there is 3 user accessing application , one is admin , second is tester and third is verifier ...both of them works on different pages , now when admin assign a task the tester automatically get a notification " new message " ( for this i am using master page)..on whatever page the tester is on working... now if the tester is completes it 's task and assign to verifier , verifier must get notification "new message" ... and so on..)
for this a have put a button on master page ..and also i have make a windows service that runs on every minute , now my problem is how i sent the message from windows service to my master page button ( that i change text of button).
Is this idea working ?
Why do you need to window service to run in background? Is there any specific reason to have the windows service for these requirements?
As per your detailed description what I understood is that when the employee completes a task and assigned to a user the user automatically get the message on his page. So when the employee is working and completed means they will click on some button that their work is completed. Then while clicking on the button, you just write the code for sending the mail to the tester. like the same way, when the tester is completed their work and click on the testing completes, send a mail to the reviewer and so on..Then where is the need to have a window service for this to send the mails?
All the requirements can be achieved through the simple send mail code.
Let us know if you need any more help or if you don't understand the exact scenario or if anything is missing in the requirements.
Hope it will be helpful to you.
I don't think it is possible to send from a windows service informations to asp.page. You can create a button that can query a webservice about new tasks (but you are counting on the user to press it).
Another more "friendly" way is to have a timer in javascript that uses ajax requests to get new tasks.
I my application I do not want the same user name login at the same time,so I have and idea but I am not sure if it is correct.
1) When a user login,update the status(the "isOnLine" column in the user table in db) and save its login time in the session ,something like:
Inside the login method:
DateTime ltime=Datetime.now();
Dbservice.executeSql(update User set(isOnLine,lastLoginTime) value("1",ltime));
Session["logintime"]=ltime;
When another user try to login,check the table to see if the status of this user is logined or not.if yes,set the "isOnline" to "0",then he can login now.
2)In each protected page's Page_Onload() method,check if the login time in the session is equal to the time in db:
string logtime=Dbservice.executeSelect("select lastLoginTime from user where xxxxx").Rows[0]["lastLoginTime"];
if(!Session["logintime"]==logtime){
//this user should offline now,redirect it to the login page
}
I wonder if my way is right or not?
Also,I have to write the check logic in each protected page's Page_onLoad method,so there are so many repeat codes,any ideas to avoid this?
Since all the page in our site is protected!.
Thanks.
UPDATE:
It is not allowed two user online at the same time,but it is allowed the later user with the correct pasword can force the former user offline. For example:
user1 login with "username=bill" and
"password=000",then he is online now.
then user2 try to login with
"username=bill" and
"password=123",since his password is
not valid,so his request is denied.
user3 try to login with
"username=bill" and
"password=000",since his password is
valid,so he have the choice to make
the user1 offline.
In this case,when the later user login sucessfully,but the session of the former user is also exist,so I have to check if it is online or not according the "logintime" in the session.
If you are not going to use web farm (or web garden) scenarios then you may use in memory structure to keep track of logged in users. For example, a static global variable of dictionary type (accessed in thread-safe way).
For general purpose robust solution, you need to keep this information in database (as illustrated by you). I haven't understood the purpose of checking against logged in time against session. For correct solution,
You need a database table that will track user's session. Important field will be last accessed time and active/inactive state.
At the time of login, if active session for same user exists in db then user cannot be logged in
A job to mark session inactive after specific time-out. This time-out has to be slightly larger (say x minutes) than web server session time-out.
Periodic refresh from application code to reset the last accessed value in db so that job will not mark session inactive.
Because db time-out = web server time-out + x, you can club the refreshes for x minutes, reducing your database trips. For example, say x = 3 minutes then all requests within 3 minutes will not modify last accessed time in database (there by reducing database trips). You can track last database update time in session state and in each request check against this value to see of database needs to be updated or not (i.e. current time > last database update + x then update last accessed value in database).
Third step (job) is optional because you may modify your check in #2 to see if login attempt is after n minutes (where n > session timeout) of last accessed time.
For the logic to check if user is already online, I may want to put it in the Global.asax Application_AcquireRequestState event since all pages is protected.