plezi 0.8.7 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c39d10feca5a72236133883875628f43ae714a86
4
- data.tar.gz: a1accf79bbde62e52e63836158e2e16d32cff059
3
+ metadata.gz: c1b45fb775eeba5ab996d2581da537e38640f7d4
4
+ data.tar.gz: 1060b31518ce6e3ee36cfa315ce916f72e7ab1d2
5
5
  SHA512:
6
- metadata.gz: b94655b0900f4c5c69ac17c81cd3ee83af7c19ce8e459bb523766210b92e9c16c2d56977f4537665c19985dd5a77638bc93505abb85af8a515162d167f378017
7
- data.tar.gz: dcdff9a3dd5ec25ef4c6d6ffb43714b52552df92e49258744841902371ad094dd1232cf0bd951e2a69b0773557d50bd8e29125c9f36016804354878883780f80
6
+ metadata.gz: 030e93b8a30cc04c3ad35c3aae1303e335b5bd1558469e9673cc14e07417c17b43e0a271a4441bee64b53c6785804b2a9460cd391d3402c2cc12e0093fe0a626
7
+ data.tar.gz: d663be79b8da32121b279848fc2cad6b5b66562ccbeedac9de25a41965bfa40380085a1b43af806f4f5e763a5e86eee7314e1f88fda8d5c43a2ba23d01c7fbc3
@@ -2,6 +2,29 @@
2
2
 
3
3
  ***
4
4
 
5
+ Change log v.0.9.0
6
+
7
+ **changes** (might break code):
8
+
9
+ - The error code file handling logic has been changed.
10
+
11
+ Plezi will no longer look the 404 and 505 files in the _public_ `:root` location. Instead the files should be placed at the **templates** folder if defined or at the app's root folder (_if templates folder isn't set_).
12
+
13
+ Also, error code files should now correctly specify that they are html templates - for example, the older '404.erb' should be renamed as '404.html.erb'
14
+
15
+ To update your application **please rename the error code files and move them to the app template's folder** (`appname/app/views`).
16
+
17
+ - Updated the template's welcome page and database configuration support. Existing applications shouldn't be effected.
18
+
19
+
20
+ **feature**: auto-pinging can now be customized for different hosting-server timeouts and it can also be disabled using the `Plezi.ping_interval` setter and getter.
21
+
22
+ **feature**: The Plezi framework can now impose limits on Websocket message sizes (even messages split across a number of frames) by using the `Plezi.ws_message_size_limit=` method.
23
+
24
+ **fix**: Outgoing Websocket messages would break for messages over 32KB (and sometimes over 16KB). This was caused by an issue in the frame splitting algorithm which is now resolved.
25
+
26
+ ***
27
+
5
28
  Change log v.0.8.7
6
29
 
7
30
  **minor performance**: streamlined the ping/pong Websocket process.
data/bin/plezi CHANGED
@@ -46,10 +46,21 @@ class AppTemplate
46
46
  app_tree["app"]["models"] ||= {}
47
47
  app_tree["app"]["views"] ||= {}
48
48
 
49
+ # set up templates for status error codes
50
+ app_tree["app"]["views"]["404.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.html"), __FILE__))
51
+ app_tree["app"]["views"]["500.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.html"), __FILE__))
52
+ app_tree["app"]["views"]["404.html.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.erb"), __FILE__))
53
+ app_tree["app"]["views"]["500.html.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.erb"), __FILE__))
54
+ app_tree["app"]["views"]["404.html.slim"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.slim"), __FILE__))
55
+ app_tree["app"]["views"]["500.html.slim"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.slim"), __FILE__))
56
+ app_tree["app"]["views"]["404.html.haml"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.haml"), __FILE__))
57
+ app_tree["app"]["views"]["500.html.haml"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.haml"), __FILE__))
58
+
49
59
  # set up the assets folder
50
60
  app_tree["assets"] ||= {}
51
61
  app_tree["assets"]["stylesheets"] ||= {}
52
62
  app_tree["assets"]["javascripts"] ||= {}
63
+ app_tree["assets"]["javascripts"]["websocket.js"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"websockets.js"), __FILE__)).gsub('appname', ARGV[1])
53
64
  app_tree["assets"]["welcome.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"welcome_page.html"), __FILE__)).gsub('appname', ARGV[1])
54
65
 
55
66
  # app core files.
@@ -92,19 +103,10 @@ class AppTemplate
92
103
 
93
104
  # set up a public folder for static file service
94
105
  app_tree["public"] ||= {}
95
- app_tree["public"]["404.slim"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.slim"), __FILE__))
96
- app_tree["public"]["500.slim"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.slim"), __FILE__))
97
- app_tree["public"]["404.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.html"), __FILE__))
98
- app_tree["public"]["500.html"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.html"), __FILE__))
99
- app_tree["public"]["404.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.erb"), __FILE__))
100
- app_tree["public"]["500.erb"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.erb"), __FILE__))
101
- app_tree["public"]["404.haml"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"404.haml"), __FILE__))
102
- app_tree["public"]["500.haml"] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"500.haml"), __FILE__))
103
106
  app_tree["public"]["assets"] ||= {}
