Slide 1

Slide 1 text

@crsexton

Slide 2

Slide 2 text

@crsexton Unraveling the Cable How Action Cable Works rails websocket

Slide 3

Slide 3 text

@crsexton Hi, I'm Christopher! @crsexton Name Twitters

Slide 4

Slide 4 text

@crsexton About Me

Slide 5

Slide 5 text

@crsexton About Me

Slide 6

Slide 6 text

@crsexton About Me

Slide 7

Slide 7 text

@crsexton About Me

Slide 8

Slide 8 text

@crsexton Unraveling the Cable How Action Cable Works Enough of that Let's get to the technical bits already

Slide 9

Slide 9 text

@crsexton What should you get out of this?

Slide 10

Slide 10 text

@crsexton Not magic, not really

Slide 11

Slide 11 text

@crsexton

Slide 12

Slide 12 text

@crsexton

Slide 13

Slide 13 text

@crsexton def nand(a, b) !(a && b) end

Slide 14

Slide 14 text

@crsexton What is Action Cable?

Slide 15

Slide 15 text

@crsexton What is Action Cable? Chat Rooms

Slide 16

Slide 16 text

@crsexton What is Action Cable? Everyone makes chat rooms with it

Slide 17

Slide 17 text

@crsexton What is Action Cable? So many chat rooms

Slide 18

Slide 18 text

@crsexton What even is Action Cable?

Slide 19

Slide 19 text

@crsexton Why do we care? What does Action Cable get us?

Slide 20

Slide 20 text

@crsexton Why use Action Cable? Server to client push

Slide 21

Slide 21 text

@crsexton Why use Action Cable? Real Time*

Slide 22

Slide 22 text

@crsexton Why use Action Cable? Overhead

Slide 23

Slide 23 text

@crsexton How does it work? The Action Cable lifecycle

Slide 24

Slide 24 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 25

Slide 25 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE *YAWN* ~~ Anxiety ~~

Slide 26

Slide 26 text

@crsexton Action Cable Lifecycle 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client

Slide 27

Slide 27 text

@crsexton Action Cable Lifecycle 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client import { createConsumer } from "@rails/actioncable" export default createConsumer() app/javascript/channels/consumer.js

Slide 28

Slide 28 text

@crsexton Action Cable Lifecycle 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_user end protected def find_user User.find_by(id: cookies.signed[:user_id]) end end end app/javascript/channels/room_channel.js

Slide 29

Slide 29 text

@crsexton Action Cable Lifecycle 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client consumer.subscriptions.create("RoomChannel", { received(data) { // Handle Data }, speak: function(message) { return this.perform('speak', {message: message}); } }); app/javascript/channels/room_channel.js

Slide 30

Slide 30 text

@crsexton Action Cable Lifecycle 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client class RoomChannel < ApplicationCable::Channel def speak(data) Message.create! content: data["message"] end end app/channels/room_channel.rb consumer.subscriptions.create("RoomChannel", { speak: function(message) { return this.perform('speak', {message: message}); } }); app/javascript/channels/room_channel.js

Slide 31

Slide 31 text

@crsexton Action Cable Lifecycle 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client ActionCable.server.broadcast "room_channel", message: "OHAI World" app/models/message.rb

Slide 32

Slide 32 text

@crsexton Action Cable Lifecycle

Slide 33

Slide 33 text

@crsexton Action Cable Lifecycle C HANNELS STREAMS CONNECTIONS BROADCAST CONSUMERS

Slide 34

Slide 34 text

@crsexton All the terminology! C HANNELS STREAMS CONNECTIONS BROADCAST CONSUMERS

Slide 35

Slide 35 text

@crsexton 1. Client connects to cable Action Cable Lifecycle

Slide 36

Slide 36 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 37

Slide 37 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 38

Slide 38 text

@crsexton How does it open a connection? 1. Client connects to cable

Slide 39

Slide 39 text

@crsexton Client connects to cable webSocket = new WebSocket(url, protocols); action_cable.js

Slide 40

Slide 40 text

@crsexton Client connects to cable

Slide 41

Slide 41 text

@crsexton Client connects to cable

Slide 42

Slide 42 text

@crsexton How does the HTTP request work? 1. Client connects to cable

Slide 43

Slide 43 text

@crsexton Client connects to cable CLIENT SERVER

Slide 44

Slide 44 text

@crsexton Client connects to cable CLIENT SERVER TCP CONNECTION

Slide 45

Slide 45 text

@crsexton Client connects to cable CLIENT SERVER

Slide 46

Slide 46 text

@crsexton Client connects to cable GET / HTTP/1.0 Host: localhost:3000 CLIENT SERVER

Slide 47

Slide 47 text

@crsexton Client connects to cable GET / HTTP/1.0 Host: localhost:3000 CLIENT SERVER

Slide 48

Slide 48 text

@crsexton Client connects to cable GET / HTTP/1.0 Host: localhost:3000 HTTP/1.0 200 OK Content-Type: text/html Cache-Control: max-age=0 Set-Cookie: chocolate=chip ... CLIENT SERVER

Slide 49

Slide 49 text

@crsexton Client connects to cable How would we do that in Ruby?

Slide 50

Slide 50 text

@crsexton Client connects to cable require 'socket' body = <<~EOF GET / HTTP/1.0\r Host: localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read }

Slide 51

Slide 51 text

@crsexton Client connects to cable require 'socket' body = <<~EOF GET / HTTP/1.0\r Host: localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read } RAILS LOGS Completed 200 OK in 15ms (Views: 13.6ms | ActiveRecord: 0.2ms)

Slide 52

Slide 52 text

@crsexton require 'socket' body = <<~EOF GET / HTTP/1.0\r Host: localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read } Client connects to cable

