How do I trigger a real time client update in Rails - ruby-on-rails

I'm creating an online multiplayer board game using Rails, and I want the game to be able to be played without having to manually refresh the page. I'm planning on using websockets or Server Sent Events's to update the page. I haven't decided which yet, but I don't expect it to make a difference for my question.
The thing I'm confused about is knowing when to send an update to the client. For example, let's say I was making chess, and player1 took a turn. They would send up their move to the server, the server would then save it to the database. How does player2's websocket or SSE know to push the info about player1's move to player2's brower?
I know they could regularly query the database to see if the game has been updated, but that seems like it would be hard to scale since every user would be querying the database very often.
Is there an easy way to wait for an update to the database and be notified of it automatically somehow? Or are there other solutions?
I've looked around online a bunch for solutions to this, but haven't really gotten any concrete ideas. I'm definitely open to using a library or whatever to solve the problem as long as it's free. I've seen some paid solutions but those aren't an option.
I also saw someone suggest somehow using node.js alongside rails to do something with realtime. I don't know much about node.js, but I have heard it's good for asynchronous functionality like that. I'd be interested in learning how to use it if it's better than any rails solution.
I'm using Rails 3.2, but if Rails 4 has something that would work well here, I'd probably be interested in that as well.

As nik suggested, use the FAYE Ruby Server if you're a ruby developer.
In terms of how things could hang together:
Each game is a channel
Each player subscribes to this channel
When a player makes a move, the move is sent to the server
The server saves the move against the game in the db
The server sends a message to the channel.
Both player's ui update with the new move.
This setup allows you to easily replay a whole game or continue where you left off. Just get all moves from db and send them in order to a new channel. This might not be performant, but it should work.

you can also use FAYE which has Ruby Server and Node.js server, you can choose one

Related

django channels and running event loop