104
107
  app_tree["public"]["assets"]["stylesheets"] ||= {}
105
108
  app_tree["public"]["assets"]["javascripts"] ||= {}
106
109
  app_tree["public"]["images"] ||= {}
107
- app_tree["public"]["images"]['plezi_gray.png'] ||= IO.read(::File.expand_path(File.join("..", "..", "resources" ,"plezi_gray.png"), __FILE__))
108
110
 
109
111
  end
110
112
 
@@ -113,7 +113,7 @@ Encoding.default_external = 'utf-8'
113
113
  # PL is a shortcut for the Plezi module, so that `PL == Plezi`.
114
114
  PL = Plezi
115
115
 
116
- # shortcut for Plezi.listen.
116
+ # shortcut for Plezi::DSL.listen.
117
117
  #
118
118
  def listen(params = {})
119
119
  Plezi::DSL.listen params
@@ -74,6 +74,7 @@ module Plezi
74
74
  rescue => e
75
75
  EventMachine.queue( [@socket], REMOVE_CONNECTION_PROC)
76
76
  end
77
+ true
77
78
  end
78
79
 
79
80
  # the non-blocking proc used for send_nonblock
@@ -106,10 +107,13 @@ module Plezi
106
107
  @protocol = false
107
108
  end
108
109
  end
109
- # closes the connection.
110
+
111
+ # the non-blocking proc used for send_nonblock
112
+ FLUSH_AND_CLOSE_PROC = Proc.new {|c| c.flush; EventMachine.remove_io c.socket}
113
+
114
+ # Closes the connection. This is always asynchronous and will return immidiately.
110
115
  def close
111
- flush
112
- EventMachine.queue [@socket], REMOVE_CONNECTION_PROC
116
+ EventMachine.queue [self], FLUSH_AND_CLOSE_PROC
113
117
  end
114
118
  alias :disconnect :close
115
119
 
@@ -213,7 +213,7 @@ module Plezi
213
213
  Plezi.run_every(3_600) {GC.start; Plezi.info "Refreshing worker threads."; EventMachine.stop; EventMachine.start Plezi.max_threads}
214
214
  # run_every( 1 , Proc.new() { Plezi.info "#{IO_CONNECTION_DIC.length} active connections ( #{ IO_CONNECTION_DIC.select{|k,v| v.protocol.is_a?(WSProtocol)} .length } websockets)." })
215
215
  # run_every 10 , -> {Plezi.info "Cache report: #{CACHE_STORE.length} objects cached." }
216
- puts "** Deprecation Warning:\n- The current code for default error pages will be changed in version 0.9.0.\n- Default error pages will follow a different naming and location conventions.\n- The updated design will be part of the updated `plezi` helper script.\nPlease review your code before upgrading to the 0.9.0 version.\n"
216
+ # puts "** Deprecation Warning:\n- The current code for default error pages will be changed in version 0.9.0.\n- Default error pages will follow a different naming and location conventions.\n- The updated design will be part of the updated `plezi` helper script.\nPlease review your code before upgrading to the 0.9.0 version.\n"
217
217
  puts "Services running Plezi version #{Plezi::VERSION}. Press ^C to stop"
218
218
  EventMachine.start Plezi.max_threads
219
219
 
@@ -95,18 +95,17 @@ module Plezi
95
95
  # sends a response for an error code, rendering the relevent file (if exists).
96
96
  def send_by_code request, code, headers = {}
97
97
  begin
