List

RailsConf 2013 Real-Time Rails

RailsConf 2013 Real-Time Rails

by Brian Cardarella

In the RailsConf 2013 presentation titled "Real-Time Rails," Brian Cardarella discusses integrating real-time functionality into Rails applications with the introduction of the Rails 4.0 Live Streaming API. The talk highlights the importance of real-time features in modern web applications and compares the advantages of using Rails with pivotal technologies such as Node.js and EventMachine. Cardarella provides a brief history of the evolution of software technologies to illustrate how complacency in established frameworks can lead to innovative opportunities for newcomers like Node.js.

Key points addressed in the talk include:
- The Evolution of Technology: A light-hearted history of how major players such as IBM, Microsoft, Java, Rails, and Node have competed and evolved.

- Real-Time Functionality: The discussion centers around how Node.js has outpaced Rails in real-time features, emphasizing the importance of handling concurrent requests effectively.

- Concurrency in Rails: By adopting web servers like Puma, Rails 4 can handle multiple requests more efficiently. Advanced Rails developers must understand threading, deadlocks, and race conditions.

- WebSockets and Server-Sent Events: Cardarella covers the implementation of WebSockets for two-way communication and Server-Sent Events (SSE) for one-way communication, demonstrating how these can be set up using Action Controller Live in Rails.

- Practical Examples: He provides demonstrations of real-time chat and drawing applications, showcasing how events are captured and processed. Moreover, libraries like TubeSock simplify WebSocket handling in Rails.

- Challenges and Future of Real-Time Rails: The presentation discusses the limitations of current infrastructure, like Heroku's support for WebSockets, and highlights the need for API advancements.

The conclusion emphasizes that as developers adopt these real-time capabilities in Rails, they will find it possible to build highly responsive applications, thereby enriching user experiences and opening the door to innovative development in future iterations of Rails. Overall, Cardarella inspires developers to explore and embrace the real-time capabilities with the evolving Rails framework.

The future is real time! With the Rails 4.0 Live Streaming API we finally have the ability to easily add real time functionality to our apps. Learn all about the live streaming API, how best to take advantage of this in the browser, and how to deploy a real-time ready Rails app. Get ready to open your apps to a whole new world of interaction and functionality. Topics we will cover:
* Live Streaming API
* EventMachine vs Rails 4.0
* Node.js vs Rails 4.0
* Polling vs Live Streaming
* Websockets & Rails 4.0
* Puma

Help us caption & translate this video!

http://amara.org/v/FGb4/

Rails Conf 2013

