[MUSIC PLAYING]
GRANT TIMMERMAN: Hey, Averi.
AVERI KITSCH: Hey, Grant.
What's up?
GRANT TIMMERMAN: Hey, you would not guess this.
Our critter watch app--
the traffic has been exploding in the last few months
with all the viewers checking out our cute animals.
And our product manager, Martin?
He's requested we introduce some realtime functionality
in our Cloud Run web app.
Specifically, we're looking to add realtime chat.
AVERI KITSCH: Wow, that sounds really cool.
GRANT TIMMERMAN: However, I'm not sure
where to start from the technical side of things.
I mean, there's HTTP Push, gRBC, Websockets, server-sent events,
polling, et cetera.
AVERI KITSCH: Oh, I can help.
Let's walk through our options.
[MUSIC PLAYING]
When it comes to realtime communication with services,
there are a couple options--
server-sent events, Websockets, and gRPC.
Server-sent events use the HTTP protocol
to create a persistent, one-directional connection
to send data from the server to the client.
Server-sent events are great for apps where you don't need
to send any data to the server.
GRANT TIMMERMAN: Oh, that sounds really good,
especially for like a Twitter-style news feed,
or maybe like a realtime dashboard of stock quotes.
But in this case, we need a chat app
to have bidirectional communication.
What are the other options?
AVERI KITSCH: Well, Cloud Run also
supports Websockets, which allows
us to open a two-directional connection between the client
and server.
Both the client and server can trigger communication
with one another, and both can send messages at the same time.
GRANT TIMMERMAN: Oh, that sounds amazing.
AVERI KITSCH: But wait, there is more.
You also mentioned gRPC, which can also enable
bidirectional communication.
But it uses HTTP/2 protocol and a remote procedure call
framework.
Though there is a web proxy for browser-server communication,
gRPC is mostly used for communication
between backend services.
So in this case, for a two-way chat app,
I would recommend Websockets.
GRANT TIMMERMAN: OK, that all sounds really clear.
Thanks.
So let's go and look at the code.
So it looks like in Martin's chat app,
we use Websockets using Socket.IO.
So how does this work?
AVERI KITSCH: Socket.IO is a nice wrapper for Websockets
and provides some additional features.
And just like using the Websocket API directly,
we will install and initialize Socket.IO on both the client
and the server.
The server will listen for the connection event, which
allows us to access the socket instance on both the client
and server.
The socket instance can emit and listen for messages.
GRANT TIMMERMAN: All right, cool.
So how do I then deploy this on Cloud Run?
AVERI KITSCH: One of the great parts about Websockets
is it comes out of the box with Cloud Run.
I can deploy this straight from my terminal using gcloud, which
can also handle containerizing the application by specifying
my source directory.
Now that it's deployed, let's test it out
by logging into a chat room.
GRANT TIMMERMAN: Oh, awesome.
And it looks like Martin's already in the app.
Oh, however, there seems to be an issue.
Messages are disappearing between sessions.
Do you know how to fix that, Averi?
AVERI KITSCH: I think I know what the problem is.
Cloud Run automatically scales container instances and load
balances every request between the available instances.
Therefore, your client may be connecting
to a different container instance,
and we haven't setup any way to share or store the data.
GRANT TIMMERMAN: So I guess we need to save the chat
messages to a database?
AVERI KITSCH: Well, a database doesn't quite
solve this problem, because you need to poll
the database for updates.
But we can avoid polling altogether
by using a Publisher/Subscriber broker like Redis.
Container instances can publish to a specific channel,
as well as subscribe for push updates.
GRANT TIMMERMAN: OK, so yeah, that sounds good.
How then do we add that?
AVERI KITSCH: First, we'll go create a Redis instance for us
to use via Cloud Memorystore.
Our Redis instance lives in a virtual private cloud,
which means it's not accessible from the outside internet.
So I'll also have to go create a serverless VPC access
connector, so our Cloud Run service can
connect to our Redis instance.
When we redeploy, we'll need our Redis IP and the name
of our serverless VPC access connector.
Can you update the app to subscribe and publish
to the Redis channels?
GRANT TIMMERMAN: Well, using Socket.IO, all I had to do
was update it to use the Redis adapter.
And it handles broadcasting events to all clients,
regardless of what container instances
they are connected to.
We can connect to the Redis instance
with the IP and port environment variables
when deploying our Cloud Run service.
AVERI KITSCH: Let's deploy our changes
and specify our new Redis environment
variable and the VPC connector.
GRANT TIMMERMAN: Oh, it works.
That was easy.
AVERI KITSCH: I'm so glad we got it working.
GRANT TIMMERMAN: I'm so glad, too.
And now I know the difference between server-side events,
Websockets, and gRPC.
It's so easy to use Websockets with Cloud Run
to add realtime chat to Martin's app.
AVERI KITSCH: And don't forget, with Websockets and Redis,
we're able to store and coordinate
our data with thousands of users across all of our container
instances.
GRANT TIMMERMAN: Well, thanks so much, Averi.
I'm sure Martin will be very happy.
Oh, it looks like I have a lot of messages to reply to.
Yeah, let me get to that.
AVERI KITSCH: Awesome.
See you next time.
GRANT TIMMERMAN: See you.
[MUSIC PLAYING]