Slide 53

Slide 53 text

@crsexton require 'socket' body = <<~EOF GET / HTTP/1.0\r Host: localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read } Client connects to cable RESPONSE HTTP/1.0 200 OK X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff X-Download-Options: noopen X-Permitted-Cross-Domain-Policies: none Referrer-Policy: strict-origin-when-cross-origin Content-Type: text/html; charset=utf-8 ETag: W/"9f4da7fe69623bb6fe6c3efe5c907c06" Cache-Control: max-age=0, private, must-revalidate Set-Cookie: _unravel_session=lq1ryiEWvEoFCSLXrzVlLdkAzpAhQPWJMS X-Request-Id: 38dde761-2dda-4f57-93cf-2a4b0f871912 X-Runtime: 0.016541 Unravel

Slide 54

Slide 54 text

@crsexton How do we get from HTTP to a socket? 1. Client connects to cable

Slide 55

Slide 55 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 56

Slide 56 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 57

Slide 57 text

@crsexton Web Server Client GET 200 OK

Slide 58

Slide 58 text

@crsexton Web Server Client GET 200 OK

Slide 59

Slide 59 text

@crsexton Web Server Client GET 101 Switch Protocol

Slide 60

Slide 60 text

@crsexton Web Server Client GET 101 Switch Protocol

Slide 61

Slide 61 text

@crsexton Web Server Client GET 101 Switch Protocol Web Socket

Slide 62

Slide 62 text

@crsexton Web Server Client GET 101 Switch Protocol Socket (ノ◕ヮ◕)ノ*:・゚✧ MAGIC

Slide 63

Slide 63 text

@crsexton Client connects to cable body = <<~EOF.gsub("\n", "\r\n") GET ws://localhost:3000/cable HTTP/1.1\r Host: localhost:3000\r Connection: Upgrade\r Upgrade: websocket\r Origin: http://localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read }

Slide 64

Slide 64 text

@crsexton Client connects to cable body = <<~EOF.gsub("\n", "\r\n") GET ws://localhost:3000/cable HTTP/1.1\r Host: localhost:3000\r Connection: Upgrade\r Upgrade: websocket\r Origin: http://localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read } LOGS Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)

Slide 65

Slide 65 text

@crsexton body = <<~EOF.gsub("\n", "\r\n") GET ws://localhost:3000/cable HTTP/1.1\r Host: localhost:3000\r Connection: Upgrade\r Upgrade: websocket\r Origin: http://localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read } Client connects to cable RESPONSE HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade WebSocket-Origin: http://localhost:3000 WebSocket-Location: ws://localhost:3000 puts sock.read

Slide 66

Slide 66 text

@crsexton body = <<~EOF.gsub("\n", "\r\n") GET ws://localhost:3000/cable HTTP/1.1\r Host: localhost:3000\r Connection: Upgrade\r Upgrade: websocket\r Origin: http://localhost:3000\r \r EOF Socket.tcp("localhost", 3000) {|sock| sock.print body sock.close_write puts sock.read } Client connects to cable RESPONSE HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade WebSocket-Origin: http://localhost:3000 WebSocket-Location: ws://localhost:3000 puts sock.read

