Outside the (Web) Box

Using Ruby with Other Protocols

Danielle Adams / RailsConf 2017    

I'm Danielle

@adamzdanielle

@danielleadams

Notable Achievements

Outside the (Web) Box

Using Ruby with Other Protocols

spring 2016

1. protocols


2. Ruby + machines

 


3. integration with Rails

protocols

What is an HTTP request?

How does Rails handle requests?

DNS

IP

App Server

(ie. Puma)

Rack
Middleware

Rails

What is TCP?

"The Transmission Control Protocol is intended for use as a highly reliable host-to-host protocol between hosts in packet-switched computer communication networks, and in interconnected systems of such networks."

 

RFC (1981)

 

TCP

RFC

A document drafted to be reviewed by interested parties.

How is TCP different from HTTP?

Internet Protocol Suite

application layer

transport layer

internet layer

link layer

physical layer

summer 2016

Ruby + machines

Ruby has a Socket library.

"[...] the TCP provides a set of addresses or ports within each host. Concatenated with the network and host addresses from the internet communication layer, this forms a socket."

 

RFC (1981)

 

socket

TCPSocket

Server

(ie. Rails App)

Database
(ie. SQLite)

Client
(ie. Browser)

Server

(ie. Printer)

Client

???

open a socket

in order to communicate with hardware, a TCP socket needs to be established

require 'socket'
socket = TCPSocket.new '127.0.0.1', 8080
socket.write 'Hello, RailsConf!'
socket.close
# client.rb

TCPServer

Server

(ie. Rails App)

Database
(ie. SQLite)

Client
(ie. Browser)

Server

Client

loop do
  client = server.accept





end
require 'socket'
server = TCPServer.new 8080
puts "There's a new client: #{client}"
puts client.read
# server.rb
client.close

machines

there are lots of types of servers and clients

demo

winter 2016

integration with Rails

non-blocking
integration

Printer

Browser

???

Printer

Browser

Rails

Controller

Worker

app/
\_ controllers/
  \_ labels_controller.rb
\_ workers/
  \_ printer_worker.rb
config/
config.ru
db/
lib/
public/
tests/
# app/controllers/labels_controller.rb

def create
  label = Label.create! label_params
  
  PrinterWorker.perform_async label.zpl
end


# app/workers/printer_worker.rb

sidekiq_options queue: 'devices'

def perform(message)
  socket = TCPSocket.new

  socket.write message
  socket.close
end
# app/controllers/labels_controller.rb

def create
  label = Label.create! label_params
  
  PrinterWorker.perform_async label.zpl
end


# app/workers/printer_worker.rb

sidekiq_options queue: 'devices'

def perform(message)
  socket = TCPSocket.new

  socket.write message
  socket.close
end

???

Scanner

BAR CODE

Database

Daemon

Scanner

BAR CODE

Worker

Database

app/
\_ workers/
  \_ scan_worker.rb
config/
config.ru
db/
lib/
\_ daemons/
  \_ scan.rb
public/
tests/
# bin/scans

require_relative '../lib/daemons/scan'

Daemons::Scan.listen


# lib/daemons/scan.rb

require 'socket'
require 'sidekiq'

server = TCPServer.new port
client = server.accept

while message = client.gets
  ScanWorker.perform_async(message)
end

client.close
# bin/scans

require_relative '../lib/daemons/scan'

Daemons::Scan.listen


# lib/daemons/scan.rb

require 'socket'
require 'sidekiq'

server = TCPServer.new
client = server.accept

while message = client.gets
  ScanWorker.perform_async(message)
end

client.close

device protocols

not all devices support the same protocol

Zebra Programming Language is a label-definition and printer-control language.

ZPL

printer

^XA
^FO15,15^BQN,2,6^FDID-10^FS
^CF0,50
^FO150,30^FDHello, my name is:^FS
^CF0,120
^FO150,90^FDDanielle^FS
^CF0,50
^FO150,200^FDTitle: Software Engineer^FS
^XZ

scanner

\x04252017
\x1FRA:1L:Sx:00:C0:NF
\x1F0340\r\n

middleware

shared code to handle different device protocols

demo

obstacles

Multi socket support

Not all hardware supports connections to multiple sockets. Some only support one at a time.

Persistence

A framework may not support persistent open sockets.

Privacy

Not all hosting services support the level of privacy that may be needed for a device that is online.

Testing

Integration with hardware becomes difficult to mock and requires lots of manual testing.

epilogue

thank you!

@adamzdanielle

@danielleadams

github.com/danielleadams/web-box-demo

slides.com/danielleadams/outside-the-web-box

Outside the Web Box

By Danielle Adams

Outside the Web Box

Slides for RailsConf 2017

  • 2,374