Reputation: 2551
So I'm creating a basic jackpot betting site for fun and it allows users to put money into a pot and then based on the percentage of money each user puts in it randomly picks a winner. It's working fine at the moment but I feel like the way I'm updating the jackpot page with ajax is really bad. At the moment I have javascript that makes an ajax request each second to get the pot info (size of the pot, players, etc..). I feel like there is a much better way to do this. Is it possible to only make an ajax call when the database is updated? Thanks!
My javascript at the moment:
setInterval(update, 1000);
function update() {
getPotID();
$.ajax({
type: "POST",
url: "/jackpot/update/" + potID,
complete: function(response) {
$('.live-jackpot').html(response.responseText);
getPotInfo();
},
error: function(xhr, status,error) {
console.log("Error");
}
});
}
Upvotes: 1
Views: 523
Reputation: 5942
as said from 7urkm3n, ActionCable has great advantage for this functionality.
Right now you are writing Javascript code that is executed on the client side. Every user that will start a GET
http request to your site, will load that javascript files. They will start performing POST
request every second to your backend server.
ActionCable is a websocket preinstalled in Rails 5. This means that to configure the notifications with ActionCable and Rails 5, you already have installed everything in your app (if you are using rails 5), you just need to install Redis on your local machine for testing the app in development.
I am not an expert, my understanding is that you use a specific database called redis to store the information about the subscription. I quote a useful article
So PubSub is this concept that Redis and Postgres and a few other things supports, and basically you have this ability to have Channels and the ability to subscribe (and receive those messages) and publish to those channels and anyone listening will then receive those messages.
An example of this is a ChatroomChannel, you could have people publishing messages to the ChatroomChannel and anyone who was subscribed to the ChatroomChannel would receive the broadcast from the channel with the websocket.
This is something you are missing, this way you could only find which users are actually on the playing page and which users are just browsing around, based on this ActionCable
creates a channel
to communicate between server
and client
and then creates a subscription
to distinguish users that are actually on the playing page and those that left and should not be anymore notified
I quote another useful article
Before we dive into some code, let's take a closer look at how Action Cable opens and maintains the WebSocket connection inside our Rails 5 application.
Action Cable uses the Rack socket hijacking API to take over control of connections from the application server.
For every instance of your application that spins up, an instance of Action Cable is created, using Rack to open and maintain a persistent connection, and using a channel mounted on a sub-URI of your main application to stream from certain areas of your application and broadcast to other areas.
so every user that connects, ActionCable
creates a channel that uses a specific url localhost:3000/cable
to communicate between server
and client
(browser)
Action Cable offers server-side code to broadcast certain content (think new messages or notifications) over the channel, to a subscriber. The subscriber is instantiated on the client-side with a handy JavaScript function that uses jQuery to append new content to the DOM.
This means that the server can call the client with parameters and change the page with jquery
functions. For ex. appending a div, with a new message.
In my app https://sprachspiel.xyz I do the following in the MessagesController#create
ActionCable.server.broadcast 'messages',
message: message.content,
user: message.user.name,
chatroom_id: message.chatroom_id,
lastuser: chatroom.messages.last(2)[0].user.name
head :ok
so basically, I have my message
in my controller and I can update the client by using the ActionCable.server.broadcast
function
then in my asset pipeline file /app/assets/javascripts/channels/messages.js
I have the following code that trigger the change in the browser adding the message
App.messages = App.cable.subscriptions.create('MessagesChannel', {
received: function(data) {
$('#messages').append(this.renderMessage(data));
},
renderMessage: function(data) {
return "<br><p> <strong>" + data.user + ": </strong>" + data.message + "</p>";
}
});
I build an app called https://sprachspiel.xyz that is an actioncable app, this is the github page for the project, on my portfolio you can read more info about my app, so please ask me anything, I'll be happy to look into it!
Good luck Fabrizio
Upvotes: 1