Slide 67

Slide 67 text

@crsexton Client connects to cable

Slide 68

Slide 68 text

@crsexton Client connects to cable

Slide 69

Slide 69 text

@crsexton 2. Server confirms the connection Action Cable Lifecycle

Slide 70

Slide 70 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 71

Slide 71 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 72

Slide 72 text

@crsexton Rack 2. Server confirms the connection

Slide 73

Slide 73 text

@crsexton

Slide 74

Slide 74 text

@crsexton require 'rack' app = Proc.new do |env| [ '200', {'Content-Type' => 'text/html'}, ['Response Body'] ] end Rack::Handler::WEBrick.run app

Slide 75

Slide 75 text

@crsexton require 'rack' app = Proc.new do |env| [ '200', {'Content-Type' => 'text/html'}, ['Response Body'] ] end Rack::Handler::WEBrick.run app

Slide 76

Slide 76 text

@crsexton require 'rack' app = Proc.new do |env| [ '200', {'Content-Type' => 'text/html'}, ['Response Body'] ] end Rack::Handler::WEBrick.run app

Slide 77

Slide 77 text

@crsexton require 'rack' app = Proc.new do |env| [ '200', {'Content-Type' => 'text/html'}, ['Response Body'] ] end Rack::Handler::WEBrick.run app

Slide 78

Slide 78 text

@crsexton Rack Proc Proc Proc Proc

Slide 79

Slide 79 text

@crsexton Rack Proc Proc Proc Proc Request

Slide 80

Slide 80 text

@crsexton Rack Proc Proc Proc Proc Request call(env)

Slide 81

Slide 81 text

@crsexton Rack Proc Proc Proc Proc Request call(env) call(env)

Slide 82

Slide 82 text

@crsexton Rack Proc Proc Proc Proc Request call(env) call(env) call(env)

Slide 83

Slide 83 text

@crsexton Rack Proc Proc Proc Proc Request call(env) call(env) call(env) return

Slide 84

Slide 84 text

@crsexton Rack Proc Proc Proc Proc Request call(env) call(env) call(env) return return

Slide 85

Slide 85 text

@crsexton Rack Proc Proc Proc Proc Request call(env) call(env) call(env) return return return

Slide 86

Slide 86 text

@crsexton Rack Proc Proc Proc Proc Request call(env) call(env) call(env) return return return Response

Slide 87

Slide 87 text

@crsexton Rack Hijack 2. Server confirms the connection

Slide 88

Slide 88 text

@crsexton Rack Hijack Proc Proc Proc Proc

Slide 89

Slide 89 text

@crsexton Rack Hijack Proc Proc Proc Proc Request

Slide 90

Slide 90 text

@crsexton Rack Hijack Proc Proc Proc Proc Request call(env)

Slide 91

Slide 91 text

@crsexton Rack Hijack env['rack.hijack'].call Proc Proc Proc Proc Request call(env)

Slide 92

Slide 92 text

@crsexton Rack Hijack Proc Proc Proc Proc Request call(env)

Slide 93

Slide 93 text

@crsexton Rack Hijack # rails/actioncable/test/connection/client_socket_test.rb io, client_io = Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) env["rack.hijack"] = -> { env["rack.hijack_io"] = io }

Slide 94

Slide 94 text

@crsexton Rack Hijack # rails/actioncable/test/connection/client_socket_test.rb io, client_io = Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) env["rack.hijack"] = -> { env["rack.hijack_io"] = io }

Slide 95

Slide 95 text

@crsexton Server confirms the connection (‛ƅϪƅ)‛ “(゚ヮ゚“) Socket Connected

Slide 96

Slide 96 text

@crsexton Cookies 2. Server confirms the connection

Slide 97

Slide 97 text

@crsexton Server confirms the connection

Slide 98

Slide 98 text

@crsexton Server confirms the connection module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user end private def find_verified_user User.find_by(id: cookies.encrypted[:user_id]) end end end app/channels/application_cable/connection.rb

Slide 99

Slide 99 text

@crsexton Server confirms the connection module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user end private def find_verified_user User.find_by(id: cookies.encrypted[:user_id]) end end end app/channels/application_cable/connection.rb

Slide 100

Slide 100 text

@crsexton

Slide 101

Slide 101 text

@crsexton 3. Client subscribes to the channel Action Cable Lifecycle

Slide 102

Slide 102 text