98
- if params[:root]
99
- if defined?(::Slim) && Plezi.file_exists?(File.join(params[:root], "#{code}.slim"))
100
- Plezi.cache_data File.join(params[:root], "#{code}.slim"), Slim::Template.new( File.join( params[:root], "#{code}.slim" ) ) unless Plezi.cached? File.join(params[:root], "#{code}.slim")
101
- return send_raw_data request, Plezi.get_cached( File.join(params[:root], "#{code}.slim") ).render( self, request: request ), 'text/html', code, headers
102
- elsif defined?(::Haml) && Plezi.file_exists?(File.join(params[:root], "#{code}.haml"))
103
- Plezi.cache_data File.join(params[:root], "#{code}.haml"), Haml::Engine.new( IO.read( File.join( params[:root], "#{code}.haml" ) ) ) unless Plezi.cached? File.join(params[:root], "#{code}.haml")
104
- return send_raw_data request, Plezi.get_cached( File.join(params[:root], "#{code}.haml") ).render( self ), 'text/html', code, headers
105
- elsif defined?(::ERB) && Plezi.file_exists?(File.join(params[:root], "#{code}.erb"))
106
- return send_raw_data request, ERB.new( Plezi.load_file( File.join(params[:root], "#{code}.erb") ) ).result(binding), 'text/html', code, headers
107
- elsif Plezi.file_exists?(File.join(params[:root], "#{code}.html"))
108
- return send_file(request, File.join(params[:root], "#{code}.html"), code, headers)
109
- end
98
+ @base_code_path ||= params[:templates] || File.expand_path('.')
99
+ if defined?(::Slim) && Plezi.file_exists?(fn = File.join(@base_code_path, "#{code}.html.slim"))
100
+ Plezi.cache_data fn, Slim::Template.new( fn ) unless Plezi.cached? fn
101
+ return send_raw_data request, Plezi.get_cached( fn ).render( self, request: request ), 'text/html', code, headers
102
+ elsif defined?(::Haml) && Plezi.file_exists?(fn = File.join(@base_code_path, "#{code}.html.haml"))
103
+ Plezi.cache_data fn, Haml::Engine.new( IO.read( fn ) ) unless Plezi.cached? fn
104
+ return send_raw_data request, Plezi.get_cached( File.join(@base_code_path, "#{code}.html.haml") ).render( self ), 'text/html', code, headers
105
+ elsif defined?(::ERB) && Plezi.file_exists?(fn = File.join(@base_code_path, "#{code}.html.erb"))
106
+ return send_raw_data request, ERB.new( Plezi.load_file( fn ) ).result(binding), 'text/html', code, headers
107
+ elsif Plezi.file_exists?(fn = File.join(@base_code_path, "#{code}.html"))
108
+ return send_file(request, fn, code, headers)
110
109
  end
111
110
  return true if send_raw_data(request, HTTPResponse::STATUS_CODES[code], 'text/plain', code, headers)
112
111
  rescue Exception => e
@@ -31,11 +31,11 @@ module Plezi
31
31
  def on_message
32
32
  # parse the request
33
33
  parse_message
34
- if (@parser_stage == 1) && @parser_data[:version] >= 1.1
35
- # send 100 continue message????? doesn't work! both Crome and Safari go crazy if this is sent after the request was sent (but before all the packets were recieved... msgs over 1 Mb).
36
- # Plezi.push_event Proc.new { Plezi.info "sending continue signal."; connection.send_nonblock "100 Continue\r\n\r\n" }
37
- # connection.send_unsafe_interrupt "100 Continue\r\n\r\n" # causes double lock on connection
38
- end
34
+ # if (@parser_stage == 1) && @parser_data[:version] >= 1.1
35
+ # # send 100 continue message????? doesn't work! both Crome and Safari go crazy if this is sent after the request was sent (but before all the packets were recieved... msgs over 1 Mb).
36
+ # # Plezi.push_event Proc.new { Plezi.info "sending continue signal."; connection.send_nonblock "100 Continue\r\n\r\n" }
37
+ # # connection.send_unsafe_interrupt "100 Continue\r\n\r\n" # causes double lock on connection
38
+ # end
39
39
  true
40
40
  end
41
41
 
@@ -124,6 +124,7 @@ module Plezi
124
124
  end
125
125
  @parser_data[:step] = 0
126
126
  @parser_stage += 1
127
+ review_message_size
127
128
  end
128
129
  if @parser_stage == 2 && @parser_data[:mask] == 1
129
130
  @parser_data[:mask_key] = data.slice!(0,4)
@@ -187,6 +188,48 @@ module Plezi
187
188
  @parser_data[:body].clear
188
189
  @parser_data[:step] = 0
189
190
  end