For a game website, I want a player to contest either agains a human or an AI.
I am using Django + Channels (Django-4.0.2 asgiref-3.5.0 channels-3.0.4)
This is a long way of learning...
Human vs Human: the game take place is the web browser turn by turn. Each time a player connects, it opens a websocket connexion, a move is sent through the socket, processed by the consumer (validated and saved in the database) and sent to the other player.
It is managed only with sync programming.
Human vs AI: I try to use the same route as previously. A test branch check if the game is against the computer and process a move instead of receiving it from the other end of the websocket. This AI move can be a blocking operation as it can take from 2 to 5sec.
I don't want the receive method of the consumer to wait for the AI to return its move, since I have other operations to do quickly (like update some informations on the client side).
Then I thought I could easily take advantage of the allegedly already existing event loop of the channels framework. I could send the AI thinking process to this loop and return the result later to the client through the send method of the consumer.
However, when I write:
loop = asyncio.get_event_loop()
loop.create_task(my_AI_thinking())
Django raises a runtime effort error (the same as described here: https://github.com/django/asgiref/issues/278) telling me there is no running event loop.
The solution seemed to be to upgrade asgiref to 3.5.0 which I did but issue not solved.
I think I am a little bit short of background, and some enlightments should help me to understand a little bit more what is the root cause of this fail.
My first questions would be:
In the combo django + channels + asgi: which is in charge to run the eventloop?
How to check if indeed one event loop is running whatever the thread?
Maybe your answers wil raise other questions.
Did you try running your event_loop example on Django 3.2? (and/or with different Python version)? I experienced various problems with Django 4.0 & Python 3.10, so I keep with Django 3.2 and Python3.7/3.8/3.9 for now, maybe your errors are one of these problems?
If you won't be able to get event_loop running, I see two possible alternative solutions:
Open two WS connections: one only for the moves, and the other for all the other stuff, such as updating information on Player's UI, etc.
You can also use multiprocessing to "manually" send calculating AI move to other thread, and then join the two threads again, after receiving the result (the move). To be honest, multiprocessing in Python is quite simple -- it's pretty handy, if you are familiar with the idea of multithreaded applications.
Unfortunately, I have not yet used event loops in channels myself, maybe someone more experienced in that matter will be able to better address your issue.

WoW Lua - Get Data from URL (Vanilla)

In a World of Warcraft Vanilla Lua Addon Development, how can I issue an HTTP call to receive data back? If not, how can I get data from a web source into the game while playing?
I have a feeling the answer is tragically short, but would like the question asked and answered on Stack Overflow. My research came up lacking, and I recall doing some LUA in ~2007 and was disappointed.
Well, tragically short is an understatement. You simply can't. There was never any APIs that interacted directly with connections, let alone create any, let alone to arbitrary URLs.
Most of them just broadcast game events that occur from the game's connection, and the closest thing you can get to a "data stream" is add-on chat channels. But since bots violate the ToS, you wouldn't be able to make an account that responds to your addon's inquiries.
The closest thing you can get is building an "asynchronous mesh network", but that's only good if your addon has a considerable user base, and it's not guaranteed you'll get information timely.
The general idea is that your addon will have a public key (as in encryption), and you (only you) will detain a private key. Your addon emits a message to any connected peers, which store it on cross-realm SavedVariables, and you hope that someone will have characters on more than one realm. Upon login, the client addon will broadcast its latest packet (still encrypted) to that realm's addon channel, and hopefully within a week or so you might get the updated information across all clients.
A disadvantage is that you'll only get "push" notifications, the client won't be able to send any data back to you*.
That, or you could release a patch for the addon on Curse :P
BUT WAIT!
You mention vanilla, so I can presume you're developing this for a private server. Private servers often have one or a very small amount of realms, making the above mesh network much simpler. Instead of a mesh, just have encryption and manually login&broadcast on each realm every time you want to update the information retrieved.
Plus, you might even be able to contact the server devs to allow you an API that sends messages to the appropriate ingame addon channel (you'd have to ask).
Of course, if you pretend to make your addon server-agnostic, instead of tailored to a specific server, you're back to square one.
 * Unless you are really dedicated to make that happen, because it's a ton of work.
There is no web API in vanilla WoW. There is a web browser widget in the game currently though, albeit very limited in usage.
If you have access to the server software code, you may be able to hook listening on specific game channels for user messages in a defined format, and let the server respond in a way for the addon to parse it.

Iphone app that needs to scrape a website once every day

So I'm making an iphone application that needs to scrape a website once everyday.
What I'm going to scrape is a table of upcoming games for that same day for a soccer division. Thats why i need the app to scrape from the same page and same table once everyday to keep the upcoming games updated.
I was referred to import.io but they didn't have something like a schedule re-crawl.
I would love to get some ideas and tips to how i should do this since I'm stuck now.
You might take a look at https://www.kimonolabs.com/
I played around with the service a while back and was impressed with how easy it way to set up. They have a "free" option so long as the APIs you create are not private.
Oh, and I agree with Paul, screen scraping is not something the iOS client should be doing. Too fragile, and when (not if) something breaks, you will need to go through an Apple review process to fix it.
This doesn't seem like something an app should do, your server should do it (so that the scraping is only performed once), and your clients can retrieve it from your server. That also means you could send out push notifications for important fixtures etc. Maybe that's what you meant, anyway.
If it's on the server you can just setup a scheduler (in Java, for example) to run once every x hours (probably a smaller number than 24 assuming you don't know when the website is to be updated). Then your app can just get the latest list of fixtures from your server on startup, pull-to-refresh, etc. Presumably someone will open your app, look at the fixtures, then come out of your app - so it doesn't seem like you need to cover the case where someone is in your app all day, but if you did you could use NSTimer to run every x minutes after the initial on-startup server call.

opening and closing streaming clients for specific durations

I'd like to infrequently open a Twitter streaming connection with TweetStream and listen for new statuses for about an hour.
How should I go about opening the connection, keeping it open for an hour, and then closing it gracefully?
Normally for background processes I would use Resque or Sidekiq, but from my understanding those are for completing tasks as quickly as possible, not chilling and keeping a connection open.
I thought about using a global variable like $twitter_client but that wouldn't horizontally scale.
I also thought about building a second application that runs on one box to handle this functionality, but that seems excessive if it can be integrated into the main app somehow.
To clarify, I have no trouble starting a process, capturing tweets, and using them appropriately. I'm just not sure what I should be starting. A new app? A daemon of some sort?
I've never encountered a problem like this, and am completely lost. Any direction would be much appreciated!
Although not a direct fix, this is what I would look at:
Time
You're working with time, so I'd look at what time-centric processes could be used to induce the connection for an hour
Specifically, I'd look at running a some sort of job on the server, which you could fire at specific times (programmatically if required), to open & close the connection. I only have experience with resque, but as you say, it's probably not up to the job. If I find any better solutions, I'll certainly update the answer
Storage
Once you've connected to TweetStream, you'll want to look at how you can capture the tweets for that time period. It seems a waste to create a data table just for the job, so I'd be inclined to use something like Redis to store the tweets that you need
This can then be used to output the tweets you need, allowing you to simulate storing / capturing them, but then delete them after the hour-window has passed
Delivery
I don't know what context you're using this feature in, so I'll just give you as generic process idea as possible
To display the tweets, I'd personally create some sort of record in the DB to show the time you're pinging TweetStream that day (if it changes; if it's constant, just set a constant in an initializer), and then just include some logic to try and get the tweets from Redis. If you're able to collect them, show them as you wish, else don't print anything
Hope that gives you a broader spectrum of ideas?

iOS notification and server cheking

I'm making a program for IOS for the first time. I never had a iPhone so I don't really get how it works...
I want to make my system able to call a webservice on the background and depending in the answer show a notification.
How can I do this?
I read on the Internet that I can push notifications to the phone, however that won't solve my problem because I want my server to track the user position, so it need the user to silently tell the server it's gps coordinates.
Thank you,
GustDD
I will suggest building the app first to run in the foreground. I will assume you already understand how to use the GPS, so will not go into detail on that.
First off, you will need to write the server backend and app pretty much simultaneously. There are many choices for writing the server backend language wise. I prefer python, others ruby on rails. You want to build a REST API for the server that the iDevice can talk to with simple HTTP protocol.
You must decide on the API. You must think about what kind of data you will want to send and receive and how you will wrap the data. Also what HTTP protocols will you be using for specific requests, like GET POST etc. Furthermore, you will have to decide at what URL's on the server will it be useful to GET or POST to depending on the data you want to send or receive. I would suggest you use JSON to wrap your data. It is quite intuitive and easy to encode and decode.
Next you will have to decide how to talk to the server in iOS. There are many great third party libraries that dress up NSURLConnection or you can use NSURLConnection itself (sometimes a bit tedious). I personally like to use AFNetworking. It will do the JSON decoding and encoding for you which is a big bonus.
Finally, once you have the two communicating with how you want and with the data you want, now time to dress it up. You can allow your app to run in the background and collect GPS data and send it. You can also use the notification center to display information it gets from the server in the background.
Update to Comment
This will be extremely helpful for you with background programming. From an Android perspective, iOS is a little bit different since there is not really a direct correlation for Android services in iOS. Every little detail to put your project together is in that link.

Resources