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