191
+ #reviews the message size and closes the connection if expected message size is over the allowed limit.
192
+ def review_message_size
193
+ if ( self.class.message_size_limit.to_i > 0 ) && ( ( @parser_data[:len] + @message.bytesize ) > self.class.message_size_limit.to_i )
194
+ Plezi.callback @connection, :disconnect
195
+ @message.clear
196
+ @parser_data[:step] = 0
197
+ @parser_data[:body].clear
198
+ @parser_stage = -1
199
+ return false
200
+ end
201
+ true
202
+ end
203
+
204
+ # Sets the message byte size limit for a Websocket message. Defaults to 0 (no limit)
205
+ #
206
+ # Although memory will be allocated for the latest TCP/IP frame,
207
+ # this allows the websocket to disconnect if the incoming expected message size exceeds the allowed maximum size.
208
+ #
209
+ # If the sessage size limit is exceeded, the disconnection will be immidiate as an attack will be assumed. The protocol's normal disconnect sequesnce will be discarded.
210
+ def self.message_size_limit=val
211
+ @message_size_limit = val
212
+ end
213
+ # Gets the message byte size limit for a Websocket message. Defaults to 0 (no limit)
214
+ def self.message_size_limit
215
+ @message_size_limit
216
+ end
217
+ message_size_limit = 0
218
+
219
+ end
220
+
221
+ # Sets the message byte size limit for a Websocket message. Defaults to 0 (no limit)
222
+ #
223
+ # Although memory will be allocated for the latest TCP/IP frame,
224
+ # this allows the websocket to disconnect if the incoming expected message size exceeds the allowed maximum size.
225
+ #
226
+ # If the sessage size limit is exceeded, the disconnection will be immidiate as an attack will be assumed. The protocol's normal disconnect sequesnce will be discarded.
227
+ def self.ws_message_size_limit=val
228
+ WSProtocol.message_size_limit = val
229
+ end
230
+ # Gets the message byte size limit for a Websocket message. Defaults to 0 (no limit)
231
+ def self.ws_message_size_limit
232
+ WSProtocol.message_size_limit
190
233
  end
191
234
  end
192
235
 
@@ -52,9 +52,14 @@ module Plezi
52
52
  end
53
53
  alias :close :disconnect
54
54
 
55
- # sends data through the socket. a shortcut for ws_client.response <<
55
+ # Asynchronously sends data through the socket. a shortcut for ws_client.response <<
56
56
  def << data
57
- @response << data
57
+ @response << data
58
+ end
59
+
60
+ # Synchronously sends data through the socket. a shortcut for ws_client.response <<
61
+ def send data
62
+ @response.send data
58
63
  end
59
64
 
60
65
  # Create a simple Websocket Client(!)
@@ -17,7 +17,22 @@ module Plezi
17
17
  #the request.
18
18
  attr_accessor :request
19
19
 
20
- PING_PROC = Proc.new {|res| EventMachine.timed_job 45, 1, [res.ping], PING_PROC unless res.service.disconnected? }
20
+ # Sets the defalt Websockt auto-ping interval.
21
+ #
22
+ # The default ping interval is 45 seconds.
23
+ #
24
+ # It's possible to set the ping interval to false, thereby disabling auto-pinging.
25
+ def self.ping_interval=(val)
26
+ @ping_interval = val
27
+ end
28
+ # Returns the defalt Websockt auto-ping interval.
29
+ #
30
+ # Plezi will automatically send a ping frame to keep websocket connections open.
31
+ # This auto-pinging can be disabled by setting the `ping_interval` to false.
32
+ def self.ping_interval
33
+ @ping_interval ||= 45
34
+ end
35
+ PING_PROC = Proc.new {|res| EventMachine.timed_job ping_interval, 1, [res.ping], PING_PROC unless res.service.disconnected? || !ping_interval }
21
36
 
22
37
  def initialize request
23
38
  @request, @service = request,request.service
@@ -81,20 +96,20 @@ module Plezi
81
96
  service.locker.locked? ? (EventMachine.queue [service], CLOSE_PROC) : (CLOSE_PROC.call(service))
82
97
  end
83
98
 
84
- FRAME_SIZE_LIMIT = 131_072
99
+ FRAME_SIZE_LIMIT = 131_072 # javascript to test: str = '0123456789'; bigstr = ""; for(i = 0; i<=1033200; i+=1) {bigstr += str}; ws = new WebSocket('ws://localhost:3000/ws/size') ; ws.onmessage = function(e) {console.log(e.data.length)};ws. onopen = function(e) {ws.send(bigstr)}
85
100
 
86
- # Dangerzone! ()alters the string, use `send` instead: formats the data as one or more WebSocket frames.
101
+ # Dangerzone! use `send` instead: formats the data as one or more WebSocket frames.
87
102
  def self.frame_data data, op_code = nil, fin = true
88
103
  # set up variables
89
104
  frame = ''.force_encoding('binary')
90
105
  op_code ||= (data.encoding.name == 'UTF-8' ? 1 : 2)
91
106
 
92
107
 
93
- if data[FRAME_SIZE_LIMIT]
108
+ if data[FRAME_SIZE_LIMIT] && fin
94
109
  # fragment big data chuncks into smaller frames - op-code reset for 0 for all future frames.
95
110
  data = data.dup
96
111
  data.force_encoding('binary')
