#1 by DavidP
Dear all, I am considering an experiment that has a page live interaction, and where the server should do some computations in a regular interval (e.g. every 5 seconds) and then send the result to all players, as long as players are on this page. Is there any way to cleanly achieve this? I would like to avoid doing these computations client side. Within the means given in the documentation, the only way I can think of implementing this in a semi-stable way is (a) have the clients in javascript regularly ping the server (in a much higher frequency), and (b) the server then checking whether it's time for the next computation. Still not 100% happy, as it seems womewhat roundabout, and I am not sure whether there is any performance implication. Is there a more direct way, or is the proposed solution fine anyways? Thanks! David
#2
by
Chris_oTree
It's not available. But if oTree can get more grant funding this is the type of thing i would be happy to work on.
#3 by RudyDW
Hi David, I faced the same issue and implemented the same solution. Just be aware that the solution is not perfect since a client/participant may leave or his window may become inactive. In these cases, your server will not receive anything and will not thus be able to respond. Of course, you can have every participant pinging the server and the server responding to each one but this is not ideal. If a better solution is found, I would be happy to know about it. Rudy
#4 by DavidP
Hi Rudy, I haven't gotten around to implementing anything, but my thought is this: All clients ping the server regularly. Whenever such a ping arrives, the server checks whether it is time for the next calculation (by comparing current timestamp with one of the last calculation). If it is not time yet, the server does not react at all. If it is, the server updates the timestamp, does the calculation, sends the result to all clients, and then waits for pings again. Not ideal, and I'll have to think how to prevent potential race conditions when two clients ping at the very same time (perhaps anyone with web dev experience can chime in how of a troublesome window before the timestamp is updated should be expected?), but this seems like the only way to avoid relying on a single client, which I feel is even more troublesome. Cheers, David
#5 by RudyDW
Hi David, I fully understand. On my side, I may have 200 participants playing during a session and it becomes an issue to have all of them pinging the server every second. So, I would be very happy if oTree could provide with a tool allowing the server to send a message at regular intervals without any initial message from the client. Rudy
#6
by
ccrabbe
Hi Rudy and David - I haven't implemented this, but I think there could be a middle ground here, where you as the experimenter designate N (<<200) participants as "pingers" who will be the only ones who ping the server regularly. On the server-side, do as DavidP suggested and have it send an update to all participants when it receives a ping after an appropriate time interval. You could also have it keep track of the length of time since each "pinger" checked in - so if one of them disconnects or idles (detected by them not having sent a ping in however many seconds), you can include a new list of pingers in the next all-participant update to maintain your original size of pingers. I don't know precisely how big N needs to be (5? 10?) to function (but also not DDOS the server). Good luck! --Chris
#7 by RudyDW
Hi Chris, Thank you, Chris. Just after posting my answer to David, this idea came to my mind. N needs to be sufficiently large (10 or 15 is probably enough) to prevent all these N participants to leave the session or to have their 'oTree' windows not active during the same period. Thank you for your help. Rudy
#8 by ChristianK
I have implemented a slightly different approach: I calculate and show everything on the client side (in Javascript) first to have a continuously updating user interface. Only actions / transactions are sent to the server via web sockets / live pages. Whenever the server receives such an "update", it updates the server state. That is, I calculate the changes between the last time the state was updated and the current time. I then send the results back to the clients. The client updates its values if they deviate from what the client calculations showed (i.e. if there is drift in time keeping, loss of connection, page reload etc.). The client basically interpolates between updates from the server. This avoids constant pings of potentially hundreds of clients. You can also implement a minimum time between updates for group or submission level data this way and avoid redundant calculations and concurrent calculations in response to multiple clients. That said, I would love to have the ability to extend oTree with this functionality. In the old, Django-based, days, it was easy to add a background process via task queues. Unfortunately, most hooks into the deeper workings of oTree have been closed with the switch to oTree 5.