plezi 0.12.22 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/LICENSE.txt +17 -18
- data/README.md +54 -698
- data/Rakefile +7 -4
- data/bin/config.ru +22 -0
- data/{test → bin}/console +4 -6
- data/bin/hello_world +52 -0
- data/bin/setup +8 -0
- data/exe/plezi +145 -0
- data/lib/plezi.rb +24 -137
- data/lib/plezi/activation.rb +28 -0
- data/lib/plezi/api.rb +62 -0
- data/lib/plezi/controller/controller.rb +259 -0
- data/lib/plezi/controller/controller_class.rb +176 -0
- data/lib/plezi/controller/cookies.rb +40 -0
- data/lib/plezi/helpers.rb +60 -0
- data/lib/plezi/rake.rb +2 -24
- data/lib/plezi/render/erb.rb +34 -0
- data/lib/plezi/render/has_cache.rb +36 -0
- data/lib/plezi/render/markdown.rb +63 -0
- data/lib/plezi/render/render.rb +49 -0
- data/lib/plezi/render/sass.rb +55 -0
- data/lib/plezi/render/slim.rb +33 -0
- data/lib/plezi/router/adclient.rb +23 -0
- data/lib/plezi/router/assets.rb +67 -0
- data/lib/plezi/router/errors.rb +29 -0
- data/lib/plezi/router/route.rb +112 -0
- data/lib/plezi/router/router.rb +120 -0
- data/lib/plezi/version.rb +1 -1
- data/lib/plezi/websockets/message_dispatch.rb +91 -0
- data/lib/plezi/websockets/redis.rb +55 -0
- data/plezi.gemspec +25 -16
- data/resources/404.erb +5 -4
- data/resources/500.erb +5 -4
- data/resources/{500.html → 503.html} +8 -9
- data/resources/client.js +253 -0
- data/resources/config.ru +5 -36
- data/resources/ctrlr.rb +34 -0
- data/resources/gemfile +4 -0
- data/resources/mini_app.rb +28 -82
- data/resources/mini_exec +7 -0
- data/resources/mini_welcome_page.html +0 -0
- data/resources/procfile +3 -0
- data/resources/rakefile +4 -8
- data/resources/routes.rb +9 -26
- data/resources/{websockets.js → simple-client.js} +3 -3
- metadata +60 -85
- data/bin/plezi +0 -104
- data/docs/async_helpers.md +0 -245
- data/docs/controllers.md +0 -27
- data/docs/logging.md +0 -49
- data/docs/routes.md +0 -209
- data/docs/websockets.md +0 -213
- data/lib/plezi/builders/ac_model.rb +0 -59
- data/lib/plezi/builders/app_builder.rb +0 -137
- data/lib/plezi/builders/builder.rb +0 -43
- data/lib/plezi/builders/form_builder.rb +0 -27
- data/lib/plezi/common/api.rb +0 -92
- data/lib/plezi/common/cache.rb +0 -122
- data/lib/plezi/common/defer.rb +0 -21
- data/lib/plezi/common/dsl.rb +0 -94
- data/lib/plezi/common/redis.rb +0 -65
- data/lib/plezi/common/renderer.rb +0 -141
- data/lib/plezi/common/settings.rb +0 -52
- data/lib/plezi/handlers/controller_core.rb +0 -106
- data/lib/plezi/handlers/controller_magic.rb +0 -284
- data/lib/plezi/handlers/http_router.rb +0 -205
- data/lib/plezi/handlers/placebo.rb +0 -112
- data/lib/plezi/handlers/route.rb +0 -216
- data/lib/plezi/handlers/session.rb +0 -109
- data/lib/plezi/handlers/stubs.rb +0 -156
- data/lib/plezi/handlers/ws_identity.rb +0 -253
- data/lib/plezi/handlers/ws_object.rb +0 -308
- data/lib/plezi/helpers/http_sender.rb +0 -84
- data/lib/plezi/helpers/magic_helpers.rb +0 -104
- data/lib/plezi/helpers/mime_types.rb +0 -1995
- data/lib/plezi/oauth.rb +0 -5
- data/lib/plezi/oauth/auth_controller.rb +0 -229
- data/logo/dark.png +0 -0
- data/logo/light.png +0 -0
- data/logo/sign.png +0 -0
- data/resources/404.haml +0 -121
- data/resources/404.html +0 -124
- data/resources/404.slim +0 -120
- data/resources/500.haml +0 -120
- data/resources/500.slim +0 -120
- data/resources/Gemfile +0 -86
- data/resources/code.rb +0 -8
- data/resources/controller.rb +0 -142
- data/resources/database.yml +0 -33
- data/resources/db_ac_config.rb +0 -59
- data/resources/db_dm_config.rb +0 -51
- data/resources/db_sequel_config.rb +0 -33
- data/resources/en.yml +0 -204
- data/resources/haml_config.rb +0 -6
- data/resources/i18n_config.rb +0 -14
- data/resources/initialize.rb +0 -49
- data/resources/mini_exec.rb +0 -7
- data/resources/oauth_config.rb +0 -24
- data/resources/plezi_client.js +0 -198
- data/resources/plezi_websockets.html +0 -47
- data/resources/redis_config.rb +0 -42
- data/resources/slim_config.rb +0 -11
- data/resources/welcome_page.html +0 -272
- data/test/dispatch +0 -58
- data/test/hello_world +0 -13
- data/test/plezi_tests.rb +0 -581
data/resources/404.erb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
<%
|
2
2
|
# # consider replacing the Html with the following Ruby code:
|
3
|
-
#
|
3
|
+
# cookies[:notice] = "Sorry, we couldn't find #{request.original_path} - error code 404"
|
4
|
+
# response.redirect_to "/"
|
4
5
|
# # OR
|
5
|
-
# render
|
6
|
+
# render("layout") { render("template") }
|
6
7
|
%><!DOCTYPE html>
|
7
8
|
<head>
|
8
9
|
<style>
|
@@ -46,7 +47,7 @@
|
|
46
47
|
}
|
47
48
|
h3
|
48
49
|
{
|
49
|
-
font-family: 'Architects Daughter', cursive;
|
50
|
+
font-family: 'Architects Daughter', cursive;
|
50
51
|
background-color: #44518E;
|
51
52
|
color: #C6CCE7;
|
52
53
|
text-align: left;
|
@@ -80,7 +81,7 @@
|
|
80
81
|
{
|
81
82
|
font-size: 1em;
|
82
83
|
padding: 0 1em;
|
83
|
-
margin: 0.5em 0;
|
84
|
+
margin: 0.5em 0;
|
84
85
|
}
|
85
86
|
a
|
86
87
|
{
|
data/resources/500.erb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
<%
|
2
2
|
# # consider replacing the Html with the following Ruby code:
|
3
|
-
#
|
3
|
+
# cookies[:notice] = "Internal error for #{request.original_path} - error code 500"
|
4
|
+
# response.redirect_to "/"
|
4
5
|
# # OR
|
5
|
-
# render
|
6
|
+
# render("layout") { render("template") }
|
6
7
|
%><!DOCTYPE html>
|
7
8
|
<head>
|
8
9
|
<style>
|
@@ -46,7 +47,7 @@
|
|
46
47
|
}
|
47
48
|
h3
|
48
49
|
{
|
49
|
-
font-family: 'Architects Daughter', cursive;
|
50
|
+
font-family: 'Architects Daughter', cursive;
|
50
51
|
background-color: #44518E;
|
51
52
|
color: #C6CCE7;
|
52
53
|
text-align: left;
|
@@ -80,7 +81,7 @@
|
|
80
81
|
{
|
81
82
|
font-size: 1em;
|
82
83
|
padding: 0 1em;
|
83
|
-
margin: 0.5em 0;
|
84
|
+
margin: 0.5em 0;
|
84
85
|
}
|
85
86
|
a
|
86
87
|
{
|
@@ -1,7 +1,6 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<head>
|
3
3
|
<style>
|
4
|
-
body, html
|
5
4
|
/*
|
6
5
|
med-blue: #44518E
|
7
6
|
dark-gray: #424A70
|
@@ -42,7 +41,7 @@
|
|
42
41
|
}
|
43
42
|
h3
|
44
43
|
{
|
45
|
-
font-family: 'Architects Daughter', cursive;
|
44
|
+
font-family: 'Architects Daughter', cursive;
|
46
45
|
background-color: #44518E;
|
47
46
|
color: #C6CCE7;
|
48
47
|
text-align: left;
|
@@ -76,7 +75,7 @@
|
|
76
75
|
{
|
77
76
|
font-size: 1em;
|
78
77
|
padding: 0 1em;
|
79
|
-
margin: 0.5em 0;
|
78
|
+
margin: 0.5em 0;
|
80
79
|
}
|
81
80
|
a
|
82
81
|
{
|
@@ -114,12 +113,12 @@
|
|
114
113
|
</style>
|
115
114
|
</head>
|
116
115
|
<body>
|
117
|
-
<h1>
|
116
|
+
<h1>Our servers are busy, working at full capacity...</h1>
|
118
117
|
<div id='wrapper'>
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
<p>
|
123
|
-
<p
|
118
|
+
<h2 id='missing'>
|
119
|
+
Please try again in a few minutes.
|
120
|
+
</h2>
|
121
|
+
<p>It seems our servers are all quite busy. This unexpected high load will probably be over soon...</p>
|
122
|
+
<p>... Please try again in a few minutes. If this issue persists, please let us know.</p>
|
124
123
|
</div>
|
125
124
|
</body>
|
data/resources/client.js
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
// This is a commonly used structure for WebSocket messanging.
|
2
|
+
// The documentation is available on the www.plezi.io website:
|
3
|
+
// http://www.plezi.io/docs/websockets#websocket-json-auto-dispatch
|
4
|
+
//
|
5
|
+
// Basics:
|
6
|
+
// To open a websocket connection to the current location:
|
7
|
+
//
|
8
|
+
// var client = new PleziClient()
|
9
|
+
//
|
10
|
+
// To open a connection to a different path for the original server (SSL will be preserved when in use), use:
|
11
|
+
//
|
12
|
+
// var client = new PleziClient(PleziClient.origin + "/path")
|
13
|
+
//
|
14
|
+
// To automatically renew the connection when disconnections are reported by the browser, use:
|
15
|
+
//
|
16
|
+
// client.autoreconnect = true
|
17
|
+
// client.reconnect_interval = 250 // sets how long to wait before reconnection attempts. default is 250 ms.
|
18
|
+
//
|
19
|
+
// To set up event handling, directly set an `<event name>` callback. i.e., for an event called `chat`:
|
20
|
+
//
|
21
|
+
// client.chat = function(event) { "..." }
|
22
|
+
//
|
23
|
+
// To sent / emit event in JSON format, use the `emit` method:
|
24
|
+
//
|
25
|
+
// client.emit({event: "chat", data: "the message"})
|
26
|
+
//
|
27
|
+
function PleziClient(url, autoreconnect) {
|
28
|
+
// Set URL
|
29
|
+
if (url) {
|
30
|
+
this.url = url;
|
31
|
+
} else {
|
32
|
+
this.url = PleziClient.origin + self.location.pathname;
|
33
|
+
}
|
34
|
+
// Connect Websocket
|
35
|
+
this.reconnect();
|
36
|
+
// Setup AJAJ
|
37
|
+
this.ajaj = {};
|
38
|
+
this.ajaj.client = this;
|
39
|
+
this.ajaj.url = this.url.replace(/^ws:\/\//i, "http://").replace(/^wss:\/\//i, "https://");
|
40
|
+
this.ajaj.add = {};
|
41
|
+
this.ajaj.emit = this.___ajaj__emit;
|
42
|
+
this.ajaj.auto = false;
|
43
|
+
// auto-reconnection
|
44
|
+
this.autoreconnect = false;
|
45
|
+
this.reconnect_interval = 200;
|
46
|
+
// dump data to console?
|
47
|
+
this.log_events = false;
|
48
|
+
// the timeout for a message ack receipt
|
49
|
+
this.emit_timeout = false;
|
50
|
+
// Set the autoreconnect property
|
51
|
+
if (autoreconnect) {
|
52
|
+
this.autoreconnect = true;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
// The Websocket onopen callback
|
56
|
+
PleziClient.prototype.___on_open = function(e) {
|
57
|
+
this.owner.connected = true;
|
58
|
+
if (this.owner.onopen) {
|
59
|
+
this.owner.onopen(e);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
// The Websocket onclose callback
|
63
|
+
PleziClient.prototype.___on_close = function(e) {
|
64
|
+
this.owner.connected = false;
|
65
|
+
if (this.owner.onclose) {
|
66
|
+
this.owner.onclose(e);
|
67
|
+
}
|
68
|
+
if (this.owner.autoreconnect) {
|
69
|
+
setTimeout(function(obj) {
|
70
|
+
obj.reconnect();
|
71
|
+
}, this.owner.reconnect_interval, this.owner);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
// The Websocket onerror callback
|
75
|
+
PleziClient.prototype.___on_error = function(e) {
|
76
|
+
if (this.owner.onerror) {
|
77
|
+
this.owner.onerror(e);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
// The Websocket onmessage callback
|
81
|
+
PleziClient.prototype.___on_message = function(e) {
|
82
|
+
try {
|
83
|
+
var msg = JSON.parse(e.data);
|
84
|
+
this.owner.___dispatch(msg);
|
85
|
+
} catch (err) {
|
86
|
+
console.error("PleziClient experienced an error parsing the following data (not JSON):",
|
87
|
+
err, e);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
PleziClient.prototype.___dispatch = function(msg) {
|
91
|
+
try {
|
92
|
+
if (this.log_events) {
|
93
|
+
console.log(msg);
|
94
|
+
}
|
95
|
+
if (msg.event == '_ack_') {
|
96
|
+
clearTimeout(msg._EID_);
|
97
|
+
if (this[msg._EID_] && this[msg._EID_].callback) {
|
98
|
+
this[msg._EID_].callback(this[msg._EID_].event, this);
|
99
|
+
}
|
100
|
+
delete this[msg._EID_];
|
101
|
+
}
|
102
|
+
if ((msg.event) && (this[msg.event])) {
|
103
|
+
this[msg.event](msg);
|
104
|
+
} else if ((msg.event) && (this['on' + msg.event])) {
|
105
|
+
console.warn('PleziClient: use a callback called "' + msg.event +
|
106
|
+
'" instead of of "on' + msg.event + '"');
|
107
|
+
this['on' + msg.event](msg);
|
108
|
+
} else {
|
109
|
+
if (this['unknown'] && (msg.event != '_ack_')) {
|
110
|
+
this['unknown'](msg);
|
111
|
+
};
|
112
|
+
}
|
113
|
+
} catch (err) {
|
114
|
+
console.error("PleziClient experienced an error while responding to the following onmessage event",
|
115
|
+
err, msg);
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
// Clears meta timeout data
|
120
|
+
PleziClient.prototype.___perform_timeout_callback = function(event, pl_client, callback) {
|
121
|
+
delete pl_client[event._EID_];
|
122
|
+
callback(event, pl_client);
|
123
|
+
}
|
124
|
+
|
125
|
+
// Sets a timeout for the websocket message
|
126
|
+
PleziClient.prototype.___set_failed_timeout = function(event, callback, timeout) {
|
127
|
+
if (event._EID_) {
|
128
|
+
return event;
|
129
|
+
};
|
130
|
+
if (!timeout) {
|
131
|
+
timeout = this.emit_timeout;
|
132
|
+
};
|
133
|
+
if (!callback) {
|
134
|
+
callback = this.___on_timeout;
|
135
|
+
};
|
136
|
+
if (!timeout) {
|
137
|
+
return event;
|
138
|
+
};
|
139
|
+
event._EID_ = setTimeout(this.___perform_timeout_callback, timeout, event, this, callback);
|
140
|
+
return event;
|
141
|
+
}
|
142
|
+
// Removes the _client_ property from the event and calls
|
143
|
+
// the ontimeout callback within the correct scope
|
144
|
+
PleziClient.prototype.___on_timeout = function(event, client) {
|
145
|
+
if (client.ajaj.auto) {
|
146
|
+
if (client.log_events) {
|
147
|
+
console.log("falling back on AJAJ for the event:", event);
|
148
|
+
}
|
149
|
+
client.ajaj.emit(event, client.ontimeout);
|
150
|
+
} else {
|
151
|
+
client.ontimeout(event);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
// The timeout callback
|
155
|
+
PleziClient.prototype.ontimeout = function(event) {
|
156
|
+
console.warn("Timeout reached - it's assumed the connection was lost " +
|
157
|
+
"and the following event was ignored by the server:", event);
|
158
|
+
console.log(this);
|
159
|
+
}
|
160
|
+
|
161
|
+
PleziClient.prototype.reconnect = function() {
|
162
|
+
this.connected = NaN;
|
163
|
+
this.ws = new WebSocket(this.url);
|
164
|
+
// lets us access the client from the callbacks
|
165
|
+
this.ws.owner = this;
|
166
|
+
// The Websocket onopen callback
|
167
|
+
this.ws.onopen = this.___on_open;
|
168
|
+
// The Websocket onclose callback
|
169
|
+
this.ws.onclose = this.___on_close;
|
170
|
+
// The Websocket onerror callback
|
171
|
+
this.ws.onerror = this.___on_error;
|
172
|
+
// The Websocket onmessage callback
|
173
|
+
this.ws.onmessage = this.___on_message;
|
174
|
+
}
|
175
|
+
|
176
|
+
PleziClient.prototype.close = function() {
|
177
|
+
this.autoreconnect = false;
|
178
|
+
this.ws.close();
|
179
|
+
}
|
180
|
+
|
181
|
+
PleziClient.origin = (self.location.protocol.match(/https/) ? 'wws' : 'ws') + '://' + self.location.hostname + (self.location.port == '' ? '' : (':' + self.location.port));
|
182
|
+
|
183
|
+
PleziClient.prototype.sendraw = function(data) {
|
184
|
+
if (this.ws.readyState != 1) {
|
185
|
+
return false;
|
186
|
+
}
|
187
|
+
this.ws.send(data);
|
188
|
+
if (this.ws.readyState != 1) {
|
189
|
+
return false;
|
190
|
+
}
|
191
|
+
return true;
|
192
|
+
}
|
193
|
+
|
194
|
+
PleziClient.prototype.emit = function(event, callback, timeout_callback, timeout) {
|
195
|
+
if (!timeout && callback && !this.emit_timeout)
|
196
|
+
timeout = 10;
|
197
|
+
this.___set_failed_timeout(event, timeout_callback, timeout)
|
198
|
+
if (callback) {
|
199
|
+
this[event._EID_] = {
|
200
|
+
callback: callback,
|
201
|
+
event: event
|
202
|
+
};
|
203
|
+
}
|
204
|
+
return this.sendraw(JSON.stringify(event));
|
205
|
+
}
|
206
|
+
|
207
|
+
PleziClient.prototype.readyState = function() {
|
208
|
+
return this.ws.readyState;
|
209
|
+
}
|
210
|
+
|
211
|
+
PleziClient.prototype.___ajaj__emit = function(event, callback) {
|
212
|
+
var combined = {}
|
213
|
+
for (var k in this.add) {
|
214
|
+
combined[k] = this.add[k];
|
215
|
+
};
|
216
|
+
for (var k in event) {
|
217
|
+
combined[k] = event[k];
|
218
|
+
};
|
219
|
+
if (!combined.id) {
|
220
|
+
combined.id = event.event;
|
221
|
+
};
|
222
|
+
var req = new XMLHttpRequest();
|
223
|
+
req.client = this.client;
|
224
|
+
req.json = combined;
|
225
|
+
req.callback = callback;
|
226
|
+
// if(!req.callback) req.callback = this.failed
|
227
|
+
req.onreadystatechange = function() {
|
228
|
+
if (this.readyState != 4) {
|
229
|
+
return;
|
230
|
+
}
|
231
|
+
if (this.status == 200) {
|
232
|
+
try {
|
233
|
+
var res = JSON.parse(this.responseText);
|
234
|
+
this.client.___dispatch(res);
|
235
|
+
} catch (err) {
|
236
|
+
console.error("PleziClient experienced an error parsing the following data (not JSON):",
|
237
|
+
err, this.responseText);
|
238
|
+
}
|
239
|
+
|
240
|
+
} else {
|
241
|
+
if (this.callback) {
|
242
|
+
this.callback(this.json);
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
req.open("POST", this.url, true);
|
247
|
+
req.setRequestHeader("Content-type", "application/json");
|
248
|
+
try {
|
249
|
+
req.send(JSON.stringify(combined));
|
250
|
+
} catch (err) {
|
251
|
+
callback(event);
|
252
|
+
}
|
253
|
+
}
|
data/resources/config.ru
CHANGED
@@ -1,39 +1,8 @@
|
|
1
|
-
|
2
|
-
# RackServer rack interface
|
3
|
-
#
|
4
|
-
# using Rack with Plezi poses some limitations...:
|
5
|
-
#
|
6
|
-
# 1. there is NO WebSockets support for Rack apps.
|
7
|
-
#
|
8
|
-
# 2. this might break any streaming / asynchronous methods calls, such as Iodine's Http streaming.
|
9
|
-
#
|
10
|
-
# 3. Plezi parameters and file uploads are different then Rack - HTML Form code might be incompatible!
|
11
|
-
# This MIGHT BREAKE YOUR CODE! (changing this requires Plezi to re-parse the HTML, and costs in performance).
|
12
|
-
#
|
13
|
-
# also, all Plezi server specific configuration will be ignored.
|
14
|
-
#
|
15
|
-
# on the other hand, there is an upside:
|
16
|
-
#
|
17
|
-
# 1. you can choose a well tested server written in C that might (or might not) bring a performance boost.
|
18
|
-
#
|
19
|
-
# 2. you have better control over Middleware then you could have with Plezi.
|
20
|
-
# ("wait", you might say, "there is no Middleware in Plezi!"... "Ahhh", I will answer, "so much to discover...")
|
21
|
-
#
|
22
|
-
#
|
23
|
-
##############
|
24
|
-
#
|
25
|
-
# For now, Rack mode is NOT supported unless using the Iodine Http server,
|
26
|
-
# even than you're 404 not found pages will break unless using a catch-all route.
|
1
|
+
# Default Rack interface
|
27
2
|
|
28
|
-
# load
|
29
|
-
load ::File.expand_path(File.join(
|
3
|
+
# load the application
|
4
|
+
load ::File.expand_path(File.join('..', 'appname.rb'), __FILE__)
|
30
5
|
|
31
|
-
|
32
|
-
load ::File.expand_path(File.join("..", "routes.rb"), __FILE__)
|
6
|
+
Iodine::Rack.public ||= './public'
|
33
7
|
|
34
|
-
|
35
|
-
if Rack::Handler.default == Iodine::Http::Rack
|
36
|
-
run(Proc.new { [404, {}, ["not found"]] })
|
37
|
-
else
|
38
|
-
raise "Unsupported Server - Plezi only runs using Iodine."
|
39
|
-
end
|
8
|
+
run Plezi.app
|
data/resources/ctrlr.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Replace this sample with real code.
|
2
|
+
class RootController
|
3
|
+
# HTTP
|
4
|
+
def index
|
5
|
+
# any String returned will be appended to the response. We return a String.
|
6
|
+
render 'welcome'
|
7
|
+
end
|
8
|
+
|
9
|
+
# Websockets
|
10
|
+
def on_message(data)
|
11
|
+
data = ERB::Util.html_escape data
|
12
|
+
print data
|
13
|
+
broadcast :print, data
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_open
|
17
|
+
print 'Welcome to appname!'
|
18
|
+
@handle = params['id'.freeze] || 'Somebody'
|
19
|
+
broadcast :print, "#{ERB::Util.html_escape @handle} joind us :-)"
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_close
|
23
|
+
broadcast :print, "#{@handle} left us :-("
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
# write is inherites when a Websocket connection is opened.
|
29
|
+
#
|
30
|
+
# Inherited functions aren't exposed (for our security), so we need to wrap it.
|
31
|
+
def print(data)
|
32
|
+
write data
|
33
|
+
end
|
34
|
+
end
|
data/resources/gemfile
ADDED
data/resources/mini_app.rb
CHANGED
@@ -1,87 +1,33 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
## Set environment, working directory, load gems and create logs
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
## Log to a file?
|
20
|
-
# Iodine.logger = Logger.new Root.join('server.log').to_s
|
4
|
+
ENV['ENV'] ||= ENV['RACK_ENV'] # production ENV will render SASS as compressed.
|
5
|
+
## Using pathname extentions for setting public folder
|
6
|
+
require 'pathname'
|
7
|
+
## Set up root object, it might be used by the environment and\or the plezi extension gems.
|
8
|
+
Root ||= Pathname.new(File.dirname(__FILE__)).expand_path
|
9
|
+
## If this app is independant, use bundler to load gems (including the plezi gem).
|
10
|
+
## otherwise, use the original app's Gemfile and Plezi will automatically switch to Rack mode.
|
11
|
+
require 'bundler'
|
12
|
+
Bundler.require(:default, ENV['ENV'].to_s.to_sym)
|
13
|
+
|
14
|
+
# Load all the code from a subfolder called 'app'
|
15
|
+
Dir[File.join '{app}', '**', '*.rb'].each { |file| load File.expand_path(file) }
|
16
|
+
|
17
|
+
## Logging
|
18
|
+
Iodine::Rack.log = 1 if Iodine::Rack.log.nil?
|
21
19
|
|
22
20
|
# # Optional Scaling (across processes or machines):
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
#
|
35
|
-
|
36
|
-
# HTTP
|
37
|
-
def index
|
38
|
-
# return response << "Hello World!" # for a hello world app
|
39
|
-
render :welcome
|
40
|
-
end
|
41
|
-
# Websockets
|
42
|
-
def on_message data
|
43
|
-
data = ERB::Util.html_escape data
|
44
|
-
print data
|
45
|
-
broadcast :print, data
|
46
|
-
end
|
47
|
-
def on_open
|
48
|
-
print 'Welcome!'
|
49
|
-
@handle = params[:id] || 'Somebody'
|
50
|
-
broadcast :print, "#{@handle} joind us :-)"
|
51
|
-
end
|
52
|
-
def on_close
|
53
|
-
broadcast :print, "#{@handle} left us :-("
|
54
|
-
end
|
55
|
-
|
56
|
-
protected
|
57
|
-
|
58
|
-
def print data
|
59
|
-
response << data
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
# change some of the default settings here.
|
65
|
-
host templates: Root.join('templates').to_s,
|
66
|
-
# public: Root.join('public').to_s,
|
67
|
-
assets: Root.join('assets').to_s
|
68
|
-
|
69
|
-
# # I18n re-write, i.e.: `/en/home` will be rewriten as `/home`, while setting params[:locale] to "en"
|
70
|
-
# route "/:locale{#{I18n.available_locales.join "|"}}/*" , false if defined? I18n
|
71
|
-
|
72
|
-
# # Response format re-write, i.e.: `/xml/home` will use .xml templates automatically
|
73
|
-
# # with :locale a request might look like `/en/json/...`
|
74
|
-
# route "/:format{html|json|xml}/*" , false
|
75
|
-
|
76
|
-
# # OAuth2 - Facebook / Google authentication
|
77
|
-
# ENV["FB_APP_ID"] ||= "app id"; ENV["FB_APP_SECRET"] ||= "secret"; ENV['GOOGLE_APP_ID'] = "app id"; ENV['GOOGLE_APP_SECRET'] = "secret"
|
78
|
-
# require 'plezi/oauth' # do this AFTER setting ENV variables.
|
79
|
-
# create_auth_shared_route do |service_name, auth_token, remote_user_id, remote_user_email, remote_response|
|
80
|
-
# # ...callback for authentication.
|
81
|
-
# # This callback should return the app user object or false
|
82
|
-
# # This callback has access to the controller's methods (request, cookies, response, etc')
|
83
|
-
# end
|
84
|
-
|
85
|
-
# Add your routes and controllers by order of priority.
|
86
|
-
route '/(:id)', MyController
|
87
|
-
|
21
|
+
ENV['PL_REDIS_URL'] ||= ENV['REDIS_URL'] ||
|
22
|
+
ENV['REDISCLOUD_URL'] ||
|
23
|
+
ENV['REDISTOGO_URL'] ||
|
24
|
+
nil # "redis://:password@my.host:6389/0"
|
25
|
+
# # redis channel name should be changed IF using the same Plezi code within
|
26
|
+
# # more then one application (i.e., using both Rails and Plezi together).
|
27
|
+
# Plezi.app_name = 'appsecret'
|
28
|
+
|
29
|
+
# Map the views folder to the template root (for the {#render} function).
|
30
|
+
Plezi.templates = Root.join('views').to_s
|
31
|
+
|
32
|
+
# load routes.
|
33
|
+
load Root.join('routes.rb').to_s
|