97
- [frame << frame_data(data.slice!(0..FRAME_SIZE_LIMIT), op_code, false), op_code = 0] while data.length > FRAME_SIZE_LIMIT # 1048576
112
+ [frame << frame_data(data.slice!(0...FRAME_SIZE_LIMIT), op_code, false), op_code = 0] while data.length > FRAME_SIZE_LIMIT # 1048576
98
113
  # frame << frame_data(data.slice!(0..1048576), op_code, false)
99
114
  # data =
100
115
  # op_code = 0
@@ -110,7 +125,7 @@ module Plezi
110
125
 
111
126
  if data.length < 125
112
127
  frame << data.length.chr
113
- elsif data.length.bit_length < 16
128
+ elsif data.length.bit_length <= 16
114
129
  frame << 126.chr
115
130
  frame << [data.length].pack('S>')
116
131
  else
@@ -123,4 +138,24 @@ module Plezi
123
138
  frame
124
139
  end
125
140
  end
141
+
142
+ module_function
143
+ # Sets the defalt Websockt auto-ping interval.
144
+ #
145
+ # This method accepts one value, which should be either a number in seconds or `false`.
146
+ #
147
+ # The default ping interval is 45 seconds.
148
+ #
149
+ # It's possible to set the ping interval to false, thereby disabling auto-pinging.
150
+ def ping_interval=(val)
151
+ WSResponse.ping_interval = val
152
+ end
153
+ # Returns the defalt Websockt auto-ping interval.
154
+ #
155
+ # Plezi will automatically send a ping frame to keep websocket connections open.
156
+ # This auto-pinging can be disabled by setting the `ping_interval` to false.
157
+ def ping_interval
158
+ WSResponse.ping_interval
159
+ end
160
+
126
161
  end
@@ -1,3 +1,3 @@
1
1
  module Plezi
2
- VERSION = "0.8.7"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Plezi::VERSION
9
9
  spec.authors = ["Boaz Segev"]
10
10
  spec.email = ['boaz@2be.co.il']
11
- spec.summary = %q{Plezi is the native Ruby Framework for real time web-apps, with Websockets, RESTful routing and HTTP streaming support.}
12
- spec.description = %q{Plezi is the native Ruby Framework for real time web-apps, with Websockets, RESTful routing and HTTP streaming support.}
11
+ spec.summary = %q{Plezi is the native Ruby Framework for real time web-apps. An easy way to write Websockets, RESTful routing and HTTP streaming apps.}
12
+ spec.description = %q{Plezi is the native Ruby Framework for real time web-apps. An easy way to write Websockets, RESTful routing and HTTP streaming apps.}
13
13
  spec.homepage = "http://boazsegev.github.io/plezi/"
14
14
  spec.license = "MIT"
15
15
 
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
 
24
- spec.post_install_message = "** Deprecation Warning:\n- The current code for default error pages will be changed in version 0.9.0.\n- Default error pages will follow a different naming and location conventions.\n- The updated design will be part of the updated `plezi` helper script.\nPlease review your code before upgrading to the 0.9.0 version.\n\nThank you for installing Plezi, the native Ruby Framework for real time web-apps."
25
- spec.post_install_message ||= "Thank you for installing Plezi, the native Ruby Framework for real time web-apps."
24
+ spec.post_install_message = "Thank you for installing Plezi, the native Ruby Framework for real time web-apps."
25
+ # spec.post_install_message = "** Deprecation Warning:\n- The current code for default error pages will be changed in version 0.9.0.\n- Default error pages will follow a different naming and location conventions.\n- The updated design will be part of the updated `plezi` helper script.\nPlease review your code before upgrading to the 0.9.0 version.\n\nThank you for installing Plezi, the native Ruby Framework for real time web-apps."
26
26
 
27
27
  end
@@ -11,21 +11,12 @@
11
11
  # http://sequel.jeremyevans.net
12
12
  if defined? Sequel
13
13
 
14
- if defined? SQLite3
15
- # An in-memory Sqlite3 connection:
16
- # DB = Sequel.sqlite
17
-
18
- # A Sqlite3 connection to a persistent database
19
- DB = Sequel.sqlite(Root.join('db', 'db.sqlite3').to_s)
20
-
21
- elsif defined? PG
22
- if ENV['DYNO']
23
- # A Postgres connection for Heroku:
24
- DB = Sequel.connect(ENV['HEROKU_POSTGRESQL_RED_URL'])
25
- else
26
- # app name is the same as the root app folder: Root.to_s.split(/\/\\/).last
27
- DB = Sequel.connect("postgres://localhost/#{Root.to_s.split(/[\/\\]/).last}")
28
- end
14
+ if defined? PG && ENV['DYNO']
15
+ # A default Postgres connection for Heroku:
16
+ DB = Sequel.connect(ENV['HEROKU_POSTGRESQL_RED_URL'])
17
+ else
18
+ # use db/config.yaml to connect to database
19
+ DB = Sequel.connect( YAML::load( File.open( Root.join('db', 'config.yml').to_s ) )[ ENV["ENV"].to_s ] )
29
20
  end
