Can anyone suggest me the approach of implementing the live chat functionality in my ruby on rails application? Is there any plugin exists to implement this functionality?
Thanks
Yes, Juggernaut. Unfortunately it requires flash, but it works pretty well otherwise. You might also want to look at the WebSockets standard, as there is flash emulation for it in browsers that don't support it yet.
A very simple (possibly not very efficient) implementation would involve using AJAX to send new messages and receive conversation updates. The conversation could be a database backed object shared amongst the users involved. Each user's page would then poll for updates to that object.
Related
Background
I have a fairly typical Rails application, which uses Devise for authentication management. While building this app, I realized that realtime chat would be a great feature to have. Ideally, of course, this would make use of Websockets, in order to reduce the polling load on the server (as well as making it marginally easier to implement, as you don't have to manage polling).
I realized quickly that Ruby isn't really a great fit for having a large number of concurrent connections open at one time. Phoenix, however, is written in Elixir, so I can make use of the Erlang VM, which is quite good at long connections. It also seems like it could be greatly beneficial if all the chat data was stored separate from the main application database, which should also reduce load in the future.
The Problem
I want to be able to make this separation completely invisible to the user. They visit www.example.com/chat, and it loads all the relevant data in from chat.example.com and starts up the websockets, without requiring them to login to a separate service. I think using an <iframe> is probably the way to go about doing this.
My problem is sharing authentication and data between the two applications. The Rails app needs to be able to create conversations on the Phoenix app in response to certain events. The Phoenix app needs to know what user is currently authenticated into Rails, as well as general data about the user.
An OAuth flow with the Rails app as the ID provider seemed like a good fit at first, but I can't figure out a way for the Phoenix app to automatically be granted access. I also have some concerns about user records existing inside the Phoenix app—it should be aware of all users on the main application, so you can start a chat with a user even if they haven't ever opened chat.
What would be the best way to go about doing this? My intuition says that this is going to involve window.postMessage and some kind of token system, but I wanted to ask what the generally accepted way of doing this was before I accidentally created an insecure mess.
Sharing the session isn't too hard, assuming you are running at least Rails 4.1 and using JSON serialization (default for apps created with >=4.1). A quick google search finds PlugRailsCookieSessionStore, which accomplishes this.
For more information on what it takes to share a session between Rails and another language, Matt Aimonetti has an excellent blog post with detailed information.
Lastly, if you would prefer to stay entirely in Ruby, it's definitely doable. Ryan Stout discusses scalability around persistent connections in the FAQ for Volt, which uses a persistent connection for every user. The article he links is also a great read. Just mentioning it to help you weigh the trade off of building a separate app in another language.
I want to try to make a simple real-time chat Rails web app, but I thought I would need some kind of let's call it "event listener" to be able to keep track of sent messages so the receiver user's feed get updated with the new message. Also, for the Typing... notice box.
I hope I explained myself.
I guess I could do it in a very troglodyte way to achieve this like follows:
main.js:
while(true) {
$.get('/user-you-are-talking-to/are-there-new-messages', function(data) {
if (data['are_there_new_messages'] === true) {
$('#conversation').append(data['new_message']);
}
});
}
conversation_controller.rb:
# routed by /user-you-are-talking-to/are-there-new-messages'
def new_messages?
unless #new_messages.blank?
#json = []
#json[:are_there_new_messages] = #new_messages.count > 0
#json[:new_message]= #new_messages.shift
render json: #json
end
end
But well aside than the fact that I didn't test that code, a while loop and constant requests to the server seem like a really really bad idea, obviously.
I would like to know if Rails has a built-in feature like this, but as far as I know it doesn't, unlike frameworks I've worked with like Laravel. If there's not a built-in tool for this, how can I do this app?
Real time apps are usually done with websockets.
https://github.com/eventmachine/eventmachine
https://github.com/igrigorik/em-websocket
Or if on a hosted service you can use a publish/subscribe service such as Pusher or PubNub.
Otherwise, you would do polling which is what you have in your example.
Rails 5 will come with Action Cable:
Action Cable seamlessly integrates websockets with the rest of your Rails application. It allows for real-time features to be written in Ruby in the same style and form as the rest of your Rails application, while still being performant and scalable. It's a full-stack offering that provides both a client-side JavaScript framework and a server-side Ruby framework. You have access to your full domain model written with ActiveRecord or your ORM of choice.
But while you're waiting for it, you can use a number of existing solutions, some of which #dinomix listed.
Another option is Faye (never used, but heard good things).
So I want to be able to get a live stream of notifications for my users that are using my rails application. I heard that you are able to do this using web sockets but I haven't seen anything about it in rails.
Is there a way to do this in rails or am I able to use something else along side my application such as node.js ?
Okay I started searching for different terms and I was able to find Faye
This tutorial is great for it http://code.tutsplus.com/tutorials/how-to-use-faye-as-a-real-time-push-server-in-rails--net-22600
You can also use something like PubNub http://www.pubnub.com/
They support a good amount of languages/libraries such as AngularJS. Great customer service and documentation. Also many examples such as this one: http://www.pubnub.com/developers/data-streams/twitter-stream
We are planning to make a "large" website for I'd say 5000 up to many more users. We think of putting in lots of real time functionality, where data changes instantly propagate to all connected clients. New frameworks like Meteor and DerbyJS look really promising for this kind of stuff.
Now, I wonder if it is possible to do typical backend stuff like sending (bulk) emails, cleaning up the database, generating pdfs, etc. with those new frameworks. And in a way that is productive and doesn't suck. I also wonder how difficult it is to create complex forms with them. I got used to the convenient Rails view helpers and Ruby gems to handle those kind of things.
Meteor and DerbyJS are both quite new, so I do expect lots of functionality will be added in the near future. However, I also wonder if it might be a good idea to combine those frameworks with a "traditional" Rails app, that serves up certain complex pages which do not need realtime updates. And/or with a Rails or Sinatra app that provides an API to do the heavy backend processing. Those Rails apps could then access the same databases then the Meteor/DerbyJS app. Anyone thinks this is a good idea? Or rather not? Why?
It would be nice if anyone with sufficient experience with those new "single page app realtime" frameworks could comment on this. Where are they heading towards? Will they be able to handle "complete" web apps with authentication and backend processing? Will it be as productive/convenient to program with them as with Rails? Well, I guess no one can know that for sure yet ;-) Well, any thoughts, guesses and ideas are welcome!
For things like sending bulk emails and generating PDFs, Derby let's you simply use normal Node.js modules. npm now has over 10,000 packages, so there are packages for most things you might want to do on the server. Derby doesn't control your server, and it works on top of any normal Express server. You should probably stick with Node.js code as much as possible and not use Rails along with Derby. That is not to say that you can't send messages to a separate Rails app, but since you already have to have a Node.js app running to host Derby, you might as well use it for stuff like this.
To communicate with such server-side code, you can use Derby's model events. We are still exploring how this kind of code works and we don't have a lot of examples, but it is something that we will have a clear story around. We are building an app ourselves that communicates with an email server, so we should have some real experience with this pretty soon.
You can also just use a normal AJAX request or send a message over Socket.IO manually if you don't want to use the Derby model to do this kind of communication. You are free to make your own server-side only routes with Express along with your Derby app routes. We think it is nice to have this kind of flexibility in case there are any use cases that we didn't properly anticipate with the framework.
As far as creating forms goes, Derby has a very powerful templating system, and I am working on making it a lot better still. We are working on a new UI components feature that will make it possible to build libraries of self-contained UI widgets that can simply be dropped into a Derby app while still playing nicely with automatic view-model bindings and data syncing. Once this feature is completed, I think form component libraries will be written rather quickly.
We do expect to include all of the features needed for a normal app, much like Rails does. It won't look like Rails or work like Rails, but it will be similarly feature complete eventually.
For backend tasks (such as sending emails, cleaning up the database, generating pdfs) it's better to use resque or sidekiq
Now, I wonder if it is possible to do typical backend stuff like
sending (bulk) emails, cleaning up the database, generating pdfs, etc.
with those new frameworks. And in a way that is productive and doesn't
suck. I also wonder how difficult it is to create complex forms with
them. I got used to the convenient Rails view helpers and Ruby gems to
handle those kind of things.
Also, my question is not only about background jobs, but also about stuff one can might do during a request, like generating a pdf, or simply rendering complex views with rails helpers or code from gems. –
You're mixing metaphors here - a single page app is just a site where the content is loaded without doing a full page reload, be that a front end in pure js or you could use normal html and pjax.
The kind of things you are describing would be done in a background task regardless of the fornt-end framework you used. But +1 for sidekiq if you're using ruby.
As for notifying all the other users of things that have changed, you can look into using http://pusher.com or http://pubnub.com if you don't want to maintain a websocket server.
Does anyone know of a plugin or something that can be used to send bulk emails for a Rails app?
Specifically, I'd like to be able to pass an HTML email file to a rake task or something and have it emailed out to everyone who has signed up to my site and checked the "please send me info about XXX" box.
I wrote kind of a hacked-together version for myself, but I'd like something that throttles itself somewhat smartly and can pick up where it left off if interrupted.
Update: I eventually broke down and got out my credit card and signed up for a real bulk email service, and damn was that the right choice. The resulting emails are very professional, they have built-in analytics, also integrate with Google Analytics, and it's awesome for a ton of other reasons.
If you're looking to do bulk emails with Rails, I would suggest using the Mailchimp service (here's my affiliate link that has a bonus on signup) along with the hominid gem. This will allow you to sync all your user emails from your database to Mailchimp, then use a real bulk service instead of some crappy patched together one.
Another Update: I heard about Maktoub today, and it's pretty much exactly what I was describing. Disclaimer: I have never used it and would still probably steer clear and go with a paid service, but it's still probably better than rolling you own.
I couldn't find one so I wrote it myself. It's not pretty (at this stage), but should serve as a good starting point for anyone with similar needs.
Please send me a pull request if you make any beneficial changes and I'll make sure to give you credit.
Mailcar - Ruby on Rails mass / bulk email plugin
Update - I highly recommend using a service. Rolling your own is a real pain and it will be difficult to manage once your list becomes reasonably large at all.
I don't know that this is the kind of thing that can be covered by a plugin as there are whole sites/applications dedicated to this kind of thing. If you wanted to use one of those then there is www.campaignmonitor.com, it's pretty good and it has an api that you can hook into from your application.
You might want to take a look at postageapp.com
Not aware of any plugins for this and I don't know how rake could be used to do this, if at all.
Since you're using Rails, I assume you're using MySQL as your database so this may not be useful to you, but SQL Answers Mail for SQL Server sends bulk email directly from SQL Server. You could try searching for a tool that does something similar for the database you're using.
There's also a tutorial here and here on creating your own mailer.
use ActionMailer(tutorial) (docs), it comes with Rails and you should be able to rig it to run from a rake task.
There's a relatively new project called Maktoub which claims to be a Rails engine for email newsletters. I haven't tried it yet, but it looks promising.