The document discusses using Sinatra and Ruby to build web applications that utilize asynchronous JavaScript and XMLHttpRequest (AJAX) techniques. It demonstrates how to make HTTP requests to a Sinatra backend from JavaScript using XMLHttpRequest, Fetch API promises, and DOM manipulation. Various timing functions like setInterval and setTimeout are also explored. The document contains sample code for building a basic Sinatra API and incrementally enhancing the frontend JavaScript code to retrieve and display responses asynchronously.
Go for the paranoid network programmer, 3rd editionEleanor McHugh
Draft third edition of my #golang network programming and cryptography talk given to the Belfast Gophers Meetup. Now with an introduction to websockets.
Teaching Your Machine To Find FraudstersIan Barber
The slides from my talk at PHP Tek 11.
When dealing with money online, fraud is an ongoing problem for both
consumers and sellers. Researchers have been developing statistical
and machine learning techniques to detect shady sellers on auction
sites, spot fraudulent payments on e-commerce systems and catch click
fraud on adverts. While there is no silver bullet, you will learn to
flag suspicious activity and help protect your site from scammers
using PHP and a little help from some other technologies.
The case for building software with privacy as a primary concern with a discussion of how privacy and secrecy differ.
This is followed by an introduction to practical cryptographic techniques with code in Go which can be used to secure both communications channels and data stores.
Go for the paranoid network programmer, 3rd editionEleanor McHugh
Draft third edition of my #golang network programming and cryptography talk given to the Belfast Gophers Meetup. Now with an introduction to websockets.
Teaching Your Machine To Find FraudstersIan Barber
The slides from my talk at PHP Tek 11.
When dealing with money online, fraud is an ongoing problem for both
consumers and sellers. Researchers have been developing statistical
and machine learning techniques to detect shady sellers on auction
sites, spot fraudulent payments on e-commerce systems and catch click
fraud on adverts. While there is no silver bullet, you will learn to
flag suspicious activity and help protect your site from scammers
using PHP and a little help from some other technologies.
The case for building software with privacy as a primary concern with a discussion of how privacy and secrecy differ.
This is followed by an introduction to practical cryptographic techniques with code in Go which can be used to secure both communications channels and data stores.
An introduction to secrecy and privacy in software system design with code examples in Go demonstrating secure transport techniques with https, tcp/tls and encrypted udp.
Conheça um pouco mais sobre Perl 6, uma linguagem de programação moderna, poderosa e robusta que permitirá que você escreva código de forma ágil e eficiente.
Conférence données à l'Open World Forum, 05 octobre 2013.
Comment créer une base de données noSQL par paires clés-valeurs en moins d'une heure, en se basant sur le bibliothèques Nanomsg et LightningDB.
Using Mikko Koppanen's PHP ZMQ extension we will look at how you can easily distribute work to background processes, provide flexible service brokering for your next service oriented architecture, and manage caches efficiently and easily with just PHP and the ZeroMQ libraries. Whether the problem is asynchronous communication, message distribution, process management or just about anything, ZeroMQ can help you build an architecture that is more resilient, more scalable and more flexible, without introducing unnecessary overhead or requiring a heavyweight queue manager node.
PHP 7.1 contains new exciting features and improvements that can facilitate the life of many PHP developers. During the talk I will show some of these new features like nullable types, catching of multiple exceptions, the curl HTTP/2 server push support, void return types, Class constant visibility, authenticated encryption in OpenSSL with GCM and CCM modes, and more.
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Brian Sam-Bodden
Server-side browser push technologies have been around for a while in one way or another, ranging from from crude browser polling to Flash enabled frameworks. In this session you’ll get a code-driven walk-through on the evolution and mechanics of server-push technologies, including:
Server streaming
Polling and long Polling
Comet
Web Sockets
An introduction to secrecy and privacy in software system design with code examples in Go demonstrating secure transport techniques with https, tcp/tls and encrypted udp.
Conheça um pouco mais sobre Perl 6, uma linguagem de programação moderna, poderosa e robusta que permitirá que você escreva código de forma ágil e eficiente.
Conférence données à l'Open World Forum, 05 octobre 2013.
Comment créer une base de données noSQL par paires clés-valeurs en moins d'une heure, en se basant sur le bibliothèques Nanomsg et LightningDB.
Using Mikko Koppanen's PHP ZMQ extension we will look at how you can easily distribute work to background processes, provide flexible service brokering for your next service oriented architecture, and manage caches efficiently and easily with just PHP and the ZeroMQ libraries. Whether the problem is asynchronous communication, message distribution, process management or just about anything, ZeroMQ can help you build an architecture that is more resilient, more scalable and more flexible, without introducing unnecessary overhead or requiring a heavyweight queue manager node.
PHP 7.1 contains new exciting features and improvements that can facilitate the life of many PHP developers. During the talk I will show some of these new features like nullable types, catching of multiple exceptions, the curl HTTP/2 server push support, void return types, Class constant visibility, authenticated encryption in OpenSSL with GCM and CCM modes, and more.
Server-Side Push: Comet, Web Sockets come of age (OSCON 2013)Brian Sam-Bodden
Server-side browser push technologies have been around for a while in one way or another, ranging from from crude browser polling to Flash enabled frameworks. In this session you’ll get a code-driven walk-through on the evolution and mechanics of server-push technologies, including:
Server streaming
Polling and long Polling
Comet
Web Sockets
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...dantleech
Did you know that Generators and Pipelines can be combined in order to
solve software engineering problems?
Generators have been available to us in PHP for about 5 years, they are a very
powerful tool in a developers toolbox, they can be used to make your life
easier (e.g. as data providers in PHPUnit), to help process large amounts of
data, and even to enable co-operative multi-tasking.
Pipelines provide a way to compose complex tasks from stages.
In this talk we will briefly discuss a specific problem in PHPBench (a
benchmarking tool for PHP) which can be solved through the use of Generators
(and pipelines!). We will then explore both topics generally, before combining
them into an Incredible Machine in a live coding session.
The presentation focuses on Rails scaffolding as a good starting point for playing with Ext. The biggest integration task from a Rails point of view is providing the correct JSON data structures that Ext can process - a task that can be solved in a re-usable way. Passing data around between Rails controllers and views and the actual JavaScript code is another focal point.
The presentation features a preview version of Martin Rehfeld's Ext Scaffold Generator, soon to be announced as a official Rails plugin.
by Martin Rehfeld
Task Scheduling and Asynchronous Processing Evolved. Zend Server Job QueueSam Hennessy
Find out how Zend Server's Job Queues can give you the tools to effetely manage and debug the running of offline PHP tasks. Whether you need code that will execute at set intervals or you're offloading work from your web servers. Zend Server gives you a system that lets you develop the tasks easily as well as monitor and debug simply.
Un-Framework - Delivering Dynamic Experiences with HTML over the WireAndreas Nedbal
In the age of modern frontend frameworks like React and Vue that often require a lot of additional backend work to deliver dynamic content, there has been a renaissance of delivering HTML again, with a twist. With some specialized requests and HTML tags, the Hotwire suite of libraries enables dynamic adjusting of page contents with no to minimal JavaScript.
Going from zero to Puppet by Pedro Pessoa, Operations Engineer at Server Density.
Abstract: Using out-of-the-box Puppet for non-sysadmin work - steps from going from no config management to managing 100 nodes and allowing non-sysadmin tasks to be performed.
Speaker Bio: Linux admin for 10+ years. Java/Python/C developer 12+ years. Ops engineer at http://www.serverdensity.com - a hosted server and website monitoring service. Currently processing 12TB+ per month into MongoDB running on dedicated and virtual instances.
www.serverdensity.com/puppetcamp/
An experiment in a distributed approach to processing the real-time data generated by a large scale social media campaign. Presented at Cambridge Geek Nights 13.
Nesta sessão é objetivo mostrar as novas funcionalidade do HTML5, bem como a integração com tecnologias existentes.
Nesta sessão vão ser abordadas as diferenças existentes entre o HTML 4 e o HTML 5, vai ser possível perceber quais são as novas funcionalidades, novos controlos, integração com tecnologias existentes (CSS e Javascript). Vamos também discutir como fazer offline, ligações ao servidor para enviar ou receber informação e como utilizar o Canvas e o SVG para desenhar em HTML.
Comunidade NetPonto, a comunidade .NET em Portugal!
http://netponto.org
The first cut of a talk on the R&D process in software development, including taking an invention to patent.
Includes two sets of code examples. One is Forth implemented in a 1980s dialect of Basic.
The other introduces evolutionary prototyping using a hybrid ruby/bash methodology.
Generics, Reflection, and Efficient CollectionsEleanor McHugh
This is a talk about how we structure and collate information so as to effectively process it, the language tools Go provides to help us do this, and the sometimes frustrating tradeoffs we must make when marry the real world with the digital.
We'll start by looking at basic collection types in Go: array, slice, map, and channel. These will then be used as the basis for our own user defined types with methods for processing the collected items.
These methods will then be expanded to take functions as parameters (the higher order functional style popularised by languages such as Ruby) and by using Go's Reflection package we will generalise them for a variety of tasks and uses cases.
Reflection adds an interpreted element to our programs with a resulting performance cost. Careful design can often minimise this cost and it may well amortise to zero on a sufficiently large collection however there is always greater code complexity to manage. When the data to be contained in a user defined collection is homogenous we can reduce much of this complexity by using Generics and our next set of examples will demonstrate this.
At the end of this talk you should have some useful ideas for designing your own collection types in Go as well as a reasonable base from which to explore Reflection, Generics, and the Higher-Order Functional style of programming.
An introduction to functional programming with goEleanor McHugh
A crash course in functional programming concepts using Go. Heavy on code, light on theory.
You can find the examples at https://github.com/feyeleanor/intro_to_fp_in_go
Implementing virtual machines in go & c 2018 reduxEleanor McHugh
An updated version of my talk on virtual machine cores comparing techniques in C and Go for implementing dispatch loops, stacks & hash maps.
Lots of tested and debugged code is provided as well as references to some useful/interesting books.
Digital Identity talk from Strange Loop 2018 and Build Stuff Lithuania 2018 including walkthrough of the uPass system and the design principles behind it.
Don't Ask, Don't Tell - The Virtues of Privacy By DesignEleanor McHugh
This is a fairly technical overview of the considerations involved in architecting software systems to support privacy. Rather than focus on what the law demands - something which can change across time and jurisdictions - it looks at the real problems we need to solve to know as little about the users of computer systems as possible whilst achieving their needs.
Don't ask, don't tell the virtues of privacy by designEleanor McHugh
A very light intro talk on privacy, identity, and designing with the latter to preserve the former.
Probably makes no sense at all without the audio so if it whet's your appetite dig through my other decks on these topics. Most of those have code in for the more technically minded.
An overview of the uPass digital identity system. Covers the core problem domain and the end-to-end stack from liveness to black-box transaction store. Lots of diagrams, references to all the relevant patent applications and so forth.
An introduction to Go from basics to web through the lens of "Hello World", extracted from the Book "A Go Developer's Notebook" available from http://leanpub.com/GoNotebook
Finding a useful outlet for my many Adventures in goEleanor McHugh
A talk about my Leanpub-published living eBook: A Go Developer's Notebook. Buy my book? Write your own Book using Leanpub? Learn you some Golang for fun?
Implementing Software Machines in C and GoEleanor McHugh
The next iteration of the talk I gave at Progscon, this introduces examples of Map implementation (useful for caches etc.) and outlines for addition of processor core code in a later talk.
Sudheer Mechineni, Head of Application Frameworks, Standard Chartered Bank
Discover how Standard Chartered Bank harnessed the power of Neo4j to transform complex data access challenges into a dynamic, scalable graph database solution. This keynote will cover their journey from initial adoption to deploying a fully automated, enterprise-grade causal cluster, highlighting key strategies for modelling organisational changes and ensuring robust disaster recovery. Learn how these innovations have not only enhanced Standard Chartered Bank’s data infrastructure but also positioned them as pioneers in the banking sector’s adoption of graph technology.
Pushing the limits of ePRTC: 100ns holdover for 100 daysAdtran
At WSTS 2024, Alon Stern explored the topic of parametric holdover and explained how recent research findings can be implemented in real-world PNT networks to achieve 100 nanoseconds of accuracy for up to 100 days.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...Neo4j
Leonard Jayamohan, Partner & Generative AI Lead, Deloitte
This keynote will reveal how Deloitte leverages Neo4j’s graph power for groundbreaking digital twin solutions, achieving a staggering 100x performance boost. Discover the essential role knowledge graphs play in successful generative AI implementations. Plus, get an exclusive look at an innovative Neo4j + Generative AI solution Deloitte is developing in-house.
Threats to mobile devices are more prevalent and increasing in scope and complexity. Users of mobile devices desire to take full advantage of the features
available on those devices, but many of the features provide convenience and capability but sacrifice security. This best practices guide outlines steps the users can take to better protect personal devices and information.
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...DanBrown980551
Do you want to learn how to model and simulate an electrical network from scratch in under an hour?
Then welcome to this PowSyBl workshop, hosted by Rte, the French Transmission System Operator (TSO)!
During the webinar, you will discover the PowSyBl ecosystem as well as handle and study an electrical network through an interactive Python notebook.
PowSyBl is an open source project hosted by LF Energy, which offers a comprehensive set of features for electrical grid modelling and simulation. Among other advanced features, PowSyBl provides:
- A fully editable and extendable library for grid component modelling;
- Visualization tools to display your network;
- Grid simulation tools, such as power flows, security analyses (with or without remedial actions) and sensitivity analyses;
The framework is mostly written in Java, with a Python binding so that Python developers can access PowSyBl functionalities as well.
What you will learn during the webinar:
- For beginners: discover PowSyBl's functionalities through a quick general presentation and the notebook, without needing any expert coding skills;
- For advanced developers: master the skills to efficiently apply PowSyBl functionalities to your real-world scenarios.
Essentials of Automations: The Art of Triggers and Actions in FMESafe Software
In this second installment of our Essentials of Automations webinar series, we’ll explore the landscape of triggers and actions, guiding you through the nuances of authoring and adapting workspaces for seamless automations. Gain an understanding of the full spectrum of triggers and actions available in FME, empowering you to enhance your workspaces for efficient automation.
We’ll kick things off by showcasing the most commonly used event-based triggers, introducing you to various automation workflows like manual triggers, schedules, directory watchers, and more. Plus, see how these elements play out in real scenarios.
Whether you’re tweaking your current setup or building from the ground up, this session will arm you with the tools and insights needed to transform your FME usage into a powerhouse of productivity. Join us to discover effective strategies that simplify complex processes, enhancing your productivity and transforming your data management practices with FME. Let’s turn complexity into clarity and make your workspaces work wonders!
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
GridMate - End to end testing is a critical piece to ensure quality and avoid...ThomasParaiso2
End to end testing is a critical piece to ensure quality and avoid regressions. In this session, we share our journey building an E2E testing pipeline for GridMate components (LWC and Aura) using Cypress, JSForce, FakerJS…
UiPath Test Automation using UiPath Test Suite series, part 4DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 4. In this session, we will cover Test Manager overview along with SAP heatmap.
The UiPath Test Manager overview with SAP heatmap webinar offers a concise yet comprehensive exploration of the role of a Test Manager within SAP environments, coupled with the utilization of heatmaps for effective testing strategies.
Participants will gain insights into the responsibilities, challenges, and best practices associated with test management in SAP projects. Additionally, the webinar delves into the significance of heatmaps as a visual aid for identifying testing priorities, areas of risk, and resource allocation within SAP landscapes. Through this session, attendees can expect to enhance their understanding of test management principles while learning practical approaches to optimize testing processes in SAP environments using heatmap visualization techniques
What will you get from this session?
1. Insights into SAP testing best practices
2. Heatmap utilization for testing
3. Optimization of testing processes
4. Demo
Topics covered:
Execution from the test manager
Orchestrator execution result
Defect reporting
SAP heatmap example with demo
Speaker:
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
UiPath Test Automation using UiPath Test Suite series, part 5DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 5. In this session, we will cover CI/CD with devops.
Topics covered:
CI/CD with in UiPath
End-to-end overview of CI/CD pipeline with Azure devops
Speaker:
Lyndsey Byblow, Test Suite Sales Engineer @ UiPath, Inc.
In his public lecture, Christian Timmerer provides insights into the fascinating history of video streaming, starting from its humble beginnings before YouTube to the groundbreaking technologies that now dominate platforms like Netflix and ORF ON. Timmerer also presents provocative contributions of his own that have significantly influenced the industry. He concludes by looking at future challenges and invites the audience to join in a discussion.
2. pay attention!
all code is BSD 2-clause licensed
any resemblance to actual code &
conceptstm, living or dead, is probably
your imagination playing tricks on you
if you can make money from it you're
doing a damn sight better than we are!
5. require 'sinatra'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :message, ARGV[0] || "Hello World"
get '/' do
settings.message
end
6. require 'sinatra'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :message, ARGV[0] || "Hello World"
get '/' do
erb :html_02, locals: { message: settings.message }
end
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>TBE:Ruby HTML</title>
</head>
<body class='container'>
<h1>TBE:Ruby HTML</h1>
<div>
<%= message %>
</div>
</body>
</html>
9. AJAX
Asynchronous JavaScript and XML
•JavaScript is a single-threaded language
•but browsers are event-driven environments
•so JavaScript runtimes normally have three basic threads
•one to run the main script
•one to run scripts for high priority events
•one to run scripts for low priority events
•and each event can have callbacks de
fi
ned for it
10. AJAX
Asynchronous JavaScript and XML
•XMLHttpRequest
fi
rst appeared in MSXML
•available in IE5 as an ActiveX component from 1999
•similar functionality in other browsers from 2000 onwards
•fully supported in IE 7 2006
•despite its name it isn't restricted to XML
•most modern uses involve JSON
11. require 'sinatra'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :commands, ["A", "B", "C"]
get '/' do
erb :html_03, locals: { commands: settings.commands }
end
get '/:command' do
params[:command]
end
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>TBE:Ruby AJAX</title>
<script>
const element = (e = "event_log") => { return document.getElementById(e) };
const print = m => { element().innerHTML += `<div>${m}</div>` };
<% commands.each do |c, v| %>
function <%= c %>() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
print(this.responseText);
}
};
xhttp.open("GET", "<%= c %>", true);
xhttp.send();
}
<% end %>
</script>
</head>
<body>
<h1>TBE:Ruby AJAX</h1>
<h2>Actions</h2>
<div>
<% commands.each do |c, v| %>
<span>
<button type="button" onclick="<%= c %>();"><%= c %></button>
</span>
<% end %>
</div>
<h2>Server Output</h2>
<div id='event_log'></div>
</body>
</html>
12. require 'sinatra'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :commands, ["A", "B", "C"]
get '/' do
erb :html_04, locals: { commands: settings.commands }
end
get '/:command' do
if settings.commands.include? params[:command]
params[:command]
else
halt 404
end
end
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>TBE:Ruby AJAX</title>
<script>
const element = (e = "event_log") => { return document.getElementById(e) };
const print = m => { element().innerHTML += `<div>${m}</div>` };
function sendCommand(c) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
print(this.responseText);
} else {
print(`Request Failed: ${this.status}`);
}
}
};
xhttp.open("GET", c, true);
xhttp.send();
}
</script>
</head>
<body>
<h1>TBE:Ruby AJAX</h1>
<h2>Actions</h2>
<div>
<% commands.each do |c, v| %>
<span>
<button type="button" onclick="sendCommand('<%= c %>');"><%= c %></button>
</span>
<% end %>
</div>
<h2>Server Output</h2>
<div id='event_log'></div>
</body>
</html>
13. require 'sinatra'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :commands, ["A", "B", "C"]
get '/' do
erb :html_05, locals: { commands: settings.commands }
end
get '/:command' do
if settings.commands.include? params[:command]
params[:command]
else
halt 404
end
end
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>TBE:Ruby AJAX</title>
<script>
const element = (e = "event_log") => { return document.getElementById(e) };
const print = m => { element().innerHTML += `<div>${m}</div>` };
function sendCommand(c) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", c, false);
xhttp.send();
if (xhttp.status == 200) {
print(xhttp.responseText);
} else {
print(`Request Failed: ${xhttp.status}`);
}
}
</script>
</head>
<body>
<h1>TBE:Ruby AJAX</h1>
<h2>Actions</h2>
<div>
<% commands.each do |c, v| %>
<span>
<button type="button" onclick="sendCommand('<%= c %>');"><%= c %></button>
</span>
<% end %>
<span>
<button type="button" onclick="sendCommand('D');">D</button>
</span>
</div>
<h2>Server Output</h2>
<div id='event_log'></div>
</body>
</html>
27. require 'sinatra'
require 'sinatra-websocket'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :socket_url, ENV['SOCKET'] || '/'
set :commands, ["A", "B", "C"]
get '/' do
if !request.websocket?
erb :html_15, locals: {
url: settings.socket_url,
commands: settings.commands }
else
request.websocket do |ws|
ws.onopen do
warn "websocket connected"
ws.send "connection established"
end
ws.onmessage do |m|
warn "received: #{m}n"
if settings.commands.include? m
ws.send m
else
ws.send "unknown request #{m}"
end
end
ws.onclose do
warn "socket closed #{ws}"
end
end
end
end
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>TBE:Ruby WebSocket</title>
<script>
const element = (e = "event_log") => { return document.getElementById(e) };
const print = m => { element().innerHTML += `<div>${m}</div>` };
const addButton = (n, c) => {
element("action_buttons").appendChild(newButton(n, c)) };
function newButton(n, c) {
let b = document.createElement("BUTTON");
b.onclick = c;
b.appendChild(document.createTextNode(n));
return b;
}
window.onload = () => {
var socket = new WebSocket(`ws://${location.host}<%= url %>`);
socket.onopen = (e) => print("opening socket: <%= url %>");
socket.onclose = (e) => print("closing socket: <%= url %>");
socket.onerror = (e) => print(e.message);
socket.onmessage = (m) => { print(m.data) };
<% commands.each do |c, v| %>
addButton('<%= c %>', () => socket.send('<%= c %>'));
<% end %>
addButton('D', () => socket.send('D'));
</script>
</head>
<body>
<h1>TBE:Ruby WebSocket</h1>
<h2>Actions</h2>
<div id="action_buttons"></div>
<h2>Server Output</h2>
<div id='event_log'></div>
</body>
</html>
28. require 'sinatra'
require 'sinatra-websocket'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :socket_url, ENV['SOCKET'] || '/'
set :commands, ["A", "B", "C"]
set :sockets, []
get '/' do
if !request.websocket?
erb :html_16, locals: { url: settings.socket_url, commands: settings.commands }
else
request.websocket do |ws|
ws.onopen do
warn "websocket #{ws} connected"
m = "connection opened: #{ws.object_id}"
settings.sockets.each { |s| s.send m }
settings.sockets << ws
ws.send "connection established: #{ws.object_id}"
end
ws.onmessage do |m|
if settings.commands.include? m
EM.next_tick do
ws.send "message sent: #{m}"
m = "message received from #{ws.object_id}: #{m}"
settings.sockets.each { |s| s.send m unless s == ws }
end
else
ws.send "unknown command: #{m}"
end
end
ws.onclose do
warn "socket closed #{ws}"
settings.sockets.delete ws
m = "connection closed: #{ws.object_id}"
settings.sockets.each { |s| s.send m }
end
end
end
end
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>TBE:Ruby WebSocket</title>
<script>
const element = (e = "event_log") => { return document.getElementById(e) };
const print = m => { element().innerHTML += `<div>${m}</div>` };
const addButton = (n, c) => {
element("action_buttons").appendChild(newButton(n, c)) };
function newButton(n, c) {
let b = document.createElement("BUTTON");
b.onclick = c;
b.appendChild(document.createTextNode(n));
return b;
}
window.onload = () => {
var socket = new WebSocket(`ws://${location.host}<%= url %>`);
socket.onopen = (e) => print("opening socket: <%= url %>");
socket.onclose = (e) => print("closing socket: <%= url %>");
socket.onerror = (e) => print(e.message);
socket.onmessage = (m) => { print(m.data) };
<% commands.each do |c, v| %>
addButton('<%= c %>', () => socket.send('<%= c %>'));
<% end %>
addButton('D', () => socket.send('D'));
</script>
</head>
<body>
<h1>TBE:Ruby WebSocket</h1>
<h2>Actions</h2>
<div id="action_buttons"></div>
<h2>Server Output</h2>
<div id='event_log'></div>
</body>
</html>
29. require 'sinatra'
require 'sinatra-websocket'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :socket_url, ENV['SOCKET'] || '/'
set :commands, ["A", "B", "C"]
set :sockets, []
get '/' do
if !request.websocket?
erb :html_17, locals: { url: settings.socket_url, commands: settings.commands }
else
request.websocket do |ws|
ws.onopen do
warn "websocket #{ws} connected"
m = "connection opened: #{ws.object_id}"
settings.sockets.each { |s| s.send m }
settings.sockets << ws
ws.send "connection established: #{ws.object_id}"
end
ws.onmessage do |m|
if settings.commands.include? m
EM.next_tick do
ws.send "message sent: #{m}"
m = "message received from #{ws.object_id}: #{m}"
settings.sockets.each { |s| s.send m unless s == ws }
end
else
ws.send "unknown command: #{m}"
end
end
ws.onclose do
warn "socket closed #{ws}"
settings.sockets.delete ws
m = "connection closed: #{ws.object_id}"
settings.sockets.each { |s| s.send m }
end
end
end
end
require 'websocket-eventmachine-client'
server = ENV['SERVER'] || '127.0.0.1:3000'
server_url = "ws://#{server}"
EM.run do
puts "connecting to server: #{server_url}"
ws = WebSocket::EventMachine::Client.connect :uri => server_url
puts ws
ws.onopen do
puts "connected: #{server}"
end
ws.onmessage do |m, t|
puts m
end
ws.onerror do |e|
puts "error: #{e}"
end
ws.onclose do |c, m|
puts "disconnected: #{server} (#{c}, #{m})"
exit
end
end
30. require 'sinatra'
require 'sinatra-websocket'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :socket_url, ENV['SOCKET'] || '/'
set :commands, ["A", "B", "C"]
set :sockets, []
get '/' do
if !request.websocket?
erb :html_18, locals: { url: settings.socket_url, commands: settings.commands }
else
request.websocket do |ws|
ws.onopen do
warn "websocket #{ws} connected"
m = "connection opened: #{ws.object_id}"
settings.sockets.each { |s| s.send m }
settings.sockets << ws
ws.send "connection established: #{ws.object_id}"
end
ws.onmessage do |m|
if settings.commands.include? m
EM.next_tick do
ws.send "message sent: #{m}"
m = "message received from #{ws.object_id}: #{m}"
settings.sockets.each { |s| s.send m unless s == ws }
end
else
ws.send "unknown command: #{m}"
end
end
ws.onclose do
warn "socket closed #{ws}"
settings.sockets.delete ws
m = "connection closed: #{ws.object_id}"
settings.sockets.each { |s| s.send m }
end
end
end
end
require 'websocket-eventmachine-client'
server = ENV['SERVER'] || 'localhost:3000'
heartbeat = ENV['HEARTBEAT'] || 2
commands = ["A", "B", "C", "D"]
server_url = "ws://#{server}"
connected = false
def rotate_buffer b
r = b.shift
b << r
r
end
EM.run do
puts "connecting to server: #{server_url}"
ws = WebSocket::EventMachine::Client.connect(:uri => "ws://127.0.0.1:3000")
puts ws
ws.onopen do
puts "connected: #{server}"
connected = true
end
ws.onmessage do |m, t|
puts m
end
ws.onerror do |e|
puts "error: #{e}"
end
ws.onclose do |c, m|
puts "disconnected: #{server} (#{c}, #{m})"
end
timer = EventMachine::PeriodicTimer.new(heartbeat) do
ws.send rotate_buffer(commands) if connected
end
end
31. require 'sinatra'
require 'sinatra-websocket'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :socket_url, ENV['SOCKET'] || '/'
set :commands, [:HEARTBEAT, :PRINT, :ERROR]
set :sockets, []
set :heartbeat, 0
def message id, a, m, e = nil
{ "id" => id, "action" => a, "message" => m, "error" => e }
end
get '/' do
if !request.websocket?
erb :html_19, locals: { url: settings.socket_url, commands: settings.commands }
else
request.websocket do |ws|
ws.onopen do
warn "websocket #{ws} connected"
m = message 0, :PRINT, "connection opened: #{ws.object_id}"
settings.sockets.each { |s| s.send m.to_json }
ws.send message(0, :PRINT, "connection established: #{ws.object_id}").to_json
ws.send message(0, :HEARTBEAT, settings.heartbeat).to_json
settings.sockets << ws
end
ws.onmessage do |m|
m = JSON.parse m
m.merge! "id" => ws.object_id
case m["action"].to_sym
when :HEARTBEAT
settings.heartbeat = m["message"].to_i
EM.next_tick do
settings.sockets.each { |s| s.send m.to_json }
end
when :PRINT
EM.next_tick do
settings.sockets.each { |s| s.send m.to_json if s != ws }
end
else
ws.send message(0, :ERROR, m["message"], m["action"]).to_json
end
end
ws.onclose do
warn "socket closed #{ws}"
settings.sockets.delete ws
m = message(0, :PRINT, "connection closed: #{ws.object_id}").to_json
settings.sockets.each { |s| s.send m }
end
end
end
end
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8' />
<title>WebSocket EXAMPLE</title>
<script>
const element = (e = "event_log") => { return document.getElementById(e) };
const print = m => { element().innerHTML += `<div>${m}</div>` };
const addButton = (n, c) => { element("action_buttons").appendChild(newButton(n, c)) };
const sendMessage = (s, a, m) => {
s.send(JSON.stringify({ id: null, action: a, message: m }))
};
function newButton(n, c) {
let b = document.createElement("BUTTON");
b.onclick = c;
b.appendChild(document.createTextNode(n));
return b;
}
window.onload = () => {
var heartbeat = 0;
var socket = new WebSocket(`ws://${location.host}<%= url %>`);
socket.onopen = (e) => print("opening socket: <%= url %>");
socket.onclose = (e) => print("closing socket: <%= url %>");
socket.onerror = (e) => print(e.message);
socket.onmessage = (m) => {
let d = JSON.parse(m.data);
switch (d.action.toUpperCase()) {
case 'HEARTBEAT':
heartbeat = d.message;
element("counter").innerHTML = heartbeat;
print(`${d.id}: ${d.action} ${heartbeat}`);
break;
case 'PRINT':
print(`${d.id}: ${d.message}`);
break;
}
};
[0, 10, 100].forEach(i => {
addButton(`HEARTBEAT ${i}`, () => sendMessage(socket, 'HEARTBEAT', i));
});
}
</script>
</head>
<body>
<h1>WebSocket EXAMPLE</h1>
<h2>Actions</h2>
<div id="heartbeat">
HEARTBEAT: <span id="counter">0</span>
</div>
<div id="action_buttons"></div>
<h2>Server Output</h2>
<div id='event_log'></div>
</body>
</html>
32. require 'sinatra'
require 'sinatra-websocket'
set :server, %w[ thin mongrel webrick ]
set :bind, ENV['IP_ADDRESS'] || '0.0.0.0'
set :port, ENV['PORT'] || 3000
set :socket_url, ENV['SOCKET'] || '/'
set :commands, [:HEARTBEAT, :PRINT, :ERROR]
set :sockets, []
set :heartbeat, 0
def message id, a, m, e = nil
{ "id" => id, "action" => a, "message" => m, "error" => e }
end
get '/' do
if !request.websocket?
erb :html_19, locals: { url: settings.socket_url, commands: settings.commands }
else
request.websocket do |ws|
ws.onopen do
warn "websocket #{ws} connected"
m = message 0, :PRINT, "connection opened: #{ws.object_id}"
settings.sockets.each { |s| s.send m.to_json }
ws.send message(0, :PRINT, "connection established: #{ws.object_id}").to_json
ws.send message(0, :HEARTBEAT, settings.heartbeat).to_json
settings.sockets << ws
end
ws.onmessage do |m|
m = JSON.parse m
m.merge! "id" => ws.object_id
case m["action"].to_sym
when :HEARTBEAT
settings.heartbeat = m["message"].to_i
EM.next_tick do
settings.sockets.each { |s| s.send m.to_json }
end
when :PRINT
EM.next_tick do
settings.sockets.each { |s| s.send m.to_json if s != ws }
end
else
ws.send message(0, :ERROR, m["message"], m["action"]).to_json
end
end
ws.onclose do
warn "socket closed #{ws}"
settings.sockets.delete ws
m = message(0, :PRINT, "connection closed: #{ws.object_id}").to_json
settings.sockets.each { |s| s.send m }
end
end
end
end
require 'websocket-eventmachine-client'
require 'json'
server = ENV['SERVER'] || '127.0.0.1:3000'
heartbeat = ENV['HEARTBEAT'] || 1
server_url = "ws://#{server}"
connected = false
count = 0
EM.run do
puts "connecting to server: #{server_url}"
ws = WebSocket::EventMachine::Client.connect(:uri => server_url)
puts ws
ws.onopen do
puts "connected: #{server}"
connected = true
end
ws.onmessage do |m, t|
v = JSON.parse(m)
case v["action"].to_sym
when :PRINT
puts "#{v["id"]}: #{v["message"]}"
when :HEARTBEAT
count = v["message"].to_i
puts "#{v["id"]}: HEARTBEAT ==> #{count}"
when :ERROR
puts "ERROR: #{v["error"]} ==> #{v["message"]}"
end
end
ws.onerror do |e|
puts "error: #{e}"
end
ws.onclose do |c, m|
puts "disconnected: #{server} (#{c}, #{m})"
exit
end
timer = EventMachine::PeriodicTimer.new(heartbeat) do
count += 1
ws.send({ "action" => 'HEARTBEAT', "message" => count }.to_json) if connected
end
end