30
21
  if defined? Rake
31
22
  ##########
@@ -1,28 +1,29 @@
1
-
2
- // remember to set your websocket uri as an absolute path!
3
- var ws_uri = "ws://echo.websocket.org/";
1
+ // Your websocket URI should be an absolute path. The following sets the base URI.
2
+ var ws_uri = 'ws://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port) );
3
+ // remember to add the specific controller's path to your websocket URI.
4
+ ws_uri += "/";
5
+ // websocket variable.
4
6
  var websocket = NaN
5
7
 
6
8
  function init_websocket()
7
9
  {
8
10
  websocket = new WebSocket(ws_uri);
9
- websocket.onopen = function(e) { on_open(e) };
10
- websocket.onclose = function(e) { on_close(e) };
11
- websocket.onmessage = function(e) { on_message(e) };
12
- websocket.onerror = function(e) { on_error(e) }; }
13
-
14
- function on_open(e) {
11
+ websocket.onopen = function(e) {
15
12
  // what do you want to do now?
16
- }
17
- function on_close(e) {
13
+ };
14
+
15
+ websocket.onclose = function(e) {
18
16
  // you probably want to reopen the websocket if it closes.
19
17
  init_websocket()
20
- }
21
- function on_message(e) {
18
+ };
19
+ websocket.onerror = function(e) {
22
20
  // what do you want to do now?
23
- }
24
- function on_error(e) {
21
+ };
22
+ websocket.onmessage = function(e) {
25
23
  // what do you want to do now?
26
- }
24
+ console.log(e.data);
25
+ // to use JSON, use:
26
+ // msg = JSON.parse(e.data); // remember to use JSON also in your Plezi controller.
27
+ };
27
28
  }
28
- window.addEventListener("load", init, false);
29
+ window.addEventListener("load", init_websocket, false);
@@ -1,30 +1,64 @@
1
- <!DOCTYPE html><head><title>appname - Feed Me!</title><style type="text/css">body, html
1
+ <!DOCTYPE html><head><title>appname - Feed Me!</title>
2
+ <link href='http://fonts.googleapis.com/css?family=Shadows+Into+Light|Architects+Daughter' rel='stylesheet' type='text/css'>
3
+
4
+ <link href="https://fonts.googleapis.com/css?family=Architects+Daughter" rel="stylesheet" type="text/css">
5
+ <style type="text/css">
6
+ /*
7
+ med-blue: #44518E
8
+ dark-gray: #424A70
9
+ blue: #1B2864
10
+ light-blue: #818ECE
11
+ light-gray: #99A3CE
12
+ */
13
+ body, html
2
14
  {
3
- background-color: #eee;
15
+ background-color: #99A3CE;
4
16
  padding: 0; margin: 0;
5
17
  width: 100%;
6
18
  font-size: 1em;
7
19
  }
8
- body, html, h1, #wrapper, #wrapper h2
9
- {
10
- background-image: url(/images/plezi_gray.png);
11
- background-position: center top;
12
- background-origin: inherit;
13
- background-repeat: no-repeat;
14
- background-size: 88% auto;
15
- background-attachment: fixed;
16
-
17
- }
18
20
 
19
21
  h1
20
22
  {
21
- background-color: #ddd;
22
- color: #00a;
23
+ font-family: 'Indie Flower', cursive;
24
+ background-color: #1B2864;
25
+ color: #99A3CE;
23
26
  text-align: center;
24
- border-bottom: 1px solid #000;
27
+ border-bottom: 1px solid #424A70;
25
28
  margin: 0 0 1em 0;
26
29
  padding: 0.5em 0;
27
30
  width: 100%;
31
+
32
+ }
33
+ h2, h3
34
+ {
35
+ background-color: #44518E;
36
+ color: #99A3CE;
37
+ text-align: left;
38
+ margin: 0 0 1em 0;
39
+ padding: 0.5em 5%;
40
+ border-radius: 20px;
41
+ font-family: 'Shadows Into Light', cursive;
42
+ }
43
+ h2:before {
44
+ content: "|||";
45
+ color: #424A70;
46
+ padding-right: 0.3em;
47
+ margin-left: -1.5em;
48
+ }
49
+ h3:before {
50
+ content: "|||||";
51
+ color: #424A70;
52
+ padding-right: 0.3em;
53
+ margin-left: -2em;
54
+ }
55
+ h1 a, h2 a, h3 a
56
+ {
57
+ color: #EBCD86;
58
+ }
59
+ h1 a:hover, h2 a:hover, h3 a:hover
60
+ {
61
+ color: #EBD7A6;
28
62
  }