@crsexton Subscription Handshake 3. Client subscribes to channel

Slide 103

Slide 103 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 104

Slide 104 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 105

Slide 105 text

@crsexton Client subscribes to the channel CLIENT SERVER {"type":"welcome"}

Slide 106

Slide 106 text

@crsexton Client subscribes to the channel CLIENT SERVER { "command":"subscribe", "identifier":"{'channel':'RoomChannel'}" }

Slide 107

Slide 107 text

@crsexton Client subscribes to the channel CLIENT SERVER { "identifier":"{'channel':'RoomChannel'}", "type":"confirm_subscription" }

Slide 108

Slide 108 text

@crsexton Client subscribes to the channel

Slide 109

Slide 109 text

@crsexton Redis Pub/Sub 3. Client subscribes to channel

Slide 110

Slide 110 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 111

Slide 111 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 112

Slide 112 text

@crsexton Redis CLI

Slide 113

Slide 113 text

@crsexton Redis Pub/Sub Server Client % %

Slide 114

Slide 114 text

@crsexton Redis Pub/Sub % redis-cli % Server Client

Slide 115

Slide 115 text

@crsexton Redis Pub/Sub % Server Client % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1

Slide 116

Slide 116 text

@crsexton Redis Pub/Sub % Server Client % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1 Reading messages... 1) "subscribe" 2) "chan1" 3) (integer) 1 ⏎

Slide 117

Slide 117 text

@crsexton Redis Pub/Sub % redis-cli Server Client % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1 Reading messages... 1) "subscribe" 2) "chan1" 3) (integer) 1

Slide 118

Slide 118 text

@crsexton Redis Pub/Sub % redis-cli 127.0.0.1:6379> Server Client % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1 Reading messages... 1) "subscribe" 2) "chan1" 3) (integer) 1 ⏎

Slide 119

Slide 119 text

@crsexton Redis Pub/Sub % redis-cli 127.0.0.1:6379> PUBLISH chan1 hi Server Client % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1 Reading messages... 1) "subscribe" 2) "chan1" 3) (integer) 1 ⏎

Slide 120

Slide 120 text

@crsexton Redis Pub/Sub % redis-cli 127.0.0.1:6379> PUBLISH chan1 hi Server Client ⏎ % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1 Reading messages... 1) "subscribe" 2) "chan1" 3) (integer) 1 1) "message" 2) "chan1" 3) "hi"

Slide 121

Slide 121 text

@crsexton Redis Pub/Sub Server Client % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1 Reading messages... 1) "subscribe" 2) "chan1" 3) (integer) 1 1) "message" 2) "chan1" 3) "hi" % redis-cli 127.0.0.1:6379> PUBLISH chan1 hi (integer) 1 127.0.0.1:6379> PUBLISH chan1 hi

Slide 122

Slide 122 text

@crsexton Redis Pub/Sub % redis-cli 127.0.0.1:6379> SUBSCRIBE chan1 Reading messages... 1) "subscribe" 2) "chan1" 3) (integer) 1 1) "message" 2) "chan1" 3) "hi" 1) "message" 2) "chan1" 3) "hi" % redis-cli 127.0.0.1:6379> PUBLISH chan1 hi (integer) 1 127.0.0.1:6379> PUBLISH chan1 hi (integer) 1 Server Client ⏎

Slide 123

Slide 123 text

@crsexton Redis Pub/Sub in Ruby?

Slide 124

Slide 124 text

@crsexton Redis Pub/Sub require 'redis' $redis = Redis.new $redis.subscribe('chan1') do |on| on.message do |channel, msg| puts "1) message" puts "2) #{channel}" puts "3) #{msg}" end end require 'redis' $redis = Redis.new $redis.publish "chan1", ARGV[0]

Slide 125

Slide 125 text

@crsexton Redis Pub/Sub Server % ruby sub.rb Client %

Slide 126

Slide 126 text

@crsexton Redis Pub/Sub Server % ruby sub.rb Client ⏎ %

Slide 127

Slide 127 text

@crsexton Redis Pub/Sub Server % ruby sub.rb Client % ruby pub.rb hi

Slide 128

Slide 128 text

@crsexton Redis Pub/Sub Server Client % ruby sub.rb 1) message 2) chan1 3) hi % ruby pub.rb hi % ⏎

Slide 129

Slide 129 text

@crsexton Redis Pub/Sub Server Client % ruby sub.rb 1) message 2) chan1 3) hi % ruby pub.rb hi
 % ruby pub.rb there

