Real-time Messaging to Webapps from a Production Database
David Johnson, djohnson@ommc.com, www.djohn89.com
Outline
Automotive Assembly Line
Break
TCP Sockets Review
Websockets
The goal of this talk is to describe an automotive assembly line and to encourage web developers to use websockets in their web applications. See RFC 6455 and Websocket API for more details.
PLC turns bit on (conveyor stopped due to no torque at station 6)
Communication program sees bit, logs to database and sends CometD message to Andon Board servlet: {type: Alarm, Line: ML1, Station: 6, Message: Torque Overrun DC Tool}
Andon Board javascript receives message, displays alarm to alert supervisor
Andon Board Example
Broadcast Elimination
Printed broadcasts were wasteful ($50,000+ per year)
... and became unnecessary (computer error proofing, barcode scanners, digital displays).
So we replaced them with tablet PCs displaying a webpage
Broadcast Display Webapp
Broadcast Display webapp receives messages from RFID system: {type: Arrival, Line: ML2, Station: 4, SKID: A053, VIN: 1C4... }
It receives messages as new vehicle orders come in (for materials tracking)
It sends messages to the RepairTech webapp (to request repairs)
RepairTech Webapp
This webapp tracks vehicles that need repairs
Repair Technicians physically fix the vehicle and then fill out a form
Quality Inspectors double-check the repairs
Internal statistics are calculated (FTC, MTTF)
Messaging Overview
Using webapps has been very helpful for efficient communication of events in MES (Alarms, RFID, etc.)
Websockets are a natural fit for this system
CometD integrated easily with existing Java infrastructure and internal websites
Conclusions - Automotive Assembly Line
Torque tools, barcode scanners, RFID, and alarms comprise the Manufacturing Execution System
Messaging patterns vary based on physical design and engineering constraints
Andon boards, Broadcast Display, and RepairTech use Websockets to display information to production team
Break
TCP Sockets Review
TCP connects two endpoints (defined by IP addresses and port numbers) and allows symmetric, byte-oriented data transmission over a socket (as if reading from and writing to a file).
Think of the socket as a file.
You have to define a message format!
The server listens on a port; the client connects. Afterward, transmission is symmetric.
How many bytes can you read if you request to read 1000 bytes?
TCP Sockets as File IO
Disk file operations: open, close, read, write, seek. File format is defined by application
Socket operations: open, close, read, write. No seek. Network format is defined by application
Asynchronous vs. synchronous operations: framing, latency, reliability, complexity
Sockets are very similar to disk files, but the reliability is much worse.
How much data did you actually read or write? How do you know if the other party is still there? Can your program block forever?
Classic Socket Problems - Partial buffer reads
You request to read 100 bytes (a complete message) from the socket. You receive 30 bytes.
Message Framing fixes this problem. Messages must have a length prefix or specific bytes at the beginning and end. Continue reading 70 bytes.
You read 170 bytes. The 70 bytes are for the first message; the next 100 bytes are for a subsequent message.
TCP guarantees the order of data is preserved, but it doesn't guarantee the size of any individual operations.
You request to read 100 bytes, but you never receive any data. How do you know if the other party is still there?
Keepalive messages fix this problem. Every 15 seconds, you write a dummy message to the server, which echoes another dummy message (ping/pong). No Keepalive means the connection dropped.
TCP can only detect network failures by writing data to the socket. Reading is a silent operation.
Classic Socket Problems - Asynchronous Operations
Can your program block forever? You request to write 10,000 bytes (100 messages), but the OS only writes up to 1,000 bytes in each data frame.
The write() calls begin to block, waiting for acknowledgement because the receiver has a finite buffer size (the TCP window).
TCP cannot guarantee that a read or write operation completes by any specific time, so your program must be asynchronous to remain responsive to the user. Use callbacks, events, threads, or queues.
Solutions to Classic Socket Problems
Any TCP-based protocol must use Message Framing, Keepalive Messages, and Asynchronous Operations.
A good protocol and library will fix these problems for you, but your application must be aware of them
Websockets includes free Message Framing, but your library still needs to provide Keepalive Messages, and your program must still use Asynchronous Operations.
Long Polling is an older alternative to websockets. Think of an HTTP request that doesn't end.
Every request with long polling must resend all headers (~800 bytes out of a 1500 byte MTU). Cookies can eat up a lot of bandwidth. Most headers don't change, anyway.
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer();
server.listen(8080, function() { ... });
wsServer = new WebSocketServer({ httpServer: server });
wsServer.on('request', function(request) { ... } );
Message Queues
Additional message queue functionality you'll need: more detailed message format, client identification, channels, publish and subscribe, at least once delivery, idempotent messages
client identification: a unique identifier is assigned to each client
message identification: a unique identifier is assigned to each message (by application ID, timestamps, sequence numbers, etc.)
message channels: messages are sent on a channel, which segments clients
publish and subscribe: clients can publish messages to a channel, which relays them to some number of subscribing clients
at least once delivery: the server takes ownership of a message and resends it to clients until they acknowledge receiving it, then sends a confirmation to the originator
idempotent messages: receiving the same message more than once has no effect.
Additional Properties
message persistance: if you need persistance, use a real message queue system (not just websockets)
Atomicity, Consistency, Isolation, Durability: if you need these, use a database