29
63
  p
30
64
  {
@@ -34,12 +68,12 @@ p
34
68
  }
35
69
  a
36
70
  {
37
- color: #a04;
71
+ color: #D0AC54;
38
72
  text-decoration: none;
39
73
  }
40
74
  a:hover
41
75
  {
42
- color: #70f;
76
+ color: #927121;
43
77
  text-decoration: underline;
44
78
  }
45
79
  #wrapper
@@ -51,15 +85,7 @@ a:hover
51
85
  min-height: 50%;
52
86
  color: #007;
53
87
  }
54
- #wrapper h2
55
- {
56
- background-color: #ddd;
57
- color: #008;
58
- text-align: left;
59
- margin: 0 0 1em 0;
60
- padding: 0.5em 5%;
61
- border-radius: 20px;
62
- }
88
+
63
89
  #wrapper p{ padding: 0 2%;}
64
90
  .bold { font-weight: bold; }
65
91
  #wrapper ol li{ padding: 0 2%;}
@@ -69,4 +95,35 @@ pre
69
95
  padding: 0.5em 0;
70
96
  background-color: #444;
71
97
  color: #ddd;
72
- }</style></head><body><h1>Welcome to <a href="https://github.com/boazsegev/plezi">Plezi</a></h1><div id="wrapper"><h2>Congratulations, appname is running - What's next?</h2><p><span class="bold">Congratulations</span>, you're now running appname and it has so much potential!</p><p>appname started out <a href="https://github.com/boazsegev/plezi">Plezi</a> and it's your quest to feed it your code and make sure appname grows strong and happy.</p><p>You're the master of this quest, and your next steps might include:</p><ol><li><p class="bold">Deciding which gems to use:</p><ul><li>edit Gemfile in the appname folder.</li></ul></li><li><p class="bold">Reviewing the sample code and feeding <a href="https://github.com/boazsegev/plezi">Plezi</a> your code:</p><ul><li>Review the 'sample_controller.rb' file in the appname/app/controllers folder.</li><li>Delete the 'sample_controller.rb' file and this file (appname/assets/welcome.html).</li><li>Write your own controller and code.</li><li>Edit the 'routes.rb' file to set up your routes.</li></ul></li><li><p><span class="bold">Having fun</span> and submitting any issues you discover to the <a href="https://github.com/boazsegev/plezi">Plezi Github Project.</a></p></li></ol><p class="bold">Good Luck!</p></div></body>
98
+ }
99
+
100
+ </style>
101
+ </head>
102
+ <body>
103
+ <h1>Welcome to <a href="https://github.com/boazsegev/plezi">Plezi</a></h1>
104
+ <div id="wrapper">
105
+ <h2>Congratulations, <a href='/'>appname</a> is running - What's next?</h2>
106
+ <p><span class="bold">Congratulations</span>, you're now running appname and it has so much potential!</p>
107
+ <p>appname started out <a href="https://github.com/boazsegev/plezi">Plezi</a> and it's your quest to feed it your code and make sure appname grows strong and happy.</p>
108
+ <p>You're the master of this quest, and your next steps might include:</p>
109
+ <ol><li><p class="bold">Deciding which gems to use:</p>
110
+ <ul>
111
+ <li>edit Gemfile in the appname folder.</li>
112
+ </ul>
113
+ </li>
114
+ <li>
115
+ <p class="bold">Reviewing the sample code and feeding <a href="https://github.com/boazsegev/plezi">Plezi</a> your code:</p>
116
+ <ul>
117
+ <li>Review the 'sample_controller.rb' file in the appname/app/controllers folder.</li>
118
+ <li>Delete the 'sample_controller.rb' file and this file (appname/assets/welcome.html).</li>
119
+ <li>Write your own controller and code.</li>
120
+ <li>Edit the 'routes.rb' file to set up your routes.</li>
121
+ </ul>
122
+ </li>
123
+ <li>
124
+ <p><span class="bold">Having fun</span> and submitting any issues you discover to the <a href="https://github.com/boazsegev/plezi">Plezi Github Project.</a></p>
125
+ </li>
126
+ </ol>
127
+ <p class="bold">Good Luck!</p>
128
+ </div>
129
+ </body>
@@ -135,6 +135,15 @@ class TestCtrl
135
135
  end
136
136
  end
137
137
 
138
+ class WSsizeTestCtrl
139
+ # called when new Websocket data is recieved
140
+ #
141
+ # data is a string that contains binary or UTF8 (message dependent) data.
142
+ def on_message data
143
+ response << data
144
+ end
145
+ end
146
+
138
147
  module PleziTestTasks
139
148
  module_function
140
149
 
