class LiteCable::Server::Middleware

Rack middleware to hijack the socket

Public Class Methods

new(_app, connection_class:) click to toggle source
# File lib/lite_cable/server/middleware.rb, line 9
def initialize(_app, connection_class:)
  @connection_class = connection_class
  @heart_beat = HeartBeat.new
end

Public Instance Methods

call(env) click to toggle source
# File lib/lite_cable/server/middleware.rb, line 14
def call(env)
  return [404, {"Content-Type" => "text/plain"}, ["Not Found"]] unless
    env["HTTP_UPGRADE"] == "websocket"

  raise HijackNotAvailable unless env["rack.hijack"]

  env["rack.hijack"].call
  handshake = send_handshake(env)

  socket = ClientSocket::Base.new env, env["rack.hijack_io"], handshake.version
  init_connection socket
  init_heartbeat socket
  socket.listen
  [-1, {}, []]
end

Private Instance Methods

init_connection(socket) click to toggle source
# File lib/lite_cable/server/middleware.rb, line 42
def init_connection(socket)
  connection = @connection_class.new(socket)

  socket.onopen { connection.handle_open }
  socket.onclose { connection.handle_close }
  socket.onmessage { |data| connection.handle_command(data) }
end
init_heartbeat(socket) click to toggle source
# File lib/lite_cable/server/middleware.rb, line 50
def init_heartbeat(socket)
  @heart_beat.add(socket)
  socket.onclose { @heart_beat.remove(socket) }
end
send_handshake(env) click to toggle source
# File lib/lite_cable/server/middleware.rb, line 32
def send_handshake(env)
  handshake = WebSocket::Handshake::Server.new(
    protocols: LiteCable::INTERNAL[:protocols]
  )

  handshake.from_rack env
  env["rack.hijack_io"].write handshake.to_s
  handshake
end