Websocket Gui
This gem uses Sinatra, EventMachine, and WebSockets to make it easy to use the browser as a GUI for Ruby apps that would otherwise be stuck in the console.
Using Websocket Gui
To use this gem, make a class that extends WebsocketGui::Base and a HTML/JS file to serve as the GUI.
Configuration
The following configuration options are available:
- :socket_port (8080)
- :socket_host (127.0.0.1)
- :http_port (3000)
- :http_host (127.0.0.1)
- :view (:index)
- :tick_interval (nil)
The options can be set in several ways, each level overriding the previous: 1 In declaring your subclass of WebsocketGui::Base (like tick_interval below) 1 By passing an options hash to the initializer 1 By passing an options hash to the run! method
Sample Code: project-root/app.rb
require 'websocket-gui'
class App < WebsocketGui::Base
# specify the name of the file containing the HTML of the app (this is a single-page app)
# ex. Look in root directory for frontendfile.erb instead of index.erb (which is the default)
#view :frontendfile
# set the time (seconds) between calls to 'on_tick'
# if nil (default), on_tick will not fire
tick_interval 0.1
# code for the on_tick event
on_tick do |connected|
@tick_block.call(connected)
end
# code for the on_socket_open event
on_socket_open do |handshake|
socket_send "Welcome!!!"
puts "Client connection opened:"
puts "#{handshake.inspect}"
end
# code for the on_socket_recv event
on_socket_recv do |msg|
puts "Received message from client: #{msg.strip}"
socket_send "I received your message: #{msg.strip}"
end
# code for the on_socket_close event
on_socket_close do
puts "Socket closed."
end
# custom handler
# trigger by sending JSON like this from the client:
# { event: 'custom_buttom_click', params: { ...} }
on_custom_button_click do |params|
socket_send "Custom event triggered! Params provided were:"
params.each do |k,v|
socket_send "#{k} = #{v}"
end
end
end
# specify options in the constructor and/or the run method.
instance = App.new http_port: 3000, http_host: '127.0.0.1'
instance.run! socket_port: 8080, socket_host: '127.0.0.1'
Sample Code: project-root/index.erb
<!doctype html>
<html>
<head>
<title>Test Web Sockets</title>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<div id="connectedContainer" style="display:none;">
<textarea id="input"></textarea>
<input type="button" id="send" value="Send" />
<ul id="output"></ul>
<input type="button" id="disconnect" value="Disconnect" />
</div>
<div id="notConnectedContainer">
<input type="button" id="connect" value="Connect" />
</div>
<script type="text/javascript">
var socket;
var connect = function () {
socket = new WebSocket("ws://localhost:8080");
var writeMessage = function (msg) {
$("<li></li>").text (msg).appendTo ($("#output"));
};
var sendEvent = function (event, params) {
socket.send (JSON.stringify ({
event: event,
params: params
}));
};
socket.onmessage = function (evt) {
writeMessage (evt.data);
};
socket.onclose = function () {
writeMessage ("Socket Closed!");
$("#connectedContainer").hide ();
$("#notConnectedContainer").show();
$("#output li").remove ();
}
socket.onopen = function () {
writeMessage ("Socket Opened!");
$("#connectedContainer").show ();
$("#notConnectedContainer").hide ();
}
$("#send").on ('click', function () {
var input = $("#input");
if (input.val ())
{
socket.send(input.val ());
input.val ('');
}
});
$("#custom").on ('click', function () {
sendEvent('custom_button_click', {
a: 1,
b: "Two",
c: "III"
});
});
}
$("#connect").on ('click', function () { connect (); } );
$("#disconnect").on ('click', function () { socket.close (); });
</script>
</body>
</html>
file structure
project-root/
app.rb
index.erb
... (up to you)
running the app (from the project dir)
$ ruby app.rb
This will start the socket server and sinatra, and launch a browser with your view.