@@ -251,7 +260,7 @@ module PleziTestTasks
251
260
  go_test = false
252
261
  end
253
262
  end
254
- ws3 = Plezi::WebsocketClient.connect_to("wss://localhost:3030") do |msg|
263
+ ws3 = Plezi::WebsocketClient.connect_to("ws://localhost:3000") do |msg|
255
264
  if msg.match /uuid: ([^s]*)/
256
265
  ws2 << "to: #{msg.match(/^uuid: ([^s]*)/)[1]}"
257
266
  puts " * Websocket UUID for unicast testing: #{msg.match(/^uuid: ([^s]*)/)[1]}"
@@ -290,6 +299,27 @@ module PleziTestTasks
290
299
  PL.on_shutdown {puts " * Websocket broadcast message test: #{RESULTS[broadcast_test]}" unless broadcast_test}
291
300
  PL.on_shutdown {puts " * Websocket unicast message test: #{RESULTS[unicast_test]}"}
292
301
  end
302
+ def test_websocket_sizes
303
+ should_disconnect = false
304
+ ws = Plezi::WebsocketClient.connect_to("ws://localhost:3000/ws/size") do |msg|
305
+ if should_disconnect
306
+ puts " * Websocket size disconnection test: #{RESULTS[false]}"
307
+ else
308
+ puts " * Websocket message size test: got #{msg.bytesize} bytes"
309
+ end
310
+
311
+ end
312
+ ws.on_disconnect do
313
+ puts " * Websocket size disconnection test: #{RESULTS[should_disconnect]}"
314
+ end
315
+ str = 'a'
316
+ time_now = Time.now
317
+ 6.times {|i| str = str * 2**i;puts " * Websocket message size test: sending #{str.bytesize} bytes"; ws.send str; sleep 0.2 }
318
+ sleep (Time.now - time_now + 1)
319
+ should_disconnect = true
320
+ Plezi.ws_message_size_limit = 1024
321
+ ws << str
322
+ end
293
323
  def test_404
294
324
  puts " * 404 not found and router continuity tests: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/get404" ).code == '404' ]}"
295
325
 
@@ -323,6 +353,8 @@ route("/ssl") {|req, res| res << "false" }
323
353
  listen port: 3030, ssl: true
324
354
  route("/ssl") {|req, res| res << "true" }
325
355
 
356
+ shared_route 'ws/size', WSsizeTestCtrl
357
+
326
358
  shared_route '/some/:multi{path|another_path}/(:option){route|test}/(:id)/(:optional)', TestCtrl
327
359
  shared_route '/', TestCtrl
328
360
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plezi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-25 00:00:00.000000000 Z
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,8 +38,8 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
- description: Plezi is the native Ruby Framework for real time web-apps, with Websockets,
42
- RESTful routing and HTTP streaming support.
41
+ description: Plezi is the native Ruby Framework for real time web-apps. An easy way
42
+ to write Websockets, RESTful routing and HTTP streaming apps.
43
43
  email:
44
44
  - boaz@2be.co.il
45
45
  executables:
@@ -106,7 +106,6 @@ files:
106
106
  - resources/haml_config.rb
107
107
  - resources/i18n_config.rb
108
108
  - resources/oauth_config.rb
109
- - resources/plezi_gray.png
110
109
  - resources/plezi_websockets.html
111
110
  - resources/rakefile
112
111
  - resources/redis_config.rb
@@ -119,14 +118,8 @@ homepage: http://boazsegev.github.io/plezi/
119
118
  licenses:
120
119
  - MIT
121
120
  metadata: {}
122
- post_install_message: |-
123
- ** Deprecation Warning:
124
- - The current code for default error pages will be changed in version 0.9.0.
125
- - Default error pages will follow a different naming and location conventions.
126
- - The updated design will be part of the updated `plezi` helper script.
127
- Please review your code before upgrading to the 0.9.0 version.
128
-
129
- Thank you for installing Plezi, the native Ruby Framework for real time web-apps.
121
+ post_install_message: Thank you for installing Plezi, the native Ruby Framework for
122
+ real time web-apps.
130
123
  rdoc_options: []
131
124
  require_paths:
132
125
  - lib
@@ -145,7 +138,7 @@ rubyforge_project:
145
138
  rubygems_version: 2.4.7
146
139
  signing_key:
147
140
  specification_version: 4
148
- summary: Plezi is the native Ruby Framework for real time web-apps, with Websockets,
149
- RESTful routing and HTTP streaming support.
141
+ summary: Plezi is the native Ruby Framework for real time web-apps. An easy way to
142
+ write Websockets, RESTful routing and HTTP streaming apps.
150
143
  test_files:
151
144
  - test/plezi_tests.rb
Binary file