00:00:16.480 um hi my name is brian cartarella
00:00:19.359 and my presentation is uh on doing real
00:00:23.199 time or reelish time in rails
00:00:26.640 just some quick self-promotion bs first
00:00:29.279 so i'm the owner of a consultancy in
00:00:31.679 boston called dockyard
00:00:35.600 we do rails postgrads but we've also
00:00:37.280 been doing a lot of mr.js lately in
00:00:38.960 brazil
00:00:40.559 and also
00:00:42.640 we're organizing uh wiki good ruby conf
00:00:44.719 in boston we're looking for speakers
00:00:46.320 we're looking for people to buy tickets
00:00:47.840 so this is boston's first re-conference
00:00:50.000 it's gonna be october um if people are
00:00:52.079 interested in coming to the city please
00:00:53.440 check it out
00:00:56.559 okay so that's a little s
00:00:58.399 can i do this
00:01:00.079 that's better okay so we're gonna start
00:01:01.680 with a history of popular software
00:01:05.119 oops
00:01:06.640 uh a
00:01:08.080 barely accurate history of popular
00:01:09.920 software to make a point this is going
00:01:11.119 to be really bad
00:01:12.720 first we started out with ibm ibm owned
00:01:15.119 the landscape they had everything they
00:01:17.759 you know they were the monopoly that was
00:01:19.920 around
00:01:21.119 and then a little guy microsoft came
00:01:23.040 around said hey ibm you guys are selling
00:01:25.439 the hardware
00:01:26.560 why don't you let us sell the software
00:01:28.400 and ibm's like sell the software that's
00:01:30.320 crazy no one's going to buy that okay go
00:01:32.720 ahead you can do it
00:01:35.439 then i microsoft became very good
00:01:39.119 uh and then microsoft's sitting there
00:01:41.119 they're doing well and then java came
00:01:42.240 along java's like hey yo i'm gonna you
00:01:44.640 guys are selling the software we're just
00:01:45.840 gonna give it away
00:01:47.280 and
00:01:48.399 microsoft's like give it away for free
00:01:50.159 that's crazy go ahead that's fine
00:01:53.600 and then java did very well they you
00:01:55.520 know multiplied many different versions
00:01:57.360 of java came out you can tell how cool
00:01:59.040 java is because the one the middle has a
00:02:01.200 beeper on his belt and he's got hair
00:02:02.640 plugs
00:02:05.520 and then this little guy called rails
00:02:07.439 came along and said hey
00:02:09.360 we're going to take this language called
00:02:10.640 ruby and we're going to run scripting
00:02:12.400 language on the server
00:02:14.160 and java is like scripting language on
00:02:15.920 the server that's crazy no one's going
00:02:17.760 to buy into that
00:02:20.000 and as we all know rails became rock
00:02:22.160 stars and ninjas and
00:02:24.000 all that good stuff
00:02:27.599 and then finally node came along and
00:02:29.360 node said
00:02:30.720 we're going to run javascript on the
00:02:32.080 server
00:02:34.239 and rails is like javascript on the
00:02:36.080 server that's crazy no one's going to do
00:02:38.160 that okay go ahead
00:02:40.319 but now we know that
00:02:42.000 node has done pretty well and
00:02:49.200 and it lets us know about it quite a bit
00:02:53.680 so the point here is
00:02:55.680 not so much historical accuracy or
00:02:59.040 any relevance beyond this talk but more
00:03:00.800 about how um when uh technology or
00:03:04.159 business becomes complacent and fat and
00:03:06.000 happy and where it's sitting um
00:03:08.720 there's opportunity for other people to
00:03:10.319 kind of swoop in and pick up market
00:03:12.800 share or mind share and that's really
00:03:14.640 what's happened um in the past few years
00:03:17.040 with with node and rails
00:03:18.959 um
00:03:20.480 so
00:03:24.159 uh real time is just one of the areas
00:03:26.080 that node has outpaced rails um
00:03:29.440 it some of the other places might be
00:03:32.400 i don't think the metrics are really
00:03:33.599 that interesting people may claim that
00:03:36.159 uh like npm has
00:03:38.480 like five times as many packages as ruby
00:03:40.480 gyms and
00:03:42.159 i mean that's a better indicator that's
00:03:43.840 easier to build those those packages
00:03:45.760 than it is that those packages really
00:03:47.040 worth anything
00:03:49.360 the other metric i hear a lot is that
00:03:51.360 node naturally has way more developers
00:03:53.680 than rails does
00:03:56.400 i mean yes there are developers because
00:03:58.319 javascript is the only language on the
00:03:59.840 browser
00:04:00.879 that is going to mean that people are
00:04:02.480 going to be somewhat comfortable with
00:04:04.319 the language on the server but
00:04:06.560 the problems you're solving on the
00:04:08.159 server are very different than the
00:04:09.760 problems you're solving on the browser
00:04:11.599 the language is at that point the
00:04:14.640 smallest barrier of entry for solving
00:04:16.639 those problems
00:04:17.840 in fact i think the problems are
00:04:18.880 language agnostic especially the big
00:04:20.479 ones
00:04:24.240 for a long time reals was the innovator
00:04:26.000 and because of
00:04:28.759 a lot of the work that's been going on
00:04:31.440 for the past few years with uh first the
00:04:33.600 merb merge
00:04:35.040 and it seems like
00:04:36.800 stuff that's been happening lately is
00:04:38.240 more
00:04:39.199 um
00:04:40.160 like organization of your applications
00:04:42.479 rather than saying hey we're going to go
00:04:44.880 and really kind of
00:04:46.800 uh
00:04:47.759 forge the path in this new direction uh
00:04:50.479 the node has been really hitting that
00:04:52.000 hitting that point pretty well
00:04:54.000 so can rail scale its features
00:04:57.919 um
00:04:59.199 we're going to take a step back and talk
00:05:00.960 about kind of a primer on what i'll get
00:05:03.040 to later it's interesting that this is i
00:05:05.440 mean there's a lot of people in this
00:05:06.400 room so there's going to be a
00:05:08.000 whole
00:05:08.840 wide span of uh of abilities here and
00:05:12.639 for the more advanced people they can
00:05:14.000 probably just tune out for the next few
00:05:15.120 slides we're going to talk about sockets
00:05:16.639 because even though rails devs
00:05:18.320 especially some advanced rails devs
00:05:20.800 they legitimate
00:05:22.400 advanced developers for rails they may
00:05:24.639 not have experience doing some of the
00:05:26.240 stuff i'll be talking about because they
00:05:27.520 just haven't touched on it before
00:05:30.800 so um
00:05:32.479 beyond my slides because my slides will
00:05:34.160 only be good enough for me getting
00:05:35.759 through the rest of the slides towards
00:05:36.880 the end i highly recommend this book
00:05:38.880 here working with tcp sockets by jesse
00:05:41.199 storeremer
00:05:42.960 it's awesome
00:05:44.080 i don't think it's that much money
00:05:45.199 either i think it's like 10 bucks or 15
00:05:47.199 bucks or something like that here's
00:05:48.080 another book too
00:05:50.080 i think it's like called ruby and unix
00:05:51.840 or something like that that's also very
00:05:53.120 very good
00:05:54.960 so the basics of the sockets for the
00:05:56.639 purposes of um
00:05:58.560 the websockets i'll get into later is
00:06:00.400 that you have to know that data when you
00:06:02.160 send it from your client is broken down
00:06:04.000 into frames those frames are then broken
00:06:06.080 down the packets the packets then travel
00:06:08.080 on the center ted steven tubes to the uh
00:06:10.800 to the server and then the packets are
00:06:12.800 constructed into frames and the data is
00:06:14.319 read from the frames
00:06:18.080 um
00:06:19.120 what we're really after here
00:06:20.960 on on a lot of levels is this idea of
00:06:23.759 concurrency
00:06:25.360 and we want to have um
00:06:27.919 not just real time not just having data
00:06:30.400 pushed to our servers very quickly but
00:06:32.160 we also want to be able to have our
00:06:33.919 servers handling many many transactions
00:06:36.080 at the same time many many requests at
00:06:37.680 the same time
00:06:39.520 so
00:06:40.319 uh the concurrent web servers that are
00:06:42.000 out there that are available i'm sure a
00:06:43.440 lot of people have seen already puma
00:06:44.880 rainbows thin
00:06:46.479 i like puma a lot the the reason is puma
00:06:50.160 i think is the smartest about how it
00:06:51.840 handles its memory uh there's a graph on
00:06:54.080 the puma io website that you know shows
00:06:56.479 puma is doing way better than anything
00:06:58.400 everything else i don't know how
00:06:59.520 accurate that information is but if we
00:07:01.599 take that somewhere in the ballpark the
00:07:03.360 way it works is puma
00:07:05.680 will actually thread
00:07:08.160 its processes so rather than forking the
00:07:11.039 process which just does a flat memory
00:07:13.039 copy it'll just use ruby threads and so
00:07:15.840 it ends up being less costly
00:07:20.080 so in rails 4
00:07:21.759 this is a quote from nick gothier
00:07:24.160 i got a few things in here from him
00:07:26.400 rails 4 is now fully concurrent there is
00:07:28.639 no full stack lock on your request if
00:07:30.639 you use a concurrent server like puma
00:07:32.800 you can handle mana requests at this
00:07:35.360 with a single process
00:07:37.199 so that is
00:07:41.759 and inside
00:07:44.720 when we're working with websockets we're
00:07:46.479 working with
00:07:48.319 server sent events we're going to want
00:07:50.400 to get used to working with frets and
00:07:52.160 this is going to be a whole new world
00:07:53.680 for a lot of ruby developers as well
00:07:56.960 you'll have to learn how to write good
00:07:58.639 threaded code that means observing
00:08:00.400 thread safety practices being aware of
00:08:01.919 deadlocks being aware of
00:08:04.000 race conditions
00:08:07.680 simple example
00:08:09.599 this here could produce a race condition
00:08:11.520 so we're going to say hey we're going to
00:08:13.520 create a new thread we're going to
00:08:14.560 iterate this through 100 times put out
00:08:16.479 here and then at the end here we're
00:08:18.319 going to say over here too but we don't
00:08:20.720 really have any guarantee which one's
00:08:22.160 going to happen first so let's see a
00:08:24.000 more complex example this is an example
00:08:26.800 from an application that we wrote we
00:08:29.280 have some you can think of it like chat
00:08:30.720 roulette almost we have several rooms
00:08:32.479 each room can only hold two visitors
00:08:35.039 visitors are assigned to a room as they
00:08:36.719 join and when a room fills the next
00:08:39.120 visitor is assigned to the next
00:08:40.560 available room
00:08:42.159 so i want to demonstrate this if you
00:08:44.399 guys will indulge me with some audience
00:08:46.480 participation
00:08:48.000 so i'm going to need
00:08:49.839 can i just get these guys you guys set
00:08:51.519 up front so you're gonna
00:08:53.200 i'm gonna recruit you guys in so i need
00:08:55.839 about
00:08:56.800 give me four people
00:09:02.640 okay so
00:09:04.640 imagine if you will that there is an
00:09:06.880 imagine that there is a pretend room
00:09:08.320 where there only holds
00:09:10.560 two people so you're gonna be one two
00:09:12.240 three four these requests are coming in
00:09:14.240 okay number one how many people are in
00:09:15.760 the room
00:09:17.200 no not that room the room
00:09:19.440 the pretend room to your right zero
00:09:22.399 people okay so you can go in because
00:09:24.000 there's less than two people go go go
00:09:25.600 ahead
00:09:26.399 all right um go a little bit further
00:09:28.640 all right
00:09:29.760 all right now
00:09:31.279 uh number two
00:09:33.279 um how many people are in that room okay
00:09:36.160 now number three how many people are in
00:09:37.600 that room
00:09:38.560 all right now you both try to join at
00:09:40.000 the same time because you got two
00:09:41.680 requests coming in
00:09:43.519 and now we got
00:09:44.959 a problem
00:09:46.080 so
00:09:47.920 this is where thread safety comes into
00:09:49.680 play and a
00:09:51.680 simple fix for thread safety is to
00:09:53.680 introduce some sort of cue so you can
00:09:55.839 while your requests are still coming in
00:09:58.959 concurrently you're handling a lot of
00:10:00.399 other things concurrently when you need
00:10:02.000 to
00:10:02.720 actually make certain parts of your
00:10:04.399 application thread safe you can
00:10:05.440 introduce their queue so i want you guys
00:10:07.120 head back in this direction
00:10:10.880 all right so now number one how many i
00:10:13.360 actually i don't know if i need you
00:10:14.480 sorry
00:10:16.640 i just yeah yeah we'll see
00:10:18.720 number one how many people in the room
00:10:20.079 zero all right zero you go you go over
00:10:21.920 there
00:10:22.959 number two how many people in the room
00:10:25.040 all right number two you go into the
00:10:26.720 queue
00:10:28.399 and
00:10:29.440 now number number uh three you know you
00:10:32.079 go and i'm sorry i messed up sorry
00:10:33.839 number two you come back
00:10:35.760 sorry sorry sorry
00:10:37.760 okay number two you head into the queue
00:10:40.640 number three you head into the queue
00:10:42.640 you gotta go behind him it's a queue
00:10:45.680 all right
00:10:48.320 number four aren't you going to queue
00:10:49.519 too just for the hell of it
00:10:52.240 all right so now you're at the front of
00:10:53.279 the queue we're going to process you
00:10:54.320 because you're a job all right now now
00:10:56.320 job how many people are in the room
00:10:58.480 okay now you can go in because we're
00:11:00.079 handling you one at a time number three
00:11:02.000 how many people in the room okay now we
00:11:04.000 need to create a new room so that new
00:11:05.360 room is gonna be over here and number
00:11:07.200 four how many people are in that room to
00:11:08.800 your right
00:11:10.240 two so you gotta come over here so that
00:11:12.000 that's a pretty simple
00:11:14.399 very uh
00:11:16.320 easy way to handle thread safety and it
00:11:18.320 works well for the presentation because
00:11:19.519 i get to kill some time all right thank
00:11:21.120 you guys
00:11:27.279 um if you are working with a single ruby
00:11:30.320 process you have um
00:11:32.560 a rather a single ruby server
00:11:34.880 inside the mutex class you have a
00:11:36.560 synchronous a synchronized instance
00:11:38.560 method
00:11:39.519 um
00:11:40.720 you just create a new mutex object and
00:11:42.800 this synchronizes it can work as a queue
00:11:45.200 for you so if you don't have that then
00:11:47.839 you can work with some sort of external
00:11:49.920 job processor
00:11:53.760 inside the world of concurrency pub sub
00:11:56.320 is going to be your best friend um
00:11:58.880 you will be relying upon it quite a bit
00:12:01.839 there are the bottom two are probably
00:12:04.079 the more popular ones for those that
00:12:05.440 don't know postgres has pub sub in it
00:12:07.920 and i like talking about postgrads
00:12:09.200 because postgres is awesome um it's
00:12:11.519 called notify listen instead the pg gem
00:12:13.680 does have access to to this
00:12:16.320 um
00:12:17.040 redis is probably the easiest xero mq is
00:12:20.240 uh when i understand the fastest but i
00:12:22.079 actually have not used it
00:12:25.600 so
00:12:27.440 for for rails
00:12:30.240 the way we've been kind of accomplishing
00:12:32.720 doing this right now is really to go
00:12:34.959 outside of rails
00:12:37.680 you could create a server
00:12:39.760 another app server that sits right next
00:12:41.680 to rails with either event machine or
00:12:43.279 celluloid event machine has an em
00:12:44.800 websockets
00:12:46.160 uh plugin
00:12:48.079 we've done that
00:12:49.200 i haven't used celluloid but it seems to
00:12:50.959 be where people in the event machine
00:12:52.079 world are moving towards
00:12:53.760 or you can use an outside service like
00:12:55.600 fey or pusher and
00:12:58.079 let that handle handle everything and
00:13:00.000 push it back to rails or push it back to
00:13:02.000 the client
00:13:03.920 the other option is i mean the the
00:13:06.800 people using your your apps they don't
00:13:08.800 really know what's under the hood so as
00:13:11.120 long as something feels real time-ish
00:13:12.959 that might be good enough and for a long
00:13:14.959 time everyone's been a lot of people
00:13:16.560 been using long polling
00:13:18.160 and for those unfamiliar with that this
00:13:19.680 is the gist you make a asynchronous
00:13:21.920 request to your server uh you might give
00:13:24.720 back you might give the last time you
00:13:26.320 made this request so you can just get a
00:13:27.839 delta of your data um and then when it's
00:13:30.079 done it will then uh set the timeout and
00:13:32.480 re-pull again so it's kind of an
00:13:33.839 infinite loop that just keeps going over
00:13:35.200 and over again and then we'll populate
00:13:36.800 with data
00:13:39.440 so in rails four
00:13:41.440 there's been introduced this concept
00:13:43.519 of a
00:13:44.399 rails metal called action controller
00:13:46.000 live
00:13:47.120 action controller live
00:13:49.200 is a proxy object for the socket it's
00:13:51.200 exposed by doing response dot socket
00:13:54.480 and
00:13:56.160 it doesn't i mean anything in rails
00:13:57.519 allows to control the headers that's not
00:13:58.880 right
00:14:00.000 but what you will want to do is modify
00:14:02.240 your headers based upon the type of your
00:14:04.000 response that you're giving back
00:14:08.399 this would be the api endpoint that you
00:14:10.480 would see for the long pulling and here
00:14:13.199 we're just again using the delta on the
00:14:15.600 chat model and getting the history from
00:14:17.199 it and responding with json
00:14:19.680 this might be something that you would
00:14:20.880 see with action controller live you're
00:14:22.320 mixing in the module
00:14:24.240 and then you may or may not be using a
00:14:25.839 thread here and handing it off to some
00:14:27.839 sort of service to process the stream
00:14:30.959 everything out
00:14:34.000 um on android patterson's blog tenor
00:14:36.160 love making he talked about
00:14:39.600 the action controller live stuff
00:14:41.839 the most important quote i think rather
00:14:44.320 is that the stream object is meant to
00:14:46.240 quack like an i o object which means
00:14:47.760 that
00:14:48.480 if you're familiar with using files and
00:14:50.560 such in ruby it's going to be somewhat
00:14:52.000 similar you have the right method you
00:14:53.279 have the close method and you're going
00:14:54.399 to have a read method as well so this
00:14:56.240 shouldn't be too different from what
00:14:58.000 you've done before
00:15:01.519 so now we're starting to get into more
00:15:02.639 interesting things
00:15:04.240 server sent events
00:15:08.160 it allows for one-way communication from
00:15:10.000 your server to the client these are part
00:15:12.560 of the html5 spec and they're pretty
00:15:14.399 easy to build
00:15:16.000 so here is something else i stole from
00:15:17.920 aaron's blog
00:15:20.639 we are setting the response that should
00:15:23.360 be easy to see we're setting the
00:15:25.120 response header to text event stream
00:15:27.600 this tells um our client that the uh
00:15:31.920 the response is coming back as an event
00:15:33.839 in response
00:15:35.199 and then the event itself is going to be
00:15:37.760 written as a key value pair
00:15:40.720 that has multiple lines they're split by
00:15:42.959 new lines and then each event is split
00:15:44.800 by a double new line
00:15:46.639 in this example we are
00:15:49.519 writing back a time event
00:15:51.759 and we are streaming back the time.now
00:15:54.800 data
00:15:56.000 um
00:15:58.160 you can also include an id
00:16:00.720 so if your client becomes disconnected
00:16:03.120 from the server for some reason
00:16:04.959 you will repurpose that id so that the
00:16:07.040 client can pick up where last left off
00:16:10.160 on the bottom
00:16:11.440 code we're using the event source object
00:16:14.160 which is
00:16:15.600 how you're creating events
00:16:17.199 or listening for events on on the
00:16:19.040 browser
00:16:20.160 and then we add an event listener and we
00:16:21.920 give it the event of time because that's
00:16:23.120 the one we're interested in and the
00:16:24.399 callback here will allow us to handle
00:16:25.839 the event in some fashion
00:16:27.680 so i will just demo this pretty quick oh
00:16:30.000 that's tiny
00:16:34.959 um let's see here
00:16:39.360 this will work okay so i mean it's not
00:16:41.199 super interesting but we're just
00:16:42.240 responding with server time and this is
00:16:44.160 going to continue to count for 100
00:16:46.000 seconds and then we'll stop but we're
00:16:47.199 not going to wait that long
00:16:52.639 that
00:16:55.920 so
00:16:56.800 um with action controller live it's cool
00:16:58.720 that we have
00:16:59.839 some way to stream back responses
00:17:02.320 but in in aaron's blog he admits that in
00:17:05.199 order to get it working he had to work
00:17:06.400 around rack quite a bit
00:17:08.640 um
00:17:09.600 what's really nice is that
00:17:11.360 back in january i think with rack 1.5 it
00:17:14.799 was introduced rack.hijack so rack
00:17:17.520 hijack allows us to hijack the raw tcp
00:17:20.559 socket from rack and then do whatever we
00:17:22.799 want with it and then allow rack to you
00:17:24.799 know continue on
00:17:26.319 this is the this is essentially the api
00:17:28.640 here inside our rails environment
00:17:30.400 variable
00:17:31.679 if
00:17:32.480 our web server in this case puma is rack
00:17:35.440 hijack compliant then the rack.hijack
00:17:38.000 question mark
00:17:40.880 key is going to return true
00:17:43.200 and then we can call call on rack.hijack
00:17:46.320 and this will return the raw tcp socket
00:17:48.640 if for some reason we need to access
00:17:50.320 that socket later on again then we can
00:17:52.799 just call
00:17:54.400 iraq.hijack underscore i o
00:17:58.160 and there's two ways that rack hijack is
00:18:00.000 meant to work but for the purposes here
00:18:01.520 we're just going to talk about the full
00:18:02.559 hijack
00:18:04.400 and
00:18:05.360 requests are
00:18:06.720 made to the server the tcp socket is
00:18:09.120 then
00:18:10.160 taken for
00:18:11.520 your purposes
00:18:13.039 you can put it into a thread
00:18:14.880 you probably should put into a thread to
00:18:16.000 do what i'll be doing next
00:18:18.640 and then you tell the server to complete
00:18:20.720 the request as normal you want to
00:18:22.080 respond with just like an empty
00:18:24.400 body and then a 200
00:18:26.240 just so that
00:18:27.360 rack can complete
00:18:29.039 and
00:18:30.640 the thread is alive until you close the
00:18:32.320 socket and kill your thread essentially
00:18:34.640 and then it's up to the web server
00:18:36.080 whether or not it's going to allocate
00:18:37.440 new sockets or if it's going to wait
00:18:39.760 until the socket is free and i also if
00:18:42.080 people are interested in this i
00:18:43.200 recommend checking out the
00:18:44.880 rack spec
00:18:46.559 just search for hijack inside of it and
00:18:48.720 you can find
00:18:50.400 everything having to do with that
00:18:53.280 so websockets this is the part that
00:18:55.280 really interested me because i'm i
00:18:57.280 actually haven't used server sent events
00:18:58.640 but we use web sockets quite a bit and i
00:19:00.720 think that websockets in rack hijack
00:19:02.640 work really well together
00:19:04.480 allows for two-way communication
00:19:07.120 and there is a websocket gem for
00:19:09.440 constructing your websocket handshakes
00:19:11.840 and frames that will be going into so
00:19:14.960 if you if you want to get up and running
00:19:16.400 with this
00:19:18.000 i recommend that you use the master
00:19:19.840 branch
00:19:20.799 on the websocket project
00:19:23.600 if you for whatever reason think that
00:19:25.360 your websockets are not fast enough
00:19:26.799 there is a natively compilable websocket
00:19:29.600 gem but i have not used it
00:19:32.799 and this is what a
00:19:34.640 handshake construction
00:19:36.240 incoming and outgoing frame um
00:19:39.280 uh requesting response would look like
00:19:41.440 it's a little bit of code but we'll show
00:19:43.520 you something a bit that's much easier
00:19:45.600 so on the third line we're getting the
00:19:47.679 socket from rack hijack uh second uh
00:19:50.400 fifth line on stop lines but we're going
00:19:52.320 down we're creating the handshake and
00:19:53.440 then below that we see handshake dot
00:19:55.200 from rack and then env this is the
00:19:57.280 reason we want the master branch of the
00:19:58.880 web socket gem um it hasn't been pulled
00:20:01.440 into uh the gem on ruby gems yet but
00:20:04.840 recently there was this method added
00:20:07.360 that allows you allows the handshake to
00:20:09.600 construct all the headers properly based
00:20:11.840 upon the rack environment variable
00:20:13.919 and then we're just writing out to the
00:20:14.960 socket the handshake
00:20:17.360 the second group here is we're reading
00:20:19.120 from a frame so when i mentioned frames
00:20:20.799 earlier on in tsp sockets this is what
00:20:23.200 we're constructing here
00:20:25.039 um
00:20:26.640 the object itself we're creating a
00:20:27.919 buffer and then we're receiving 2000
00:20:30.159 bytes from the buffer rather from the
00:20:32.400 socket we're running that data to the
00:20:34.640 buffer and then we're going to iterate
00:20:36.400 through the buffer and we're going to
00:20:37.840 get frames back and then we can handle
00:20:40.000 the frame data anyway we want
00:20:43.280 down at the bottom we are just sending
00:20:45.280 out a message so it's going to look
00:20:47.280 somewhat similar to the handshake itself
00:20:52.400 just to read it we're constructing the
00:20:53.520 header bringing the header to the socket
00:20:55.679 write data to the socket redid the
00:20:57.280 socket close the socket i mean this is
00:20:59.200 it's not super interesting when you kind
00:21:00.880 of do it quite a bit but this is the
00:21:02.400 gist of of how the websocket's going to
00:21:04.080 work in general socket programming
00:21:07.600 websockets on the client
00:21:10.400 this api is much simpler
00:21:13.200 and should be pretty self-evident these
00:21:15.039 uh callbacks fire based upon responses
00:21:17.760 from the server or yeah these are all
00:21:19.679 responses from the server and then the
00:21:21.280 the third one is when you're sending
00:21:22.320 data out
00:21:24.559 and i have some demos to show so
00:21:27.280 we have a chat demo and then we have a
00:21:28.880 drawing demo both of these are using the
00:21:30.480 same rails application using web sockets
00:21:33.280 and hopefully they won't be really slow
00:21:35.039 because
00:21:36.880 the wi-fi is
00:21:38.400 not fantastic anyway so we got this this
00:21:40.799 chat server here people can join if they
00:21:42.400 want if they're if they're up there if
00:21:43.679 you go to railsconf2013.docu.com
00:21:46.400 you have the option of clicking on chat
00:21:48.320 or draw
00:21:50.000 this one might be a little whoops
00:21:52.320 just
00:21:53.679 this one might be
00:21:56.080 it's probably goofing up that doesn't
00:21:58.000 look
00:21:59.360 i think that's a chrome thing
00:22:04.320 that's even worse
00:22:09.200 yeah i know that's what i meant to do
00:22:11.520 and let me try canary
00:22:19.919 okay so um if people join that we can
00:22:23.440 see you guys yeah there's somebody
00:22:24.960 drawing now and we can continue going
00:22:27.120 once enough people join the server will
00:22:28.559 crash because there is a memory leak on
00:22:29.919 the server
00:22:31.840 don't draw anything really stupid come
00:22:33.520 on
00:22:35.360 let me get off of this
00:22:44.880 um all right there's people in the chat
00:22:46.480 room okay hello
00:22:49.039 anyway these are pretty simple cases for
00:22:51.919 what we can do with this stuff
00:22:54.640 the source code is available on github
00:22:57.280 github
00:22:58.400 dockyard slash real time dash rails
00:23:02.080 the
00:23:03.520 code is really
00:23:04.960 fugly because
00:23:06.640 i put everything in the controller
00:23:08.799 that's my excuse for not breaking it out
00:23:10.960 um but anyway it's it's pretty
00:23:12.400 self-explanatory and what it does oh
00:23:14.000 everyone's joining
00:23:16.080 i should have made it to actually jump
00:23:17.679 to the bottom
00:23:20.880 all right anyway
00:23:22.400 um let's go back
00:23:26.880 so what we'll notice is that when you're
00:23:29.840 doing applications like this a pattern
00:23:32.559 begins to emerge from what you're doing
00:23:34.840 from naturally what you're doing
00:23:38.080 that pattern ends up being you're
00:23:39.440 capturing events on the client you're
00:23:41.039 sending those events to the server and
00:23:42.799 there might be some data normalization
00:23:44.400 going on and then that message gets
00:23:46.640 blasted out to everyone that's connected
00:23:49.520 this is why
00:23:51.039 services like pusher can exist and work
00:23:53.600 so easily because this is not a really
00:23:55.280 complicated thing that's happening
00:23:59.200 so the code actually you know what i'll
00:24:01.360 even show you just how ugly it is
00:24:05.440 just so you can see how much nicer tube
00:24:08.080 sock makes everything
00:24:09.760 all right
00:24:16.080 all right so this is a big fat
00:24:18.000 controller method but i got two threads
00:24:20.159 going on i've got pub sub happening and
00:24:23.360 um
00:24:25.120 that was it anyway so
00:24:26.799 uh tube sock makes things much much
00:24:28.640 nicer much easier to work with tube sock
00:24:30.640 is a gem written by nick gothier and the
00:24:34.000 api for tube sock is going to look much
00:24:35.760 similar to what the websocket api looks
00:24:37.840 like on the on the browser
00:24:40.559 inside
00:24:41.600 your
00:24:43.440 action controller method
00:24:45.520 inside your action rather you're just
00:24:47.039 going to wrap everything in this hijack
00:24:48.960 block and you can
00:24:51.120 just use in the same way you would on
00:24:52.400 the client
00:24:55.120 i highly recommend tube sock
00:24:58.159 so some of the challenges that do exist
00:25:00.400 for
00:25:01.440 um
00:25:03.360 for websockets right now is heroku does
00:25:05.679 not support them last time i checked
00:25:07.440 they don't it kind of flies in the face
00:25:09.840 of what their
00:25:12.000 business model is they're bringing down
00:25:13.840 servers and bringing them up all the
00:25:14.799 time that doesn't work well when you
00:25:16.159 have persistent connections that need to
00:25:17.360 be there
00:25:19.039 but it would be nice if the paid
00:25:20.320 instances had that
00:25:21.840 and nginx tends to really not want you
00:25:24.400 to do websockets they did introduce http
00:25:27.600 1.1 1.1 support a few months ago
00:25:31.600 this has the keep alive
00:25:33.440 aspect to it which is necessary for web
00:25:35.279 sockets but by default
00:25:37.679 nginx and this took me way too long to
00:25:39.760 find that it should have
00:25:41.200 x also has a setting called proxy read
00:25:44.559 timeout that is set for 60 seconds
00:25:47.039 so
00:25:48.080 if the socket is inactive if the
00:25:49.919 connection isn't active for 60 seconds
00:25:51.760 it just kills it
00:25:53.039 and i had no idea why
00:25:55.600 like it was just dying after a minute
00:25:57.440 every single time going nuts but you can
00:25:59.279 bump that up quite a bit you can bump it
00:26:01.120 up to 24 days i don't know if you need
00:26:03.200 it that high
00:26:04.400 it would be nice if there was just a
00:26:05.840 all-around infinite time or maybe even
00:26:08.960 nginx might not be the right solution
00:26:10.320 for this
00:26:13.520 so for the future
00:26:15.919 it would be nice if rack hijack was
00:26:18.640 integrated into action controller live
00:26:21.600 right now we have two solutions for kind
00:26:24.320 of the same problem
00:26:26.000 i've offered
00:26:27.200 twice now on the uh on the rails core
00:26:30.000 mailing list to do it and i've
00:26:32.240 taken my sweet time and haven't done it
00:26:33.600 both times i've offered and i'm not
00:26:35.279 gonna go for a third so
00:26:37.120 if somebody wants to tackle that i think
00:26:38.400 that'd be really cool but with release
00:26:40.000 candidate one today for rails i don't
00:26:41.760 know if it'd still be on the table for
00:26:43.200 reals four maybe 4.1
00:26:46.240 and i
00:26:47.360 i think or at least i hope that um
00:26:50.080 having this stuff in there would be
00:26:51.919 validation and some indication that
00:26:53.760 rails is moving towards a friendlier
00:26:56.000 like rich client experience uh
00:26:58.400 for developers like i said i'm getting
00:27:00.559 more and more into ember i highly
00:27:02.159 recommend it's awesome
00:27:03.760 and i think having uh these type of
00:27:06.000 tools available on the server allows
00:27:08.480 your
00:27:09.279 your rail taking all the tools and
00:27:10.880 everything you've learned doing rails
00:27:12.159 applications now applying it to doing
00:27:14.080 these uh these
00:27:15.919 highly responsive asynchronous
00:27:17.840 applications is is going to be pretty
00:27:20.000 interesting to see what we come up with
00:27:21.200 over the next few years
00:27:24.240 um i think that's it and um my we'll
00:27:27.039 explore again if you guys like doing
00:27:28.640 this type of stuff we're always hiring
00:27:30.080 and um we're looking to do anything like
00:27:32.559 this so thank you guys very very much
00:27:34.320 for the time
00:28:12.080 you