►
Description
Tokio, Warp, and Websockets
In his talk, Stefan will show you how to build a Server with Tokio, Warp, and Websockets. Demo repository: https://github.com/ddprrt/warp-websockets-example
https://twitter.com/ddprrt
https://twitter.com/rustlinz
https://sessionize.com/rust-linz
https://rust-linz.at
A
We
are
talking
today
about
tokyo,
warp
and
websockets.
So
hey,
hey
yeah,
that's
me
hi,
I'm
stefan!
I
have
the
worst
twitter
handle
on
the
bladder
planet.
It's
that
parrot.
So
if
you
are
into
monty
python,
you
maybe
know
what
it
means.
If
you
aren't,
don't
worry
it's
60
years
old
or
something,
and
today
I
want
to
talk
to
you
about
tokyo
warp
and
web
sockets.
This
is
so.
I've
spent
a
lot
of
time
trying
to
learn
async
trying
to
teach
async
in
rust.
It's
interesting.
A
It's
it's
very
different
to
what
I'm
used
to
from
other
programming
languages,
but
also,
once
you
get
it.
It's
really
one
of
those
mind
opening
things,
and
I
want
to
talk
to
that
about
it.
Some
other
point
now
I
want
to
talk
about
an
actual
application
that
I
wrote
with
with
async
in
rust,
and
I
use
the
tokyo
framework
for
that.
A
So
tokyo
tokyo
is
fun
because,
if
you've
done
anything,
async
or
anything
web
related
in
rust,
chances
are
that
you
have
stubborn
bomb
tokyo
in
one
way
or
the
other,
either
by
seeing
some
hash
tokyo,
colon
colon
main
thing.
Maybe
if
you,
if
you
deploy
the
lambda
on
the
aws
lambda
or
something
in
rust,
then
you
use
that
because
the
aws
lambda
runtime
uses
it
or,
if
you've
written
a
web
server,
be
it
with
rocket.
A
If
you
use
rocket,
which
was
one
of
those
talks
that
you
hear
had
that
we
had
here
in
rustling
very
early
on,
then
you've
used
tokyo.
Even
if
you
didn't
know
it.
I
think
also
hectic.
So,
basically
any
web
framework
out
there
bait
is
based
upon
tokyo.
It's
a
multi-threaded
run-time
for
executing
asynchronous
code.
A
It
has
an
asynchronous
version
of
the
standard
library
and
a
large
ecosystem
of
libraries.
There
are
some
alternatives.
A
glomio
is
one
that
I
that
I
just
found
out
about
recently.
Async
standard
is,
I
guess
that
the
other
big
alternative
to
having
an
asynchronous
runtime
for
rust,
which
is
honestly
one
of
the
better
ones
to
learn
async,
because
the
surface
is
a
lot
lot
easier
to
understand,
because
tokyo
can
get
very
big
very
early
on.
A
But
if
you
reach
one
point
where
you
are
working
on
the
the
application
layers,
your
stuff
is
mostly
done
in
tokyo.
Why
do
we
need
a
multi-threaded
runtime
for
executing
asynchronous
code
in
rust?
So
rust
gives
you
all
the
primitives
for
for
writing
asynchronous
code?
It
gives
you
futures
to
write
something
that
is
executed
at
some
point
in
time
and
returns
a
value
it
gives
you
async
and
the
weight
to
have
syntax
sugar
to
work
conveniently
with
asynchronous
code,
but
it
doesn't
give
you
a
runtime
to
execute
it.
The
reason
is
rust.
A
A
Maybe
it's
async
standard,
or
maybe
you
have
different
concerns
that
that
you
need
to
take
into
account
and
for
that
you
have
to
choose
your
random
and
the
runtime
is
the
one
thing
to
take
that
takes
all
your
futures,
all
the
asynchronous
bits
and
pieces
and
executes
it
on
the
thread
or
multiple
thread
depending
on
your
flavor.
So
tokyo
is
not
only
a
runtime,
but
tokyo
has
also
an
entire
set
of
tools.
It
includes
everything
from
low
level.
A
I
o
up
to
to
type
system
based
service,
modeling
and
anything
in
between,
so
we
have
mile-
that's
that's
short
for
metal.
I
o
and
it's
some
sort
of
abstraction
layer
on
top
of
operating
system.
Events
like
oh
wow,
there's
a
socket
done.
Please
do
something
dear
the
application,
that's
coming
from
my
it
normalizes
the
I
o
across
all
operating
systems
for
apps
that
you
build
on
top
of
it.
Then
we
have
to
tokyo
runtime,
which
is
the
heart
of
tokyo.
It's
the
synchronous,
runtime.
A
It
implements
work
stealing
if
it's
multi-threaded,
so
you
have
a
queue
of
of
tasks.
Task
is
a
unit
of
process
in
tokyo
land
and
you
have
a
couple
of
threads
that
spawn
workers
which
can
work
on
those
tasks
and
they
just
pick
a
task
from
a
queue
execute
it.
If
there's
something
to
do
or
put
it
back
on
the
queue
and
produce
results.
So
that's
that's
what
tokyo
does?
It
also
comes
with
the
rich
standard
library.
A
They
have
async
file
as
inc
networker
timer
schedules,
all
the
chairs,
that's
all
there
in
the
tokyo
around
them,
and-
and
this
is
this
is
already
great-
and
if
you're
at
that
level,
you
can,
you
can
pick
and
choose
whichever
runtime
that
you
like
there
plenty
out
there
I
took
it
might
be
one
of
the
most
popular
but
there's,
maybe
others
that
are
better
suited
for
your
needs
and
then
there's
even
stuff.
A
On
top
of
that,
and
that's
a
couple
of
layers,
first
is
hyper,
which
is
an
hdb
implementation,
a
correct
http
implementation
for
rust,
which
implements
http
one
and
two
for
both
client
and
severance,
which
is
basically
that
the
framework
basis
for
anything
x
and
rocket
warp
actives,
you
name
it.
That's
all.
Based
on
this
package,
we
have
the
same
thing
for
for
trpc,
it's
called
tonic.
A
It's
also
a
layer
on
top
of
tokyo
which
implements
the
grpc
protocol,
and
you
can
work
with
that
and
all
those
protocol
implementations
get
around
the
idea
of
a
service
which
is
done
with
power
so
think
of
it
as
a
middleware
layer,
where
you
have
different
middlewares
different
layers
on
top
of
each
other,
you
can
build
a
tower
and
then
you
run
a
request
through
this
target
down
to
the
bottom.
You
get
a
response,
you
run
it
up
again
and
then
you
can
modify
requests
and
responses.
A
Like
oh
there's
there's
an
http
response
which
I
want
to
cheat
it.
Then
you
run
through
the
cheesy
player.
Maybe
you
want
to
have
a
shot
token
validation,
then
you're
onto
the
top
layer,
or
maybe
you
don't
want
to
take
this
to
take
really
long.
Let's
have
a
timer
player,
so
you
can
kill
some
of
those
requests
if
it's
not
worth
working
with
the
nmr.
So
this
is
this
is
tower
and
all
those
things
build
up
all
the
things
that
we
see
then
are
building
up
upon
tower.
A
We
also
have
a
couple
of
packages
that
help
us
with
the
whole
thing.
Bytes
is
basically
a
synchronous
reference
count,
the
mutex
on
u8,
that's
cool.
If
you
want
to
want
to
manipulate
byte
arrays
across
threads
and
tracing.
If
you
want
to
monitor,
if
you
want
to
send
your
data
into
data,
talk
or
dynatrix
or
whatever.
A
So
that's
that's
this
part
well,
and
on
top
of
that
we
also
have
frameworks
and
frameworks
like
exxon,
which
is
pretty
new,
which
is
from
the
tokyo
team
themselves.
It's
also
in
the
tokyo
organization
on
github
and
warp,
which
is
one
of
the
crew
one
of
the
tokyo
maintainers
one
of
the
hype
maintainers
from
sean
mcarthur,
which
I
guess
that's
a
pretty
wild,
guess
so
sean.
If
you,
if
you
can
see
this
and
if
I'm
totally
wrong,
I'm
sorry
a
warp
is,
I
guess,
inspired
from
a
haskell
framework.
A
That's
that
same
similarity,
and
you
can
see
that
if
we,
if
you
look
into
an
example,
it's
very
functional
and
very
compositional
and
filter-based-
and
I
think
it's
beautiful.
So
I
liked
working
with
that
with
that
a
lot
but
yeah.
So
those
are
a
couple
of
frameworks,
but
there
are
others
and-
and
you
can
see
tokyo,
basically,
basically
anywhere.
A
So
one
thing
where
I
had
to
work
a
lot
with
tokyo
is
deno,
I'm
using
denoin
in
a
couple
of
projects,
not
just
as
a
runtime
that
I
can
install
as
a
binary,
but
I
use
the
runtime
itself
to
work
on
a
couple
of
javascript
projects.
More
than
5
500
crates
depend
on
tokyo
and
that's
great,
it's
not
application.
So
it's
really
really
popular
all
right.
But
what
we're
going
to
see
warp
just
in
a
bit?
A
What
tokyo
also
gives
us-
and
that's
that's
very
inspired-
I
guess-
by
by
go
and
how
gold
works
in
terms
of
communicating
with
go
routines,
which
is
their
version
of
executing
a
synchronous
code,
is
channels
channels
to
share
state,
and
I
want
to
quote
rob
pike
who
said
if
you
run
concurrent
code,
if
you
run
things
concurrently,
don't
communicate
by
sharing
memory
like
a
mutex
like
an
rw,
lock
or
something
share
memory
by
communicating.
A
So
you
get
the
couple
of
channels
where
you
can
send
messages
through
and
you
can
pick
it
up
from
your
other
tasks.
You
have
those
independent
units
of
executing
things
and
you
send
data
in
between
them
and
geography.
There
are
a
couple
of
things:
a
couple
of
implementations
integrate,
there's
npsc,
which
stands
for
multi-producers
single
consumer.
So
you
have
a
lot
of
producers.
Many
taskers
can
create
value
and
have
one
produce
one
consumer
that
gets
them
one
shot,
which
is
just
sending
one
value
once
and
then
it's
done,
which
is
great
for
communicating
back.
A
So
you
can,
for
example,
use
this,
sent
the
sender
pattern
where
you
send
something
to
your
consumer
and
you
get
the
sender
where
you
can
send
back
to
the
producer.
So
you
can
do
this
back
and
forth,
which
is
great,
if
you
have
some
architecture
where
you
have
the
web
player
completely
separated
from
everything
else.
This
is
where
I
use
that
a
lot.
Then
you
can
communicate
between
two
parts
of
your
architecture
without
them,
even
knowing
from
each
other.
It's
just
message.
A
Part
watching
brokers
is
multiple
reducer,
multiple
consumer,
with
with
a
bit
of
different
flavors,
so
there's
a
lot
of
stuff
stuff
in
there,
so
the
tasks
operate
independently
and
you
can
send
messages
in
between
to
synchronize
and
yeah
channel
support,
sending
a
message
from
one
producer
task
to
one
or
more
consumer
tasks,
one
that
we
are
going
to
see
right
now
in
an
implementation.
This
is
also
available
in
the
standard
library
in
standard
sync,
and
psc
is
multi-producer.
A
Multi-Consumer,
send
work
to
a
task
and
receive
the
results
of
many
computations
multi-producers
single
consumer
channels
have
a
capacity
but
they're
also
unbounded
variants.
So
this
is
this
is
the
idea
of
many
producers.
You
send
it
to
one
one
consumer
already,
and
you
know
those
are
many
producers,
but
this
also
could
be
just
one
producer,
so
we
have
also
one
to
one
but
with
multiple
computations,
here's
a
little
example.
So
I
have,
I
hope
you
can
see
my
cursor,
because
I
don't
have
those
fancy
errors
to
draw
to
draw
on
the
screen.
A
But
here
I
have
an
async
function
main
I
create
a
new
tcp
stream.
I
connect
to
some
some
server
and
then
I
oh
forget
this
line
this.
This
is
not
so
important.
This
is
more
important.
I
create
the
multi-produce,
a
single
consumer
channel
with
a
capacity
of
100
okay
and
then
I
create
10
tokyo
tasks
with
tokyo.spawn,
and
I
do
that
from
from
0
to
10,
so
10
tasks
in
total,
I
clone
the
producer
and
a
clone
from
a
producer
just
creates
another
producer.
It
doesn't
create
another
channel.
A
It
just
creates
another
producer,
which
means
I
have
many
producers
that
talk
to
one
receiver,
but
I
need
to
clone
that
so
I
can
move
that
into
this
async
move
here.
So
this
this
async
block,
which
is
a
future.
So
if
I
write
async
move
here,
it
creates
a
future
that's
being
executed
in
the
tokyo
task
that
took
his
wonders,
and
once
this
essence
once
the
future
is
executed,
I
can
send
some
data
to
this
channel
and
down
there,
I'm
going
to
receive
it,
so
this
is
also
pretty
nice.
A
This
is
a
tokyo
stream,
so
this
is
some
sort
of
asynchronous
iterator
and
even
if
you
look
at
the
trade
definition,
it's
also
very,
very
similar
to
an
iterator,
which
is
that
you
have
an
option
that
returns
an
item,
but
it's
also
something
that's
packed
in
the
future.
So
you
need
to
wait
for
it,
so
you
can
use
it
like
an
iterator,
but
it's
asynchronous,
so
it
runs
somewhere
in
this
whole
task
execution
on
tokyo.
A
And
yes,
if
I
get
some
some
data
here,
I
write
everything
out
and
one
thing
that
is
important:
this
receiver
returns
none,
so
it's
an
option
either.
I
have
a
value,
some
value
or
have
no
value
at
all,
and
if
I
have
no
value
it
returns
num,
but
it
only
returns
num
if
all
the
producers
have
been
dropped-
and
this
happens-
you
know
if
this
block
here
ends
from
the
async
move
block.
A
A
Returns,
none
at
some
point
and
I
can
stop
the
execution
of
my
program.
So
this
is
one
of
those
channel
types
that
are
available
in
tokyo
and
this
is
also
the
one
that
I
want
to
focus
on
today.
So
there
are
a
couple
of
more
and
there's
great
documentation
on
all
of
them,
but
but
this
is
one
that's
interesting
for
what
for
that,
what
we
are
doing
just
in
a
second
all
righty,
and
what
I
want
to
do
is
having
a
simple
web
social
chat,
and
this
is
a
very,
very
stupid
architecture
diagram.
A
I
have
a
client,
that's
a
browser
up
here
and
I
create
a
web
socket
connection
to
some
server.
So
this
is
this.
Is
the
world
simple
for
server,
which
is
this
cylinder?
I
I
don't
know
why,
but
that's
that's
the
the
world
superfood
server,
and
why
is
it
for
a
database?
I'm
sorry
I
I
guess
I
totally
forgot,
but
I'm
creating
I'm
creating
a
websocket
connection,
which
is
I
have
something
to
receive.
That's
rx
is
for
receiver,
tx
or
tx
is
for
transmitter.
A
These
are
terms
that
come
from
from
broadcasting.
Actually
so
from
radio
broadcasting.
You
have
a
transmitter,
you
have
a
receiver
and
and
the
the
abbreviations
for
that
were
tx
and
rx,
and
we
carry
them
until
today,
even
if
we
do
either
sockets
or
just
channels
or
whatnot.
So
I
have
a
user
rx,
which
is
a
receiver,
so
I
get
messages
in
from
the
browser.
A
This
is
the
one
socket
connection
and
I
have
tx
where
I
can
send
back
to
the
web
server,
and
I
do
this
for
every
for
for
every
client
connection
for
every
browser
connection
that
establishes
a
websocket
to
to
the
server.
Once
I
get
a
message,
what
I
do
is
I
send
this
message
to
every
user
and
I
create
an
mpsc
channel
for
every
user,
so
every
user
has
the
possibility
to
to
send
messages
two
to
two
one
or
more
receivers
to
one
receiver,
sorry
to
one
with
zero.
A
A
This
is
everything
that
I
do
with
the
websocket,
so
I
establish
a
connection
and
then
using
channels,
so
I
can
communicate
between
all
those
connections
that
I
have
by
keeping
track
of
all
the
centers
and
sending
out
stuff
alrighty,
and
this
is
this-
is
what
we're
going
to
see
right
now.
Let's
remove
my
presentation
and
give
me
a
second:
let's
go
to
visual
studio
code
and
that's
the
websocket
administration
itself.
A
That's
that's
warp
and,
as
you
can
see,
it's
very
busy,
it's
very
very
busy
because
the
moment
you
want
to
abstract
a
lot
of
stuff
with
for
web
servers
or
whatnot.
A
You
end
up
with
a
lot
of
types
and
if
you
end
up
with
a
lot
of
types,
you
get
type
annotations
the
size
of
war
and
peace
or
something
so
so
really
really
huge,
nonetheless,
for
for
for
right
now,
so
that
you
can
scan
this
and
see
what's
happening
there,
let's
remove
the
inlay
hints,
and
if
you
learned
one
thing
today
that
it's
that
you
can
remove
the
inlay
hints
it's
a
little
bit
less
busy
less
busy
to
look
at
okay,
okay.
A
So
what
I'm
doing
here
I
create,
I
create
a
new
work
server
and
what
this
is
funny,
because
you
are
connecting
bits
and
pieces
to
to
create
routes
and
to
create
callbacks
for
that
or
stuff
that
needs
to
be
executed,
and
it's
then,
and
or
or
so
it's
just
connecting
little
filters
together
and
to
have
a
big
filter
tree
and
when
a
request
comes
in,
it
gets
filtered
through.
So
it
finds
the
right
and
the
last
stuff
to
execute,
and
this
is
very
functional.
A
This
is
a
very
heschlish
if
you
will,
but
it's
also
it's
also
a
lot
of
fun
fun
to
use.
So,
especially
if
you,
if
you
have
have
a
little
love
for
for
functional
programming,
all
righty,
so
let's
start
with
something
easy.
What
one
did
I
do,
which
is
great
for
starting
a
web
server,
is
having
having
a
serving
a
static
directory,
a
directory
with
static
files
in
it,
and
I
create
a
new
binding
where
I
say:
okay,
this
is
warped.
Colon
colon
effects,
current
colon
directory
server-
everything
from
this
folder.
A
If
it's
an
html,
if
you
have
an
html,
if
it's
a
css
file
serving
css
file
and
that's
about
it.
So
that's
that's
the
easiest
that
you
can
do
here.
I
have
a
route
that
does
some
some
some
more
interesting
stuff.
So
I
create
a
path.
That's
called
hello,
which
means
I
can
do
slash,
get
get
hello.
So
this
is
a
route
that
I'm
creating
for
that
and
you
say:
okay,
you
have
an
optional
argument,
an
optional
parameter
and
I
create
this
parameter
up.
A
There
and
say:
okay:
hey:
I
want
to
have
a
string
parameter
and
if
it
is
some
return
it
if
it
isn't
some
return
at
least
nancy,
I
get
an
option,
an
option
back
an
option
which
I
don't
have
a
value.
I
have
no
video
and
this
is
an
optional
parameter.
How
I
declare
it
in
warp-
and
so
I
can
say,
okay
for
this
hello
path.
Have
this
optional
argument
have
an
optional
parameter
there,
where
you.
A
Can
send
you
know
something
like
that
or
or
stefan
or
whatnot-
and
I
also
say,
okay
after
this-
let
the
path
end.
So
so
it's
not
possible
to
write.
Slash
hello,
slash,
verb,
slash,
something
something,
but
this
is
not
a
valid
route.
I
let
the
path
end
after
an
optional
argument-
and
this
is
this-
is
one
filter
that
I
create
for
this
route
and
then
I
say:
okay,
everything
that
comes
into
that
filter.
A
It's
mapped
to
something
that
I
want
to
want
to
execute.
And
what
do
I
get?
I
write
the
closure
here.
We
heard
a
lot
about
closures
today.
I
guess
so
so
you
know
what
what
this
does?
I
get
an
optional
string
in
there
and,
let's
say,
okay,
say
hello
to
the
name
unwrapped
or
else
several
or
world
that
should
work
too.
A
I
don't
know
why
I
did
it
that
way,
but
but
this
is
how
I
create
a
lever
out
with
an
optional
argument,
which
is
either
hello
world
or
hello
name,
depending
on
what
you
do,
and
this
is
how
you,
how
you
plug
everything
together
here,
that's
also
interesting.
I
have
a
404
route,
which
means
that
for
any
else,
so
this
is
every
other
request.
That
probably
so.
This
is
a
filter
that
accepts
it,
create
the
new
response
where
okay,
my
status
code
is
not
found.
A
404
and
the
body
is
just
this
four
or
four
html
file,
and
this
is
also
a
string
that
a
function
fs
read
to
string,
which
is
also
something
that
could
error.
So
I
expect
it
to
work
and
if
this
file
isn't
here,
I
get
a
4
for
my
404,
and
this
is
a
very,
very,
very
bad
error
message,
but
I
was
lazy,
I
guess
so
result
of
404.
A
I
have
some
files,
I
have
the
hello
route
and
now
I
combine
them
so
I
say:
okay,
wait
for
the
chat,
I'm
going
to
talk
to
that
in
a
little
bit,
so
I
say
hello
or
files
or
four
or
four.
So
those
are
this.
Is
that
the
order
that
of
priorities-
I
say?
Okay,
hey
the
hello
route
goes
first,
if
I
have
anything
there,
that's
my
dynamic
api
execute
this
if
this
gets
filtered
out.
So
it's
not
part
of
this
select
the
file.
A
If
this
file
isn't
available
go
to
the
404
and
that's
how
I
concatenate
all
those
to
speak
to
each
other,
but
I
also
have
this
chat
here,
and
this
chat
is
funny.
This
is
the
chat
route,
so
I
say
for
the
web
socket
for
the
web
soccer
dot
for
the
path.
A
I
don't
know
if
you
know
how
web
circuits
work,
but
web
sockets
is
basically
talking
over
http
if
they
speak
http
and
then
sending
this
this
upgrade
header
and
say:
hey:
do
you
speak
web
circuit
and
then
you
get
either
okay
back
or
or
another
okay
back
and
say
yeah,
I
speak
websocket
then
say:
okay,
let's
upgrade
our
existing
http
connection
to
a
web
socket
connection,
and
now
we
can
send
back
and
forth
packages.
That's
what
it
is.
Basically,
it
is
a
little
protocol
on
top
of
tcp.
A
Then
the
tcp
connection
stands
open.
You
can
send
packages
back
and
forth
and
the
browser
knows
how
to
integrate
them
to
see.
Everyone
knows
how
to
interpret
them.
That's
what
it
does.
What
I
also
doing.
That's
also
funny-
I
add
some
users
there
and
users
is
this
here-
is
this
little
data
structure
that
I
have
here
uses
default?
That's
a
very
simple
data
structure.
It's
basically
an
atomic
reference
count
on
a
read
w
log
on
the
hashmap,
where
I
store
multiproducer
single
consumer
senders.
A
A
I
say:
okay,
if,
if
users
I
want
to
create
the
filter
out
of
it,
a
filter
that
I
can
use
with
what
which
means,
I
say:
hey
for
anything
that
bubbles
through
here,
mapbit2
uses.clone,
since
it's
an
atomic
reference
counter,
I
get
another
atomic
reference
that
I
can
work
with
and
suddenly
I
have
here
in
my
chat
users
available
as
an
object.
So
I
can.
A
A
I
get
the
users
to
say
if
this
web
socket
upgrade
is
successful,
so
on
upgrade,
I
have
a
I
have
an
actual
websocket
and
then
I
want
to
call
this
connect
function
with
the
socket
and
with
my
users.
So
this
is
what's
going
to
happen
here.
That's
that's
a
mouthful,
that's
a
lot
and
this
connect
function.
This
is
what
I'm
going
to
implement
you
with
you
right
now,
so
here
again
combining
everything
then
I'm
serving
the
routes.
I
bind
it
on
the
socket
address,
and
I
wait
for
that
and
here.
A
Oh
there's
this
to
do
function,
so
this
is
now
something
that
I
have
to
do
with
you
already.
So
let's
toggle
the
inlay
hints
again,
because
I
need
them
in
developing
the
first
thing
that
I
do.
I
create
the
new
user
id
that
mighty.
I
have
one
thing
up
there:
that's
the
next
user
id,
which
is
an
atomic
use
size,
which
means
it's
a
thread
safe
use,
size
that
starts
at
one,
and
I
can
increment
it
across
threads
and
across
tokyo
tasks.
Of
course.
A
So
I
say
my
id
is
next
user
id
and
then
I
have
something
like
fetch
ad.
That
say:
okay,
basically
take
this
one
and
add
one
twit,
and
how
do
you
add
one
to
it?
I
don't
care
about
race
conditions
or
whatnot
sha.
Do
it
in
a
relaxed
way
so
increment
whenever
you
can,
because
hey
everything
that
I
want
to
get
out
is
the
next
user
id.
I
don't
care.
A
If
somebody
is
there
in
front
of
me,
absolutely
not
something
that
I
I
need
to
do
so,
let's
print
a
print
out
that
I
have
welcome
user,
that
I
have
a
new
user,
all
righty,
what
I
do
then
so
so
I
have
an.
I
have
a
websocket
connection
established.
That's
great
sorry!
It's
my
id,
my
id,
and
here
I
say
it's
bordering
sorry,
better.
Okay,
so
I
have
a
websocket
established.
Now
I
want
to
get
the
transmitter
and
the
receiver.
A
So
I
want
to
get
something
where
I
can
read
from
I
get
onto
something
that
I
can
write
to
and
I
call
it
like
in
my
architecture.
A
Diagram
use
a
tx
and
I
need
a
mutable
user
rx
which
I
do
from
websocket.split,
and
this
is
splitting
is
always
always
pretty
funny,
because
if
I
go
to
the
definition
down
there,
it's
split
and
then
I
have
here
split
sorry,
split,
again,
split,
split
and
again
so
basically
long
story
short,
it's
still
one
connection,
but
I
get
a
reading
reference
and
a
writing
reference
to
the
same
socket
that
I
can
use
differently
and
I
need
to
use
them
differently.
So
I
can
move
those
parts
safely
across
threads
across
tasks,
etc.
A
So
this
is
the
idea
why
I
want
to
call
split
there,
but
I
don't
want
to
use
the
same
socket
for
reading
a
writing,
because
I
want
to
do
different
tasks
with
so
that's
the
connection,
something
to
read
from
something
to
write
from
between
browser
and
server
so
and
what
I
want
to
store
is.
I
want
to
then
use
channels,
so
I
can
communicate
between
all
the
existing
users
that
are
there.
So
I
create
something
for
the
users
to
communicate.
So
that's
px
and
rx,
and
here
I
create,
would
you
produce
a
single
consumer?
A
Let's
create
a
number
on
the
channel,
I
don't
care
about
bounce
in
in
that
case.
So
if
you
get
too
many
too
many
requests
it
errors,
that's
that's
bad,
but
usually
for
that.
What
I'm
doing
here?
A
That's
okay,
but
you
also
see
here
the
types
are
unknown:
typescript,
sorry,
typescript,
rust,
that's
a
thrill,
rust
can't
infer
the
type
yet,
but
it
will
when
we
move
forward,
so
bear
with
me
and
what
I
also
create
so
so
this
is
a
sender
and
a
receiver
for
the
channel,
so
I
can
sense
the
file
tickets
gets
received
to
the
other
side,
and
this
is
the
way
how
I
want
to
communicate
between
between
channels
what
I
do
with
rx,
because
I
get
a
couple
of
convenience
functions
with
it.
A
I
say:
let's
create
an
unbounded,
receiver
stream
out
of
that
receiver
stream,
and
now
I
have
an
unbounded
receiver
stream,
where
I
can
simply
use
it
to
to
forward
everything
that
comes
in
to
something
else,
and
this
is
what
I'm
doing
right
right
now,
so
I
create
a
new
task.
A
I
spawn
a
new
task,
so
this
is
the
one
thing
that
needs
to
be
as
synchronous.
This
is
every
every
time
something
happens
I
want.
I
want
to
forward
everything
that
comes
in
front,
so
these
are
the
messages
that
come
from
others
and
I
want
to
send
it
out
to
the
websocket
to
the
browser.
So
this
is
what
I'm
doing
here
say
forward
everything
through
user
tx,
so
everything
that
every
message
that
comes
in
from
my
internal
users
send
it
out
to
the
web
socket
to
the
browser.
A
This
is
what
I'm
doing
here
and
suddenly
I
also
get
type
annotations
right.
So
now
it's
a
message,
etc.
So
this
is
this
is
what
we
get
here.
One
thing
that
I
need
to
do
as
well:
I
want
to
add
the
new
user,
so
I
have
created
the
user,
and
this
is
why
I
want
to
store
them
and
what
I'm
storing
here
is
say:
users.right,
I
get
right
access
weight,
it's
in
a
synchronous
operation
because
I'm
using.
A
Why
is
it
in
a
synchronous
operation
because
I'm
using
the
tokusync
rw
log
and
not
the
one
from
from
the
standard
library?
This
is
because
those
are
w
log
right
guards
are
not
thread
safe.
A
A
Also
with
the
same
api,
which
is
which
is
not
the
only
thing
that
you
need
to
do
is
a
wait
for
it,
and
once
you
get
it,
let's
insert
based
on
the
idea
that
you
have
this
one
sender.
So
what
I'm
doing
here,
I
store
all
the
senders,
all
the
transmitters
for
all
my
users
in
this
bookkeeping
data
structure.
A
That's
what
I
do
here,
I'm
not
using
a
mutex,
because
mutex
means
it's
it's
locked
for
reading
and
writing
and
rw
log
means
once
I
I
lock
it
others
can
still
read,
which
is
which
is
interesting
for
broadcasting
later
on.
So
it's
a
little
bit
faster
in
certain
scenarios.
Okay,
let's
do
that
now.
I
have
this
here
as
well
okey-dokey.
A
So
now
I
created
that
connection,
and
I
said
okay,
everything
that
if
I
have
a
message
internally
to
broadcast,
send
it
out
to
to
the
websocket,
store
the
sender
and
now
I
need
to
use
this
and
then
I
need
to
broadcast
stuff,
and
this
is
done
by
listening
to
messages
from
the
websocket
incoming.
A
Let's
say
I
have
some
result,
which
is
user
rx
dot
next,
so
it's
an
is
it
stream?
It's
an
executive
stream.
I
get
little
messages
in.
I
wait
them.
I
wait
for
them
and
want
to
do
that.
Let's
broadcast
this
method,
so
I
create
a
little
function
broadcast
it's
an
async
function,
broadcast
message.
The
message
is
of
type
message:
that's
what
comes
in
from
the
websocket,
so
you
see
warp
filters
wsws
for
apps.
A
Okay,
that's
a
website
message,
that's
great
and
I
want
to
have
a
reference
on
my
users
and
then
I
say
okay,
for
if
let
sorry,
if
let
okay
string
message
or
sdr
message,
I
don't
I
don't
need
that.
I
guess
do
I
need
that.
A
I
don't
know
why
I
need
that.
I
guess
this
is
a
this
is
operation
that
could
fail,
but
I
want
to
have
it
because
I
want
to
send
strings.
I
want
to
check
if
this
is
a
string
message.
I
guess
this
is
what
I
want
to
do.
It's
been
a
while.
A
So
if
this
is
a
string
message,
let's
get
all
my
users
from
the
user
data
structure
and
it's
again
it's
a
alternating
stream,
so
I
have
some
sort
of
iterator.
No,
no,
it's
an
actual
iterator,
because
I'm
now
accessing
accessing
the
hashnet.
So
I'm
reading
the
rw
log
I'm
accessing
the
hashtag.
Now
I
have
an
actual
iterator
and
it's
okay
for
every
sender
that
I
have
here
send
send
a
clone
of
the
message
and.
A
Failed
to
send
message
so
this
should
be
it.
That's
the
broadcast
message
message
stuff,
that's
great,
and
here
I
say:
okay,
broadcast
message
and
the
message
is
result
and
unwrap
it
so
expect
fail
to
fetch
message.
That's
also
a
result,
type
already:
okay,
okay,
that
looks
good,
I'm
already
broadcasting.
A
Oh,
I
have
some
troubles
here.
I
guess
you
need
to
have
a
semicolon
in
there
now
we
are
good
this
one.
Okay,
that's
an
asynchronous
function,
so
I
definitely
need
to
wait
thanks
to
robert
analyzer
for
letting
me
know.
Okay
now,
for
the
last
part,
this
is
something
that
I
don't
need.
I
want
to
also
write
the
disconnect
message,
so
if
something,
if
one
of
the
users
is
run
away,
I
want
to
disconnect
them
disconnect
the
user
id
from
users.
A
Oh
that's
a
that
has
been
something
where
they
could
be
disconnect
now.
So
how
do
I
say
that
that
disconnect
news-
and
this
is
this-
is
great.
This
is
great
because
we
have
here
an
asynchronous
stream
and
this
one
returns
either
result
or
it
returns.
None,
and
when
does
it
return?
None
it
returns.
None
the
moment.
A
A
A
Reading
and
broadcasting
broadcasting
messages
disconnected
that's
sequential,
that's
that's
a
four
step
solution
to
having
a
web
sub
gate
application
and
the
only
thing
that
they
need
to
do
as
strengtheners
is
this
particular
and,
let's
say:
okay,
everything
that
comes
in
from
rx
forwarded
to
usage.
I
don't
want
to
to
have
that
in
my
synchronous
code,
right
particulars
in
my
sequential
code,
I
want
to
have
that
somewhere
else.
This
is
a
standard
task
work
on
that.
Just
forward
that
I
don't
care.
A
The
rest
is
bookkeeping,
establishing
a
connection
reading
and
broadcasting
messages
and
disconnect
in
the
end-
and
this
is
the
only
thing
that
I
need
to
put
aside
this-
only
little
token
spawn.
Of
course,
I
have
lots
of
awaits
in
there,
which
means
there's
lots
of
little
little
tasks,
because
basically,
every
await
this
is
some
sort
of
checkpoint
for
for
us
to
say.
Okay,
this
is
one
package,
one
part
in
this
future
state
machine
that
I
can
execute
independently.
A
This
is
with
every
await
block
that
there
is,
but
everything
that
I
need
to
shop
aside,
which
I
need
to
to
not
have
in
my
sequential
flow
of
code,
is
this
line.
That's
everything
this
couple
of
live
coding.
Let's
see
if
it
works,
I
don't
know
the
old
one
worked.
Look
at
that
there
you
go.
Let's
see,
cargo
run,
there's
the
trees.
Okay,
I
have
around
here
building
building
building.
In
the
meantime,
I'm
opening
up
another
connection
and
what
I'm
also
opening
up
is
for
you
to
look
at.
A
That's
that's
an
index
html
file.
It
does
nothing
but
loading
a
main
charge
file.
The
main.js
file
is
is
very,
very
simple.
It
creates
a
new
web,
socket
connection.
That's
that
it
opens
it.
That's
great!
It's
connected
on
message.
It
says:
okay,
receive
the
data
and
put
it
in
some
some
text
content
and
on
send
it
send
some
some
data.
That's
that's
order.
Is
it's
it's
nothing!
Nothing!
Fancy
at
all
just
getting
messages,
sending
messages
not
even
jquery
in
there,
because
I
yeah
clogged
it
together,
really
really
quick.
A
Okay
back
to
the
terminal.
Okay,
I
have
a
running
server
at
this
world,
so
if
I
say
girl,
localhost,
8080
hello,
then
I
get
hello
world.
If
I
do
it
with
hello,
rust
lintz,
I
get
hello
wrestling.
So
that's
great
that
already
works.
Now,
let's
see
what
happens.
If
I
want
to
curl
localhost
aesthetic
file,
that's
great!
You
can
see
that
I
tried
it
with
hectics.
First
now
I
switched
to
a
warp
that
looked
a
little
better.
A
So
let's
do
even
more
stuff.
Let's
open
up
a
browser.
Let's
go
to
localhost
8080.,
say
hello.
Oh
I
didn't
implement,
return,
sits
and
hello
cool.
Oh
that's
great!
I
just
got
everything
that
came
up
from
here
down
there.
That's
super
great!
Why
a
server
round
trip
that's
easier,
but
it's
even
better.
If
I
create
another
browser
window
down
there
and
say
how
are
you
if
I
click
here,
let's
see
hello,
it's
here
as
well.
A
Go
off
alrighty
and
that's
about
it,
that's
the
demo.
So,
in
the
end,
one
one
advice
that
they
can
give
you
if
you
want
to
develop
a
websocket
server
on
your
own.
That's
a
very
basic
demo
of
establishing
that
tokyo
gives
you
a
lot
of
stuff
to
wire
everything
together
to
plug
something
in
and
and
send
messages
via
channels
and
opening
connections.
So
this
is
all
part
of
tokyo
everything
that
happened
after
ws
after
I
had
this
websocket
connection
established
is
pure
tokyo.
A
It's
not
part
of
the
framework,
and
this
is
also
the
reason
why
I
was
able
to
do
that,
because
those
frameworks
like
like
warp
and
exim
they
build
on
top
of
those
tokyo
primitives,
which
means
everything
that
they
can't
provide
on
their
own.
You
can
do
yourself
with
those
tokyo,
libraries
if
you
have
a
web
server
like
acting.
A
So
if
you
have
a
web
server
like
like
rocket
a
framework
like
that
stuff,
like
that
becomes
in
my
experience
increasingly
harder
because
they
are
opinionated,
they
are
opinionated,
which
also
means
that
web
sockets
need
to
work
according
to
their
opinion,
opinion,
which
is
great.
You
know
you
want
to
have
an
opinionated
server
because
it
moves
you,
it
moves
you
fast
it.
A
It
brings
you
up
to
speed,
but
also
you
need
to
wait
until
they
decided
on
their
opinion
on
those
topics.
I
guess
dev
sockets
is
on
the
roadmap
for
rocket,
which
is
great,
I'm
looking
forward
to
that.
I'm
really
looking
forward
to
that,
how
they
how
they
solve
it,
because
it's.
I
think
this
is
a
challenge.
I
tried
to
implement
it
with
hectics
and
needed
to
work
with
the
actor
model,
which
was
way
too
tough
for
me
to
understand,
but
I
think
it's
doable
there
as
well.
A
There
are
some
tutorials
out
there.
I
found
this
to
be
the
easiest
version
and
I
think,
if
you
use
axon,
which
is
a
declarative
web
framework
from
the
tokyo
folks,
you
end
up
at
the
same
point
where
you
suddenly
get
all
those
primitives
in
your
hand
where
you
can
create
channels
where
you
can
create
sockets
and
you
can
split
them
and
you
can
write
them
and
you
can
read
them
and
then
you
can
do
all
the
message
passing
around
it.
So
that
was
my
talk.