Outside the (Web) Box
Using Ruby with Other Protocols
Danielle Adams / RubyConf AU 2018
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/4598291/zebra-face_1f993.png)
I'm Danielle
@adamzdanielle
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3685120/Twitter_Logo_Blue.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3685121/GitHub-Mark-64px.png)
@danielleadams
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/4680238/large-contour-political-map-of-the-world.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3663126/2ojxjNAotkXGelMpEEC1Og-BA_logo-02_STACKED.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3695854/unnamed-1.gif)
Outside the (Web) Box
Using Ruby with Other Protocols
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3663289/giphy.gif)
april 2016
1. protocols
2. Ruby + machines
3. integration with services
protocols
What is an HTTP request?
How does a web server a handle request?
DNS
IP
Web Server
(ie. Puma)
Rack
Middleware
Web App
(ie. 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
july 2016
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3695858/30l84Tj.gif)
Ruby + machines
Ruby has a Socket library.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3735526/Screen_Shot_2017-04-24_at_5.12.14_PM.png)
"[...] 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, RubyConf!'
socket.close
# client.rb
TCPServer
Web 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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3733411/DatalogicLogoBlueHiRes.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3733416/Zebra_tech_logo15.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3733419/Intelligrated_logo.jpg)
demo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/4598291/zebra-face_1f993.png)
dec. 2016
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3731614/shoe_sorter.gif)
integration with services
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3708835/giphy.gif)
non-blocking
integration
Printer
Browser
???
Printer
Browser
Web
Server
Worker
# 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
TCP Server
Scanner
BAR CODE
Worker
Database
# 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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3731775/0f5406d2965b7eaab3832e0875c1e49c.png)
scanner
\x03092018
\x1FRA:1L:Sx:00:C0:NF
\x1F0340\r\n
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3733433/472ff2ff4cdc9b0cbf296b5dd82244ea.png)
middleware
shared code to handle different device protocols
demo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/4598291/zebra-face_1f993.png)
text +1 970 800 2583
OR
+61 428 431 280
your name and "title"
ie.
"Danielle
Cat Enthusiast"
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
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3733547/giphy-1.gif)
thank you!
@adamzdanielle
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3685120/Twitter_Logo_Blue.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/3685121/GitHub-Mark-64px.png)
@danielleadams
github.com/danielleadams/web-box-demo
slides.com/danielleadams/outside-the-web-box-rbau18
![](https://s3.amazonaws.com/media-p.slid.es/uploads/619021/images/4518958/_-wFNFqf_400x400.jpg)
Outside the Web Box
By Danielle Adams
Outside the Web Box
Slides for RubyConf AU 2018
- 1,517