Slide 130

Slide 130 text

@crsexton Redis Pub/Sub Server Client % ruby sub.rb 1) message 2) chan1 3) hi 1) message 2) chan1 3) there % ruby pub.rb hi
 % ruby pub.rb there ⏎

Slide 131

Slide 131 text

@crsexton 4. Client sends messages to server Action Cable Lifecycle

Slide 132

Slide 132 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 133

Slide 133 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 134

Slide 134 text

@crsexton How do WebSockets send the data? 4. Client sends messages to server

Slide 135

Slide 135 text

@crsexton How WebSockets Work 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+ RFC 6455

Slide 136

Slide 136 text

@crsexton (Like this helps) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+ RFC 6455

Slide 137

Slide 137 text

@crsexton How WebSockets Work OPCODE LENGTH EXT LENGTH MASK DATA 2 BYTES Client Only 4 BYTES N BYTES

Slide 138

Slide 138 text

@crsexton 2-10 BYTES How WebSockets Work 2 BYTES 4 BYTES N BYTES OPCODE LENGTH EXT LENGTH MASK DATA Client Only

Slide 139

Slide 139 text

@crsexton OPCODE LENGTH EXT LENGTH MASK DATA Client Only How WebSockets Work 2 BYTES 4 BYTES N BYTES NOT TO SCALE

Slide 140

Slide 140 text

@crsexton How WebSockets Work

Slide 141

Slide 141 text

@crsexton 5. Server sends messages to client Action Cable Lifecycle

Slide 142

Slide 142 text

@crsexton Client Cable Server WebSocket Web Server Redis Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 143

Slide 143 text

@crsexton Client WebSocket Redis GET 101 Switch Protocol Web Server Workers Other Traffic Cable Server

Slide 144

Slide 144 text

@crsexton Client WebSocket Redis GET 101 Switch Protocol Web Server Workers Other Traffic Cable Server

Slide 145

Slide 145 text

@crsexton Client WebSocket Redis GET 101 Switch Protocol Web Server Workers Other Traffic Cable Server

Slide 146

Slide 146 text

@crsexton Sending messages to client 1. Broadcast to Redis Pub/Sub 2. Publish to Cable Server 3. Send message over socket 4. Receive message in consumer

Slide 147

Slide 147 text

@crsexton Sending messages to client ActionCable .server .broadcast "my_channel", message: "hi", one: 1 JSON { "identifier" : "{\"channel\":\"MyChannel\"}", "message" : { "message" : "hi", "one" : 1 } }

Slide 148

Slide 148 text

@crsexton Sending messages to client import consumer from "./consumer" window.room = consumer.subscriptions.create("RoomChannel", { received(data) { var div = document.getElementById('messages'); div.innerHTML += data['message']; }, }); JSON { "message" : { "message" : "hi", "one" : 1 }, "identifier" : "{\"channel\":\"RoomChannel\"}" }

Slide 149

Slide 149 text

@crsexton What just happened? Let's recap Did anyone get all that? Narrator: "No"

Slide 150

Slide 150 text

@crsexton WHEW

Slide 151

Slide 151 text

@crsexton Client Cable Server WebSocket Web Server Redis Other Traffic Workers Other Traffic GET 101 Switch Protocol PUBLISH/SUBSCRIBE

Slide 152

Slide 152 text

@crsexton Client Cable Server Web Server Redis Other Traffic

Slide 153

Slide 153 text

@crsexton Recap 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client Cable Server Web Server Redis Other Traffic Client

Slide 154

Slide 154 text

@crsexton Recap 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client Cable Server Web Server Redis Other Traffic Client

Slide 155

Slide 155 text

@crsexton Recap 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client Cable Server Web Server Redis Other Traffic Client

Slide 156

Slide 156 text

@crsexton Recap 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client Cable Server Web Server Redis Other Traffic Client

Slide 157

Slide 157 text

@crsexton Recap 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client Cable Server Web Server Redis Other Traffic Client

Slide 158

Slide 158 text

@crsexton Recap 1. Client connects to cable 2. Server confirms the connection 3. Client subscribes to channel 4. Client sends messages to server 5. Server sends messages to client Cable Server Web Server Redis Other Traffic Client

Slide 159

Slide 159 text

@crsexton Thanks! Questions?

Slide 160

Slide 160 text

@crsexton I'm Christopher, bye! @crsexton Also answers to "hey you" Come say "hi"