rsence 2.0.0.6.pre → 2.0.0.7.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/INSTALL.rdoc +39 -25
- data/VERSION +1 -1
- data/conf/default_conf.yaml +0 -3
- data/lib/conf/default.rb +59 -60
- data/lib/daemon/daemon.rb +269 -280
- data/lib/http/broker.rb +47 -14
- data/lib/http/rackup.rb +4 -0
- data/lib/http/request.rb +47 -49
- data/lib/http/response.rb +47 -45
- data/lib/plugins/gui_plugin.rb +22 -21
- data/lib/plugins/guiparser.rb +95 -94
- data/lib/plugins/plugin.rb +300 -295
- data/lib/plugins/plugin_plugins.rb +64 -40
- data/lib/plugins/plugin_sqlite_db.rb +63 -63
- data/lib/plugins/plugin_util.rb +95 -104
- data/lib/plugins/pluginmanager.rb +373 -414
- data/lib/plugins/plugins.rb +11 -4
- data/lib/plugins/servlet.rb +10 -9
- data/lib/session/msg.rb +249 -248
- data/lib/session/sessionmanager.rb +364 -373
- data/lib/session/sessionstorage.rb +265 -272
- data/lib/transporter/transporter.rb +164 -169
- data/lib/util/gzstring.rb +2 -0
- data/lib/values/hvalue.rb +224 -224
- data/lib/values/valuemanager.rb +98 -98
- data/plugins/index_html/index_html.rb +1 -32
- metadata +4 -4
data/lib/plugins/plugin.rb
CHANGED
@@ -6,300 +6,305 @@
|
|
6
6
|
# with this software package. If not, contact licensing@riassence.com
|
7
7
|
##
|
8
8
|
|
9
|
-
## = Abstract
|
10
|
-
## The Plugin class is the base class for extending server logic.
|
11
|
-
## A single Plugin instance serves the requests of all sessions,
|
12
|
-
## which makes them very cpu and memory efficient compared to systems,
|
13
|
-
## where the server classes are constructed and destructed for each
|
14
|
-
## request.
|
15
|
-
##
|
16
|
-
## Plugins are designed to be contained in a plugin directory bundle and
|
17
|
-
## to be loaded by the +PluginManager+, which is also responsible for
|
18
|
-
## delegating the events and other calls throughout the system.
|
19
|
-
##
|
20
|
-
## == Anatomy of a plugin bundle
|
21
|
-
## The plugin bundle contains all data needed to run the plugin. Design
|
22
|
-
## your plugin without any hard-coded paths, remember that it's intended
|
23
|
-
## to be deployed by "dropping" the whole plugin into one of the server's
|
24
|
-
## plugins directories.
|
25
|
-
##
|
26
|
-
## The +PluginManager+ looks for such bundles and evaluates them into an
|
27
|
-
## anonymous +Module+ namespace. The content of the ruby source file
|
28
|
-
## is then responsible for including its libraries, constructing an
|
29
|
-
## instance of itself and registering itself as a part of the system.
|
30
|
-
##
|
31
|
-
## It's advised to use the +GUIPlugin+ class for plugins that handle
|
32
|
-
## user interfaces. Usage of the +Plugin+ bundle is advised to use
|
33
|
-
## for plugins that provide extra functionality, value responders
|
34
|
-
## and other utilities that supplement the user interface.
|
35
|
-
##
|
36
|
-
## You must call the +#register+ method after the class is constructed.
|
37
|
-
## Otherwise, the class is not connected to the system and just discarded
|
38
|
-
## and then garbage collected.
|
39
|
-
##
|
40
|
-
## == Messages
|
41
|
-
## As a side effect of having single instances of plugins serve the requests
|
42
|
-
## of all sessions, the request/response/session messaging is implemented
|
43
|
-
## as messaging objects. These objects contain or delegate all the necessary
|
44
|
-
## hooks required by the complete request/response cycle.
|
45
|
-
##
|
46
|
-
## The naming convention of the +Message+ instance is +msg+ and it's
|
47
|
-
## given as the first parameter of methods needing it.
|
48
|
-
##
|
49
|
-
## Use +msg.ses_id+ to identify the session's serial number and +msg.user_id+
|
50
|
-
## to identify the user's identity.
|
51
|
-
##
|
52
|
-
## Use the +msg.session+ +Hash+ to store any persistent data
|
53
|
-
## associated with the user's session, preferably using the name of the
|
54
|
-
## plugin or its registered name as the primary key entry in the Hash.
|
55
|
-
## The session data is persistent; it's stored in the session database
|
56
|
-
## by +SessionStorage+ automatically.
|
57
|
-
##
|
58
|
-
## The +msg+ instance also provides access to the +Request+ and +Response+
|
59
|
-
## objects as +msg.request+ and +msg.response+, respectively.
|
60
|
-
##
|
61
|
-
## Use the +msg.run+ method to call other plugins.
|
62
|
-
##
|
63
|
-
## To append js source code to be evaluated in the client, use the +msg.reply+
|
64
|
-
## call. The +msg.console+ call appends messages to the browser's js console.
|
65
|
-
##
|
66
|
-
##
|
67
|
-
## == Session -related event methods
|
68
|
-
## The +#get_ses+ method returns (or creates and returns) the entry in
|
69
|
-
## the session based on the name your plugin is registered as. It's advised
|
70
|
-
## to use this call instead of manually managing +msg.session+ in most cases.
|
71
|
-
##
|
72
|
-
## The +#idle+ method is called each time a client performs a data
|
73
|
-
## synchronization or "idle poll" request.
|
74
|
-
##
|
75
|
-
## The +#init_ses+ method is called once in the same request a new session
|
76
|
-
## is created. A new session is created, when a user enters accesses the
|
77
|
-
## server the first time, or the first time after the previous session is
|
78
|
-
## expired.
|
79
|
-
##
|
80
|
-
## The +#init_ui+ method is called by the "main" plugin after the client has
|
81
|
-
## booted successfully. The +GUIPlugin+ class extends this method to
|
82
|
-
## automatically load and initialize the user interface from a data structure.
|
83
|
-
##
|
84
|
-
## The +#restore_ses+ method is called once in the same request an old
|
85
|
-
## session is restored. A session is restored, when the user returns to
|
86
|
-
## the page or reloads the page before the session is expired.
|
87
|
-
##
|
88
|
-
## === When the server is configured to restore previous sessions (default):
|
89
|
-
## If the user accesses the same page using the same browser (in different
|
90
|
-
## tabs or windows), only the most recently restored one is valid, while
|
91
|
-
## the previous ones are immediately invalidated.
|
92
|
-
## If your application is intended to support several sessions per browser,
|
93
|
-
## enable session cloning in the configuration file.
|
94
|
-
##
|
95
|
-
## === When the server is configured to restore and clone previous sessions:
|
96
|
-
## When sessions are cloned, the previous session is not invalidated and
|
97
|
-
## exists until timing out as a result of the web browser window being closed
|
98
|
-
## or client computer losing network connectivity for a certain (configurable)
|
99
|
-
## time frame.
|
100
|
-
##
|
101
|
-
## The +#cloned_target+ method is like +#restore_ses+, but called when
|
102
|
-
## the session is a clone of a previous session.
|
103
|
-
##
|
104
|
-
## The +#cloned_source+ method is called on the next request of the previous
|
105
|
-
## session after it has been cloned.
|
106
|
-
##
|
107
|
-
## == Server event methods
|
108
|
-
## Extend the +#init+ method to invoke constructor functionality that
|
109
|
-
## depends on the plugin to be constructed and registered as a part of
|
110
|
-
## the system.
|
111
|
-
##
|
112
|
-
## Extend the +#open+, +#flush+ and +#close+ methods to open, flush and close
|
113
|
-
## streams or other similar functionality.
|
114
|
-
##
|
115
|
-
## == Data handling
|
116
|
-
## The data exchange system exists to support bi-directional
|
117
|
-
## data synchronization between the browser and the plugin. The values
|
118
|
-
## are stored in the session as +HValue+ instances.
|
119
|
-
##
|
120
|
-
## Values support Hashes, Arrays, Strings, Numbers, Booleans and
|
121
|
-
## combinations of them. The data is automatically converted between
|
122
|
-
## ruby objects (server) and json objects (client).
|
123
|
-
##
|
124
|
-
## Each instance may be bound to plugin methods that are used as
|
125
|
-
## value change notification responders.
|
126
|
-
##
|
127
|
-
## When a method is bound to the value, the method is called as an
|
128
|
-
## event notification whenever the client has changed the value and
|
129
|
-
## synchronizes it to the server. The responders act as validators
|
130
|
-
## by default.
|
131
|
-
##
|
132
|
-
## Values are also bound in the client to classes implementing the
|
133
|
-
## HValueResponder interface, like any derivate of HControl. See the
|
134
|
-
## client documentation for instructions about using them.
|
135
|
-
##
|
136
|
-
## To define a value responder method, it needs to respond to exactly
|
137
|
-
## two parameters: the +Message+ instance +msg+ and the HValue object
|
138
|
-
## (in that order). The method's return value must be either +true+
|
139
|
-
## or +false+. When the method returns +false+, the change is discarded
|
140
|
-
## and the previously server-set value is sent back to the client.
|
141
|
-
##
|
142
|
-
## A minimal value responder method is defined like this:
|
143
|
-
##
|
144
|
-
## def my_value_responder( msg, my_value )
|
145
|
-
## return true
|
146
|
-
## end
|
147
|
-
##
|
148
|
-
## To access the content of the value, use the +HValue#data+ attribute.
|
149
|
-
##
|
150
|
-
## def int_between_100_and_200( msg, value )
|
151
|
-
## data = value.data.to_i
|
152
|
-
## return ( data >= 100 and data <= 200 )
|
153
|
-
## end
|
154
|
-
##
|
155
|
-
## To change the content of the value, use the +HValue#set+ method.
|
156
|
-
##
|
157
|
-
## def int_between_100_and_200( msg, value )
|
158
|
-
## data = value.data.to_i
|
159
|
-
## value.set( msg, 100 ) if data < 100
|
160
|
-
## value.set( msg, 200 ) if data > 200
|
161
|
-
## return true
|
162
|
-
## end
|
163
|
-
##
|
164
|
-
## == Defining values
|
165
|
-
## The simplest and recommended way of defining the values is to define
|
166
|
-
## the value configuration file +values.yaml+. Its configuration is then
|
167
|
-
## applied to sessions automatically.
|
168
|
-
##
|
169
|
-
##
|
170
|
-
## === Syntax reference of the contents of a +values.yaml+ file:
|
171
|
-
##
|
172
|
-
## # The name of the value (:value_name).
|
173
|
-
## # A hash key in the yaml syntax
|
174
|
-
## :value_name:
|
175
|
-
##
|
176
|
-
## # All of these keys are optional!
|
177
|
-
##
|
178
|
-
## # Default value, a string "Foo" here.
|
179
|
-
## # Defaults to 0
|
180
|
-
## :value: Foo
|
181
|
-
##
|
182
|
-
## # A plugin method to call to define the default value
|
183
|
-
## # instead of the one defined in :value
|
184
|
-
## :value_call:
|
185
|
-
## :plugin: plugin_name # defaults to the plugin where defined
|
186
|
-
##
|
187
|
-
## # Mandatory; name of the method to call
|
188
|
-
## :method: method_name
|
189
|
-
##
|
190
|
-
## # Optional, list of parameter values for the :method
|
191
|
-
## :args:
|
192
|
-
## # three parameters: 1, 'foo', 3
|
193
|
-
## - 1
|
194
|
-
## - foo
|
195
|
-
## - 3
|
196
|
-
##
|
197
|
-
## # When false, doesn't pass the msg as the first parameter.
|
198
|
-
## # Defaults to true
|
199
|
-
## :uses_msg: true
|
200
|
-
##
|
201
|
-
## # Restore the default, when the session is restored; defaults to false
|
202
|
-
## :restore_default: false
|
203
|
-
##
|
204
|
-
## # List of value responder methods to bind.
|
205
|
-
## :responders:
|
206
|
-
## -
|
207
|
-
## # name of plugin to call, defaults to the plugin where defined:
|
208
|
-
## :plugin: plugin_name
|
209
|
-
##
|
210
|
-
## # mandatory, name of the method to call
|
211
|
-
## :method: method_name
|
212
|
-
##
|
213
|
-
## # Another responder, this one using the same plugin where defined:
|
214
|
-
## - :method: another_method
|
215
|
-
##
|
216
|
-
## # Another value, this one just defining the defaults
|
217
|
-
## # by supplying an empty Hash:
|
218
|
-
## # (value: 0, default restored, no responders or calls)
|
219
|
-
## :value_with_defaults: {}
|
220
|
-
##
|
221
|
-
## # This value defines a Number (123) and doesn't restore
|
222
|
-
## # the default, when restoring the session.
|
223
|
-
## :one_two_three:
|
224
|
-
## :value: 123
|
225
|
-
## :restore_default: false
|
226
|
-
##
|
227
|
-
## # This value gets a random string and specifies a responder,
|
228
|
-
## # that ensures it's unique, if changed in the client.
|
229
|
-
## :random_unique_string:
|
230
|
-
## :value_call:
|
231
|
-
## :method: get_unique_random_string
|
232
|
-
## :uses_msg: false
|
233
|
-
## :responders:
|
234
|
-
## - :method: ensure_unique_random_string
|
235
|
-
##
|
236
|
-
## = Examples
|
237
|
-
## More examples are available in the repository;
|
238
|
-
## http://svn.rsence.org/contrib/plugins
|
239
|
-
## ..as well as the standard "main" plugin in the "plugins" directory.
|
240
|
-
##
|
241
|
-
##
|
242
|
-
## == A minimal Plugin bundle
|
243
|
-
## The minimal active plugin bundle (named "name_of_plugin")
|
244
|
-
## is defined like this:
|
245
|
-
##
|
246
|
-
## [dir] name_of_plugin
|
247
|
-
## |
|
248
|
-
## +---[file] name_of_plugin.rb
|
249
|
-
##
|
250
|
-
## This sample Plugin doesn't do anything except construct itself and
|
251
|
-
## respond as 'name_of_plugin'.
|
252
|
-
##
|
253
|
-
## Plugin.new.register('name_of_plugin')
|
254
|
-
##
|
255
|
-
## However, this is not very useful in itself, so you'll need to extend
|
256
|
-
## its functionality to do anything useful.
|
257
|
-
##
|
258
|
-
## == A simple Plugin extension
|
259
|
-
## This plugin logs session events to the logs/session_log file.
|
260
|
-
##
|
261
|
-
## [dir] ses_logger
|
262
|
-
## |
|
263
|
-
## +---[file] ses_logger.rb
|
264
|
-
## |
|
265
|
-
## +---[dir] logs
|
266
|
-
## |
|
267
|
-
## +---[file] session_log
|
268
|
-
##
|
269
|
-
## == Contents of "ses_logger.rb"
|
270
|
-
##
|
271
|
-
## class SessionLogger < Plugin
|
272
|
-
## def init
|
273
|
-
## super
|
274
|
-
## @logfile = false
|
275
|
-
## end
|
276
|
-
## def open
|
277
|
-
## log_path = compose_plugin_path( 'session_log', 'logs' )
|
278
|
-
## @logfile = File.open( log_path, 'a' )
|
279
|
-
## end
|
280
|
-
## def close
|
281
|
-
## @logfile.close if @logfile
|
282
|
-
## @logfile = false
|
283
|
-
## end
|
284
|
-
## def flush
|
285
|
-
## @logfile.flush if @logfile
|
286
|
-
## end
|
287
|
-
## def init_ses( msg )
|
288
|
-
## super
|
289
|
-
## @logfile.write( "#{Time.new} -- Session id #{msg.ses_id} was created.\n" )
|
290
|
-
## end
|
291
|
-
## def restore_ses( msg )
|
292
|
-
## super
|
293
|
-
## @logfile.write( "#{Time.new} -- Session id #{msg.ses_id} was restored.\n" )
|
294
|
-
## end
|
295
|
-
## def idle( msg )
|
296
|
-
## @logfile.write( "#{Time.new} -- Client of session id #{msg.ses_id} connected.\n" )
|
297
|
-
## end
|
298
|
-
## end
|
299
|
-
## SessionLogger.new.register( 'ses_logger' )
|
300
|
-
##
|
301
9
|
module ::RSence
|
302
10
|
module Plugins
|
11
|
+
|
12
|
+
## = Abstract
|
13
|
+
##
|
14
|
+
## The PluginTemplate is used to create a Plugin mimic class in
|
15
|
+
## Plugins.bundle_loader using the Plugins.PluginWrapper mimic.
|
16
|
+
##
|
17
|
+
## The Plugin class is the base class for extending server logic.
|
18
|
+
## A single Plugin instance serves the requests of all sessions,
|
19
|
+
## which makes them very cpu and memory efficient compared to systems,
|
20
|
+
## where the server classes are constructed and destructed for each
|
21
|
+
## request.
|
22
|
+
##
|
23
|
+
## Plugins are designed to be contained in a plugin directory bundle and
|
24
|
+
## to be loaded by the +PluginManager+, which is also responsible for
|
25
|
+
## delegating the events and other calls throughout the system.
|
26
|
+
##
|
27
|
+
## == Anatomy of a plugin bundle
|
28
|
+
## The plugin bundle contains all data needed to run the plugin. Design
|
29
|
+
## your plugin without any hard-coded paths, remember that it's intended
|
30
|
+
## to be deployed by "dropping" the whole plugin into one of the server's
|
31
|
+
## plugins directories.
|
32
|
+
##
|
33
|
+
## The +PluginManager+ looks for such bundles and evaluates them into an
|
34
|
+
## anonymous +Module+ namespace. The content of the ruby source file
|
35
|
+
## is then responsible for including its libraries, constructing an
|
36
|
+
## instance of itself and registering itself as a part of the system.
|
37
|
+
##
|
38
|
+
## It's advised to use the +GUIPlugin+ class for plugins that handle
|
39
|
+
## user interfaces. Usage of the +Plugin+ bundle is advised to use
|
40
|
+
## for plugins that provide extra functionality, value responders
|
41
|
+
## and other utilities that supplement the user interface.
|
42
|
+
##
|
43
|
+
## You must call the +#register+ method after the class is constructed.
|
44
|
+
## Otherwise, the class is not connected to the system and just discarded
|
45
|
+
## and then garbage collected.
|
46
|
+
##
|
47
|
+
## == Messages
|
48
|
+
## As a side effect of having single instances of plugins serve the requests
|
49
|
+
## of all sessions, the request/response/session messaging is implemented
|
50
|
+
## as messaging objects. These objects contain or delegate all the necessary
|
51
|
+
## hooks required by the complete request/response cycle.
|
52
|
+
##
|
53
|
+
## The naming convention of the +Message+ instance is +msg+ and it's
|
54
|
+
## given as the first parameter of methods needing it.
|
55
|
+
##
|
56
|
+
## Use +msg.ses_id+ to identify the session's serial number and +msg.user_id+
|
57
|
+
## to identify the user's identity.
|
58
|
+
##
|
59
|
+
## Use the +msg.session+ +Hash+ to store any persistent data
|
60
|
+
## associated with the user's session, preferably using the name of the
|
61
|
+
## plugin or its registered name as the primary key entry in the Hash.
|
62
|
+
## The session data is persistent; it's stored in the session database
|
63
|
+
## by +SessionStorage+ automatically.
|
64
|
+
##
|
65
|
+
## The +msg+ instance also provides access to the +Request+ and +Response+
|
66
|
+
## objects as +msg.request+ and +msg.response+, respectively.
|
67
|
+
##
|
68
|
+
## Use the +msg.run+ method to call other plugins.
|
69
|
+
##
|
70
|
+
## To append js source code to be evaluated in the client, use the +msg.reply+
|
71
|
+
## call. The +msg.console+ call appends messages to the browser's js console.
|
72
|
+
##
|
73
|
+
##
|
74
|
+
## == Session -related event methods
|
75
|
+
## The +#get_ses+ method returns (or creates and returns) the entry in
|
76
|
+
## the session based on the name your plugin is registered as. It's advised
|
77
|
+
## to use this call instead of manually managing +msg.session+ in most cases.
|
78
|
+
##
|
79
|
+
## The +#idle+ method is called each time a client performs a data
|
80
|
+
## synchronization or "idle poll" request.
|
81
|
+
##
|
82
|
+
## The +#init_ses+ method is called once in the same request a new session
|
83
|
+
## is created. A new session is created, when a user enters accesses the
|
84
|
+
## server the first time, or the first time after the previous session is
|
85
|
+
## expired.
|
86
|
+
##
|
87
|
+
## The +#init_ui+ method is called by the "main" plugin after the client has
|
88
|
+
## booted successfully. The +GUIPlugin+ class extends this method to
|
89
|
+
## automatically load and initialize the user interface from a data structure.
|
90
|
+
##
|
91
|
+
## The +#restore_ses+ method is called once in the same request an old
|
92
|
+
## session is restored. A session is restored, when the user returns to
|
93
|
+
## the page or reloads the page before the session is expired.
|
94
|
+
##
|
95
|
+
## === When the server is configured to restore previous sessions (default):
|
96
|
+
## If the user accesses the same page using the same browser (in different
|
97
|
+
## tabs or windows), only the most recently restored one is valid, while
|
98
|
+
## the previous ones are immediately invalidated.
|
99
|
+
## If your application is intended to support several sessions per browser,
|
100
|
+
## enable session cloning in the configuration file.
|
101
|
+
##
|
102
|
+
## === When the server is configured to restore and clone previous sessions:
|
103
|
+
## When sessions are cloned, the previous session is not invalidated and
|
104
|
+
## exists until timing out as a result of the web browser window being closed
|
105
|
+
## or client computer losing network connectivity for a certain (configurable)
|
106
|
+
## time frame.
|
107
|
+
##
|
108
|
+
## The +#cloned_target+ method is like +#restore_ses+, but called when
|
109
|
+
## the session is a clone of a previous session.
|
110
|
+
##
|
111
|
+
## The +#cloned_source+ method is called on the next request of the previous
|
112
|
+
## session after it has been cloned.
|
113
|
+
##
|
114
|
+
## == Server event methods
|
115
|
+
## Extend the +#init+ method to invoke constructor functionality that
|
116
|
+
## depends on the plugin to be constructed and registered as a part of
|
117
|
+
## the system.
|
118
|
+
##
|
119
|
+
## Extend the +#open+, +#flush+ and +#close+ methods to open, flush and close
|
120
|
+
## streams or other similar functionality.
|
121
|
+
##
|
122
|
+
## == Data handling
|
123
|
+
## The data exchange system exists to support bi-directional
|
124
|
+
## data synchronization between the browser and the plugin. The values
|
125
|
+
## are stored in the session as +HValue+ instances.
|
126
|
+
##
|
127
|
+
## Values support Hashes, Arrays, Strings, Numbers, Booleans and
|
128
|
+
## combinations of them. The data is automatically converted between
|
129
|
+
## ruby objects (server) and json objects (client).
|
130
|
+
##
|
131
|
+
## Each instance may be bound to plugin methods that are used as
|
132
|
+
## value change notification responders.
|
133
|
+
##
|
134
|
+
## When a method is bound to the value, the method is called as an
|
135
|
+
## event notification whenever the client has changed the value and
|
136
|
+
## synchronizes it to the server. The responders act as validators
|
137
|
+
## by default.
|
138
|
+
##
|
139
|
+
## Values are also bound in the client to classes implementing the
|
140
|
+
## HValueResponder interface, like any derivate of HControl. See the
|
141
|
+
## client documentation for instructions about using them.
|
142
|
+
##
|
143
|
+
## To define a value responder method, it needs to respond to exactly
|
144
|
+
## two parameters: the +Message+ instance +msg+ and the HValue object
|
145
|
+
## (in that order). The method's return value must be either +true+
|
146
|
+
## or +false+. When the method returns +false+, the change is discarded
|
147
|
+
## and the previously server-set value is sent back to the client.
|
148
|
+
##
|
149
|
+
## A minimal value responder method is defined like this:
|
150
|
+
##
|
151
|
+
## def my_value_responder( msg, my_value )
|
152
|
+
## return true
|
153
|
+
## end
|
154
|
+
##
|
155
|
+
## To access the content of the value, use the +HValue#data+ attribute.
|
156
|
+
##
|
157
|
+
## def int_between_100_and_200( msg, value )
|
158
|
+
## data = value.data.to_i
|
159
|
+
## return ( data >= 100 and data <= 200 )
|
160
|
+
## end
|
161
|
+
##
|
162
|
+
## To change the content of the value, use the +HValue#set+ method.
|
163
|
+
##
|
164
|
+
## def int_between_100_and_200( msg, value )
|
165
|
+
## data = value.data.to_i
|
166
|
+
## value.set( msg, 100 ) if data < 100
|
167
|
+
## value.set( msg, 200 ) if data > 200
|
168
|
+
## return true
|
169
|
+
## end
|
170
|
+
##
|
171
|
+
## == Defining values
|
172
|
+
## The simplest and recommended way of defining the values is to define
|
173
|
+
## the value configuration file +values.yaml+. Its configuration is then
|
174
|
+
## applied to sessions automatically.
|
175
|
+
##
|
176
|
+
##
|
177
|
+
## === Syntax reference of the contents of a +values.yaml+ file:
|
178
|
+
##
|
179
|
+
## # The name of the value (:value_name).
|
180
|
+
## # A hash key in the yaml syntax
|
181
|
+
## :value_name:
|
182
|
+
##
|
183
|
+
## # All of these keys are optional!
|
184
|
+
##
|
185
|
+
## # Default value, a string "Foo" here.
|
186
|
+
## # Defaults to 0
|
187
|
+
## :value: Foo
|
188
|
+
##
|
189
|
+
## # A plugin method to call to define the default value
|
190
|
+
## # instead of the one defined in :value
|
191
|
+
## :value_call:
|
192
|
+
## :plugin: plugin_name # defaults to the plugin where defined
|
193
|
+
##
|
194
|
+
## # Mandatory; name of the method to call
|
195
|
+
## :method: method_name
|
196
|
+
##
|
197
|
+
## # Optional, list of parameter values for the :method
|
198
|
+
## :args:
|
199
|
+
## # three parameters: 1, 'foo', 3
|
200
|
+
## - 1
|
201
|
+
## - foo
|
202
|
+
## - 3
|
203
|
+
##
|
204
|
+
## # When false, doesn't pass the msg as the first parameter.
|
205
|
+
## # Defaults to true
|
206
|
+
## :uses_msg: true
|
207
|
+
##
|
208
|
+
## # Restore the default, when the session is restored; defaults to false
|
209
|
+
## :restore_default: false
|
210
|
+
##
|
211
|
+
## # List of value responder methods to bind.
|
212
|
+
## :responders:
|
213
|
+
## -
|
214
|
+
## # name of plugin to call, defaults to the plugin where defined:
|
215
|
+
## :plugin: plugin_name
|
216
|
+
##
|
217
|
+
## # mandatory, name of the method to call
|
218
|
+
## :method: method_name
|
219
|
+
##
|
220
|
+
## # Another responder, this one using the same plugin where defined:
|
221
|
+
## - :method: another_method
|
222
|
+
##
|
223
|
+
## # Another value, this one just defining the defaults
|
224
|
+
## # by supplying an empty Hash:
|
225
|
+
## # (value: 0, default restored, no responders or calls)
|
226
|
+
## :value_with_defaults: {}
|
227
|
+
##
|
228
|
+
## # This value defines a Number (123) and doesn't restore
|
229
|
+
## # the default, when restoring the session.
|
230
|
+
## :one_two_three:
|
231
|
+
## :value: 123
|
232
|
+
## :restore_default: false
|
233
|
+
##
|
234
|
+
## # This value gets a random string and specifies a responder,
|
235
|
+
## # that ensures it's unique, if changed in the client.
|
236
|
+
## :random_unique_string:
|
237
|
+
## :value_call:
|
238
|
+
## :method: get_unique_random_string
|
239
|
+
## :uses_msg: false
|
240
|
+
## :responders:
|
241
|
+
## - :method: ensure_unique_random_string
|
242
|
+
##
|
243
|
+
## = Examples
|
244
|
+
## More examples are available in the repository;
|
245
|
+
## http://svn.rsence.org/contrib/plugins
|
246
|
+
## ..as well as the standard "main" plugin in the "plugins" directory.
|
247
|
+
##
|
248
|
+
##
|
249
|
+
## == A minimal Plugin bundle
|
250
|
+
## The minimal active plugin bundle (named "name_of_plugin")
|
251
|
+
## is defined like this:
|
252
|
+
##
|
253
|
+
## [dir] name_of_plugin
|
254
|
+
## |
|
255
|
+
## +---[file] name_of_plugin.rb
|
256
|
+
##
|
257
|
+
## This sample Plugin doesn't do anything except construct itself and
|
258
|
+
## respond as 'name_of_plugin'.
|
259
|
+
##
|
260
|
+
## Plugin.new.register('name_of_plugin')
|
261
|
+
##
|
262
|
+
## However, this is not very useful in itself, so you'll need to extend
|
263
|
+
## its functionality to do anything useful.
|
264
|
+
##
|
265
|
+
## == A simple Plugin extension
|
266
|
+
## This plugin logs session events to the logs/session_log file.
|
267
|
+
##
|
268
|
+
## [dir] ses_logger
|
269
|
+
## |
|
270
|
+
## +---[file] ses_logger.rb
|
271
|
+
## |
|
272
|
+
## +---[dir] logs
|
273
|
+
## |
|
274
|
+
## +---[file] session_log
|
275
|
+
##
|
276
|
+
## == Contents of "ses_logger.rb"
|
277
|
+
##
|
278
|
+
## class SessionLogger < Plugin
|
279
|
+
## def init
|
280
|
+
## super
|
281
|
+
## @logfile = false
|
282
|
+
## end
|
283
|
+
## def open
|
284
|
+
## log_path = bundle_path( 'session_log', 'logs' )
|
285
|
+
## @logfile = File.open( log_path, 'a' )
|
286
|
+
## end
|
287
|
+
## def close
|
288
|
+
## @logfile.close if @logfile
|
289
|
+
## @logfile = false
|
290
|
+
## end
|
291
|
+
## def flush
|
292
|
+
## @logfile.flush if @logfile
|
293
|
+
## end
|
294
|
+
## def init_ses( msg )
|
295
|
+
## super
|
296
|
+
## @logfile.write( "#{Time.new} -- Session id #{msg.ses_id} was created.\n" )
|
297
|
+
## end
|
298
|
+
## def restore_ses( msg )
|
299
|
+
## super
|
300
|
+
## @logfile.write( "#{Time.new} -- Session id #{msg.ses_id} was restored.\n" )
|
301
|
+
## end
|
302
|
+
## def idle( msg )
|
303
|
+
## @logfile.write( "#{Time.new} -- Client of session id #{msg.ses_id} connected.\n" )
|
304
|
+
## end
|
305
|
+
## end
|
306
|
+
## SessionLogger.new.register( 'ses_logger' )
|
307
|
+
##
|
303
308
|
class PluginTemplate
|
304
309
|
include PluginUtil
|
305
310
|
def self.bundle_type; :Plugin; end
|
@@ -394,7 +399,7 @@ module ::RSence
|
|
394
399
|
#
|
395
400
|
# These definitions are accessible as the +@values+ attribute.
|
396
401
|
def init_values
|
397
|
-
values_path =
|
402
|
+
values_path = bundle_path( 'values.yaml' )
|
398
403
|
return yaml_read( values_path )
|
399
404
|
end
|
400
405
|
|
@@ -418,7 +423,7 @@ module ::RSence
|
|
418
423
|
# Returns the source code of the javascript file +name+ in the 'js'
|
419
424
|
# subdirectory of the plugin bundle.
|
420
425
|
def read_js( js_name )
|
421
|
-
file_read(
|
426
|
+
file_read( bundle_path( js_name, 'js', '.js' ) )
|
422
427
|
end
|
423
428
|
|
424
429
|
# Deprecated name of +#read_js+
|
@@ -435,7 +440,7 @@ module ::RSence
|
|
435
440
|
if not ses.has_key?(:deps)
|
436
441
|
ses[:deps] = []
|
437
442
|
end
|
438
|
-
path =
|
443
|
+
path = bundle_path( js_name, 'js', '.js' )
|
439
444
|
unless ses[:deps].include?( path )
|
440
445
|
ses[:deps].push( path )
|
441
446
|
return file_read( path )
|