Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Move everything Cramp::Controller::* to Cramp::*.

Before :

  class Home < Cramp::Controller::Action
  end

After :

  class Home < Cramp::Action
  end

Similarly, Cramp::Controller::Websocket now becomes Cramp::Websocket.
  • Loading branch information...
commit 968e9030f253f74c94562555f3244aad4fe03e89 1 parent 7d3f477
Pratik authored
Showing with 420 additions and 443 deletions.
  1. +2 −2 examples/full.rb
  2. +2 −2 examples/full.ru
  3. +3 −3 examples/hello_websock.rb
  4. +2 −2 examples/hello_world.rb
  5. +2 −2 examples/hello_world.ru
  6. +3 −3 examples/rainsocket.ru
  7. +2 −2 examples/streaming.rb
  8. +2 −2 examples/with_usher.rb
  9. +11 −0 lib/cramp.rb
  10. +69 −0 lib/cramp/abstract.rb
  11. +12 −0 lib/cramp/action.rb
  12. +48 −0 lib/cramp/body.rb
  13. +48 −0 lib/cramp/callbacks.rb
  14. +0 −15 lib/cramp/controller.rb
  15. +0 −71 lib/cramp/controller/abstract.rb
  16. +0 −14 lib/cramp/controller/action.rb
  17. +0 −50 lib/cramp/controller/body.rb
  18. +0 −50 lib/cramp/controller/callbacks.rb
  19. +0 −21 lib/cramp/controller/keep_connection_alive.rb
  20. +0 −51 lib/cramp/controller/periodic_timer.rb
  21. +0 −13 lib/cramp/controller/rendering.rb
  22. +0 −57 lib/cramp/controller/test_case.rb
  23. +0 −63 lib/cramp/controller/websocket.rb
  24. +19 −0 lib/cramp/keep_connection_alive.rb
  25. +49 −0 lib/cramp/periodic_timer.rb
  26. +11 −0 lib/cramp/rendering.rb
  27. +54 −0 lib/cramp/test_case.rb
  28. +61 −0 lib/cramp/websocket.rb
  29. +1 −1  lib/cramp/{controller → }/websocket/rainbows_backend.rb
  30. +1 −1  lib/cramp/{controller → }/websocket/thin_backend.rb
  31. +6 −6 test/controller/base_test.rb
  32. +2 −2 test/controller/callback_test.rb
  33. +2 −2 test/controller/keep_alive_test.rb
  34. +2 −2 test/controller/multiple_rendering_test.rb
  35. +3 −3 test/controller/periodic_timer_test.rb
  36. +2 −2 test/controller/websocket_test.rb
  37. +1 −1  test/test_helper.rb
4 examples/full.rb
View
@@ -3,7 +3,7 @@
Bundler.setup(:default, :example)
-require 'cramp/controller'
+require 'cramp'
require 'tramp'
require 'usher'
require 'thin'
@@ -17,7 +17,7 @@ class User < Tramp::Base
validates_presence_of :name
end
-class UsersController < Cramp::Controller::Action
+class UsersController < Cramp::Action
before_start :verify_id, :find_user
def verify_id
4 examples/full.ru
View
@@ -1,7 +1,7 @@
require File.join(File.dirname(__FILE__), "../vendor/gems/environment")
$: << File.join(File.dirname(__FILE__), "../lib")
-require 'cramp/controller'
+require 'cramp'
require 'cramp/model'
Cramp::Model.init(:username => 'root', :database => 'arel_development')
@@ -13,7 +13,7 @@ class User < Cramp::Model::Base
validates_presence_of :name
end
-class UsersController < Cramp::Controller::Action
+class UsersController < Cramp::Action
before_start :verify_id, :find_user
def verify_id
6 examples/hello_websock.rb
View
@@ -2,12 +2,12 @@
require "bundler"
Bundler.setup(:default, :example)
-require 'cramp/controller'
+require 'cramp'
require 'thin'
-Cramp::Controller::Websocket.backend = :thin
+Cramp::Websocket.backend = :thin
-class WelcomeController < Cramp::Controller::Websocket
+class WelcomeController < Cramp::Websocket
periodic_timer :send_hello_world, :every => 2
on_data :received_data
4 examples/hello_world.rb
View
@@ -2,10 +2,10 @@
require "bundler"
Bundler.setup(:default, :example)
-require 'cramp/controller'
+require 'cramp'
require 'thin'
-class WelcomeController < Cramp::Controller::Action
+class WelcomeController < Cramp::Action
def start
render "Hello World"
finish
4 examples/hello_world.ru
View
@@ -2,9 +2,9 @@ require "rubygems"
require "bundler"
Bundler.setup(:default, :example)
-require 'cramp/controller'
+require 'cramp'
-class WelcomeController < Cramp::Controller::Action
+class WelcomeController < Cramp::Action
def start
render "Hello World"
finish
6 examples/rainsocket.ru
View
@@ -2,11 +2,11 @@ require "rubygems"
require "bundler"
Bundler.setup(:default, :example)
-require 'cramp/controller'
+require 'cramp'
-Cramp::Controller::Websocket.backend = :rainbows
+Cramp::Websocket.backend = :rainbows
-class WelcomeController < Cramp::Controller::Websocket
+class WelcomeController < Cramp::Websocket
periodic_timer :send_hello_world, :every => 2
on_data :received_data
4 examples/streaming.rb
View
@@ -2,10 +2,10 @@
require "bundler"
Bundler.setup(:default, :example)
-require 'cramp/controller'
+require 'cramp'
require 'thin'
-class StreamController < Cramp::Controller::Action
+class StreamController < Cramp::Action
periodic_timer :send_data, :every => 1
periodic_timer :check_limit, :every => 2
4 examples/with_usher.rb
View
@@ -2,11 +2,11 @@
require "bundler"
Bundler.setup(:default, :example)
-require 'cramp/controller'
+require 'cramp'
require 'usher'
require 'thin'
-class HomeController < Cramp::Controller::Action
+class HomeController < Cramp::Action
def before_start
if params[:password] != 'foo'
halt 401, {}, "Bad Password"
11 lib/cramp.rb
View
@@ -11,8 +11,19 @@
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/buffered_logger'
+require 'rack'
+
module Cramp
VERSION = '0.10'
mattr_accessor :logger
+
+ autoload :Action, "cramp/action"
+ autoload :Websocket, "cramp/websocket"
+ autoload :Body, "cramp/body"
+ autoload :PeriodicTimer, "cramp/periodic_timer"
+ autoload :KeepConnectionAlive, "cramp/keep_connection_alive"
+ autoload :Abstract, "cramp/abstract"
+ autoload :Callbacks, "cramp/callbacks"
+ autoload :TestCase, "cramp/test_case"
end
69 lib/cramp/abstract.rb
View
@@ -0,0 +1,69 @@
+require 'active_support/core_ext/hash/keys'
+
+module Cramp
+ class Abstract
+
+ include Callbacks
+
+ ASYNC_RESPONSE = [-1, {}, []].freeze
+
+ class << self
+ def call(env)
+ controller = new(env).process
+ end
+ end
+
+ def initialize(env)
+ @env = env
+ end
+
+ def process
+ EM.next_tick { before_start }
+ ASYNC_RESPONSE
+ end
+
+ def continue
+ init_async_body
+
+ status, headers = respond_with
+ send_initial_response(status, headers, @body)
+
+ EM.next_tick { start } if respond_to?(:start)
+ EM.next_tick { on_start }
+ end
+
+ def respond_with
+ [200, {'Content-Type' => 'text/html'}]
+ end
+
+ def init_async_body
+ @body = Body.new
+
+ if self.class.on_finish_callbacks.any?
+ @body.callback { on_finish }
+ @body.errback { on_finish }
+ end
+ end
+
+ def finish
+ @body.succeed
+ end
+
+ def send_initial_response(response_status, response_headers, response_body)
+ EM.next_tick { @env['async.callback'].call [response_status, response_headers, response_body] }
+ end
+
+ def halt(status, headers = {}, halt_body = '')
+ send_initial_response(status, headers, halt_body)
+ end
+
+ def request
+ @request ||= Rack::Request.new(@env)
+ end
+
+ def params
+ @params ||= request.params.update(@env['usher.params']).symbolize_keys
+ end
+
+ end
+end
12 lib/cramp/action.rb
View
@@ -0,0 +1,12 @@
+module Cramp
+ class Action < Abstract
+
+ include PeriodicTimer
+ include KeepConnectionAlive
+
+ def render(body)
+ @body.call(body)
+ end
+
+ end
+end
48 lib/cramp/body.rb
View
@@ -0,0 +1,48 @@
+# Copyright 2008 James Tucker <raggi@rubyforge.org>.
+
+module Cramp
+ class Body
+ include EventMachine::Deferrable
+
+ def initialize
+ @queue = []
+
+ # Make sure to flush out the queue before closing the connection
+ callback { flush }
+ end
+
+ def call(body)
+ @queue << body
+ schedule_dequeue
+ end
+
+ def each &blk
+ @body_callback = blk
+ schedule_dequeue
+ end
+
+ def closed?
+ @deferred_status != :unknown
+ end
+
+ def flush
+ return unless @body_callback
+
+ until @queue.empty?
+ Array(@queue.shift).each {|chunk| @body_callback.call(chunk) }
+ end
+ end
+
+ def schedule_dequeue
+ return unless @body_callback
+
+ EventMachine.next_tick do
+ next unless body = @queue.shift
+
+ Array(body).each {|chunk| @body_callback.call(chunk) }
+ schedule_dequeue unless @queue.empty?
+ end
+ end
+
+ end
+end
48 lib/cramp/callbacks.rb
View
@@ -0,0 +1,48 @@
+module Cramp
+ module Callbacks
+
+ extend ActiveSupport::Concern
+
+ included do
+ class_inheritable_accessor :before_start_callbacks, :on_finish_callbacks, :on_start_callback, :instance_reader => false
+ self.before_start_callbacks = []
+ self.on_finish_callbacks = []
+ self.on_start_callback = []
+ end
+
+ module ClassMethods
+ def before_start(*methods)
+ self.before_start_callbacks += methods
+ end
+
+ def on_finish(*methods)
+ self.on_finish_callbacks += methods
+ end
+
+ def on_start(*methods)
+ self.on_start_callback += methods
+ end
+ end
+
+ def before_start(n = 0)
+ if callback = self.class.before_start_callbacks[n]
+ EM.next_tick { send(callback) { before_start(n+1) } }
+ else
+ continue
+ end
+ end
+
+ def on_start
+ self.class.on_start_callback.each do |callback|
+ EM.next_tick { send(callback) }
+ end
+ end
+
+ def on_finish
+ self.class.on_finish_callbacks.each do |callback|
+ EM.next_tick { send(callback) }
+ end
+ end
+
+ end
+end
15 lib/cramp/controller.rb
View
@@ -1,15 +0,0 @@
-require 'cramp'
-require 'rack'
-
-module Cramp
- module Controller
- autoload :Action, "cramp/controller/action"
- autoload :Websocket, "cramp/controller/websocket"
- autoload :Body, "cramp/controller/body"
- autoload :PeriodicTimer, "cramp/controller/periodic_timer"
- autoload :KeepConnectionAlive, "cramp/controller/keep_connection_alive"
- autoload :Abstract, "cramp/controller/abstract"
- autoload :Callbacks, "cramp/controller/callbacks"
- autoload :TestCase, "cramp/controller/test_case"
- end
-end
71 lib/cramp/controller/abstract.rb
View
@@ -1,71 +0,0 @@
-require 'active_support/core_ext/hash/keys'
-
-module Cramp
- module Controller
- class Abstract
-
- include Callbacks
-
- ASYNC_RESPONSE = [-1, {}, []].freeze
-
- class << self
- def call(env)
- controller = new(env).process
- end
- end
-
- def initialize(env)
- @env = env
- end
-
- def process
- EM.next_tick { before_start }
- ASYNC_RESPONSE
- end
-
- def continue
- init_async_body
-
- status, headers = respond_with
- send_initial_response(status, headers, @body)
-
- EM.next_tick { start } if respond_to?(:start)
- EM.next_tick { on_start }
- end
-
- def respond_with
- [200, {'Content-Type' => 'text/html'}]
- end
-
- def init_async_body
- @body = Body.new
-
- if self.class.on_finish_callbacks.any?
- @body.callback { on_finish }
- @body.errback { on_finish }
- end
- end
-
- def finish
- @body.succeed
- end
-
- def send_initial_response(response_status, response_headers, response_body)
- EM.next_tick { @env['async.callback'].call [response_status, response_headers, response_body] }
- end
-
- def halt(status, headers = {}, halt_body = '')
- send_initial_response(status, headers, halt_body)
- end
-
- def request
- @request ||= Rack::Request.new(@env)
- end
-
- def params
- @params ||= request.params.update(@env['usher.params']).symbolize_keys
- end
-
- end
- end
-end
14 lib/cramp/controller/action.rb
View
@@ -1,14 +0,0 @@
-module Cramp
- module Controller
- class Action < Abstract
-
- include PeriodicTimer
- include KeepConnectionAlive
-
- def render(body)
- @body.call(body)
- end
-
- end
- end
-end
50 lib/cramp/controller/body.rb
View
@@ -1,50 +0,0 @@
-# Copyright 2008 James Tucker <raggi@rubyforge.org>.
-
-module Cramp
- module Controller
- class Body
- include EventMachine::Deferrable
-
- def initialize
- @queue = []
-
- # Make sure to flush out the queue before closing the connection
- callback { flush }
- end
-
- def call(body)
- @queue << body
- schedule_dequeue
- end
-
- def each &blk
- @body_callback = blk
- schedule_dequeue
- end
-
- def closed?
- @deferred_status != :unknown
- end
-
- def flush
- return unless @body_callback
-
- until @queue.empty?
- Array(@queue.shift).each {|chunk| @body_callback.call(chunk) }
- end
- end
-
- def schedule_dequeue
- return unless @body_callback
-
- EventMachine.next_tick do
- next unless body = @queue.shift
-
- Array(body).each {|chunk| @body_callback.call(chunk) }
- schedule_dequeue unless @queue.empty?
- end
- end
-
- end
- end
-end
50 lib/cramp/controller/callbacks.rb
View
@@ -1,50 +0,0 @@
-module Cramp
- module Controller
- module Callbacks
-
- extend ActiveSupport::Concern
-
- included do
- class_inheritable_accessor :before_start_callbacks, :on_finish_callbacks, :on_start_callback, :instance_reader => false
- self.before_start_callbacks = []
- self.on_finish_callbacks = []
- self.on_start_callback = []
- end
-
- module ClassMethods
- def before_start(*methods)
- self.before_start_callbacks += methods
- end
-
- def on_finish(*methods)
- self.on_finish_callbacks += methods
- end
-
- def on_start(*methods)
- self.on_start_callback += methods
- end
- end
-
- def before_start(n = 0)
- if callback = self.class.before_start_callbacks[n]
- EM.next_tick { send(callback) { before_start(n+1) } }
- else
- continue
- end
- end
-
- def on_start
- self.class.on_start_callback.each do |callback|
- EM.next_tick { send(callback) }
- end
- end
-
- def on_finish
- self.class.on_finish_callbacks.each do |callback|
- EM.next_tick { send(callback) }
- end
- end
-
- end
- end
-end
21 lib/cramp/controller/keep_connection_alive.rb
View
@@ -1,21 +0,0 @@
-module Cramp
- module Controller
- module KeepConnectionAlive
-
- extend ActiveSupport::Concern
- include PeriodicTimer
-
- module ClassMethods
- def keep_connection_alive(options = {})
- options = { :every => 15 }.merge(options)
- periodic_timer :keep_connection_alive, options
- end
- end
-
- def keep_connection_alive
- render " "
- end
-
- end
- end
-end
51 lib/cramp/controller/periodic_timer.rb
View
@@ -1,51 +0,0 @@
-module Cramp
- module Controller
- module PeriodicTimer
-
- extend ActiveSupport::Concern
-
- included do
- class_inheritable_accessor :periodic_timers, :instance_reader => false
- self.periodic_timers ||= []
- end
-
- module ClassMethods
- def periodic_timer(method, options = {})
- self.periodic_timers << [method, options]
- end
- end
-
- def initialize(*)
- super
- @timers = []
- end
-
- def continue
- super
- EM.next_tick { start_periodic_timers }
- end
-
- def init_async_body
- super
-
- if self.class.periodic_timers.any?
- @body.callback { stop_periodic_timers }
- @body.errback { stop_periodic_timers }
- end
- end
-
- private
-
- def start_periodic_timers
- self.class.periodic_timers.each do |method, options|
- @timers << EventMachine::PeriodicTimer.new(options[:every] || 1) { send(method) }
- end
- end
-
- def stop_periodic_timers
- @timers.each {|t| t.cancel }
- end
-
- end
- end
-end
13 lib/cramp/controller/rendering.rb
View
@@ -1,13 +0,0 @@
-module Cramp
- module Controller
- module Rendering
-
- extend ActiveSupport::Concern
-
- def render(body)
- @body.call(body)
- end
-
- end
- end
-end
57 lib/cramp/controller/test_case.rb
View
@@ -1,57 +0,0 @@
-require 'active_support'
-require 'active_support/test_case'
-
-module Cramp
- module Controller
- class TestCase < ::ActiveSupport::TestCase
-
- setup :create_request
-
- def create_request
- @request = Rack::MockRequest.new(app)
- end
-
- def get(path, options = {}, headers = {}, &block)
- callback = options.delete(:callback) || block
- headers = headers.merge('async.callback' => callback)
-
- EM.run { @request.get(path, headers) }
- end
-
- def get_body(path, options = {}, headers = {}, &block)
- callback = options.delete(:callback) || block
- response_callback = proc {|response| response[-1].each {|chunk| callback.call(chunk) } }
- headers = headers.merge('async.callback' => response_callback)
-
- EM.run { @request.get(path, headers) }
- end
-
- def get_body_chunks(path, options = {}, headers = {}, &block)
- callback = options.delete(:callback) || block
- count = options.delete(:count) || 1
-
- stopping = false
- chunks = []
-
- get_body(path, options, headers) do |body_chunk|
- chunks << body_chunk unless stopping
-
- if chunks.count >= count
- stopping = true
- callback.call(chunks) if callback
- EM.next_tick { EM.stop }
- end
- end
- end
-
- def app
- raise "Please define a method called 'app' returning an async Rack Application"
- end
-
- def stop
- EM.stop
- end
- end
-
- end
-end
63 lib/cramp/controller/websocket.rb
View
@@ -1,63 +0,0 @@
-module Cramp
- module Controller
- module WebsocketExtension
- WEBSOCKET_RECEIVE_CALLBACK = 'websocket.receive_callback'.freeze
-
- def websocket?
- @env['HTTP_CONNECTION'] == 'Upgrade' && @env['HTTP_UPGRADE'] == 'WebSocket'
- end
-
- def websocket_upgrade_data
- location = "ws://#{@env['HTTP_HOST']}#{@env['REQUEST_PATH']}"
-
- upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
- upgrade << "Upgrade: WebSocket\r\n"
- upgrade << "Connection: Upgrade\r\n"
- upgrade << "WebSocket-Origin: #{@env['HTTP_ORIGIN']}\r\n"
- upgrade << "WebSocket-Location: #{location}\r\n\r\n"
-
- upgrade
- end
- end
-
- class Websocket < Abstract
- include PeriodicTimer
-
- # TODO : Websockets shouldn't need this in an ideal world
- include KeepConnectionAlive
-
- class_inheritable_accessor :on_data_callbacks, :instance_reader => false
- self.on_data_callbacks = []
-
- class << self
- def backend=(backend)
- raise "Websocket backend #{backend} is unknown" unless [:thin, :rainbows].include?(backend.to_sym)
- require "cramp/controller/websocket/#{backend}_backend.rb"
- end
-
- def on_data(*methods)
- self.on_data_callbacks += methods
- end
- end
-
- def process
- @env['websocket.receive_callback'] = method(:_on_data_receive)
- super
- end
-
- def render(body)
- @body.call("\x00#{body}\xff")
- end
-
- def _on_data_receive(data)
- data = data.split(/\000([^\377]*)\377/).select{|d| !d.empty? }.collect{|d| d.gsub(/^\x00|\xff$/, '') }
- self.class.on_data_callbacks.each do |callback|
- data.each do |message|
- EM.next_tick { send(callback, message) }
- end
- end
- end
-
- end
- end
-end
19 lib/cramp/keep_connection_alive.rb
View
@@ -0,0 +1,19 @@
+module Cramp
+ module KeepConnectionAlive
+
+ extend ActiveSupport::Concern
+ include PeriodicTimer
+
+ module ClassMethods
+ def keep_connection_alive(options = {})
+ options = { :every => 15 }.merge(options)
+ periodic_timer :keep_connection_alive, options
+ end
+ end
+
+ def keep_connection_alive
+ render " "
+ end
+
+ end
+end
49 lib/cramp/periodic_timer.rb
View
@@ -0,0 +1,49 @@
+module Cramp
+ module PeriodicTimer
+
+ extend ActiveSupport::Concern
+
+ included do
+ class_inheritable_accessor :periodic_timers, :instance_reader => false
+ self.periodic_timers ||= []
+ end
+
+ module ClassMethods
+ def periodic_timer(method, options = {})
+ self.periodic_timers << [method, options]
+ end
+ end
+
+ def initialize(*)
+ super
+ @timers = []
+ end
+
+ def continue
+ super
+ EM.next_tick { start_periodic_timers }
+ end
+
+ def init_async_body
+ super
+
+ if self.class.periodic_timers.any?
+ @body.callback { stop_periodic_timers }
+ @body.errback { stop_periodic_timers }
+ end
+ end
+
+ private
+
+ def start_periodic_timers
+ self.class.periodic_timers.each do |method, options|
+ @timers << EventMachine::PeriodicTimer.new(options[:every] || 1) { send(method) }
+ end
+ end
+
+ def stop_periodic_timers
+ @timers.each {|t| t.cancel }
+ end
+
+ end
+end
11 lib/cramp/rendering.rb
View
@@ -0,0 +1,11 @@
+module Cramp
+ module Rendering
+
+ extend ActiveSupport::Concern
+
+ def render(body)
+ @body.call(body)
+ end
+
+ end
+end
54 lib/cramp/test_case.rb
View
@@ -0,0 +1,54 @@
+require 'active_support'
+require 'active_support/test_case'
+
+module Cramp
+ class TestCase < ::ActiveSupport::TestCase
+
+ setup :create_request
+
+ def create_request
+ @request = Rack::MockRequest.new(app)
+ end
+
+ def get(path, options = {}, headers = {}, &block)
+ callback = options.delete(:callback) || block
+ headers = headers.merge('async.callback' => callback)
+
+ EM.run { @request.get(path, headers) }
+ end
+
+ def get_body(path, options = {}, headers = {}, &block)
+ callback = options.delete(:callback) || block
+ response_callback = proc {|response| response[-1].each {|chunk| callback.call(chunk) } }
+ headers = headers.merge('async.callback' => response_callback)
+
+ EM.run { @request.get(path, headers) }
+ end
+
+ def get_body_chunks(path, options = {}, headers = {}, &block)
+ callback = options.delete(:callback) || block
+ count = options.delete(:count) || 1
+
+ stopping = false
+ chunks = []
+
+ get_body(path, options, headers) do |body_chunk|
+ chunks << body_chunk unless stopping
+
+ if chunks.count >= count
+ stopping = true
+ callback.call(chunks) if callback
+ EM.next_tick { EM.stop }
+ end
+ end
+ end
+
+ def app
+ raise "Please define a method called 'app' returning an async Rack Application"
+ end
+
+ def stop
+ EM.stop
+ end
+ end
+end
61 lib/cramp/websocket.rb
View
@@ -0,0 +1,61 @@
+module Cramp
+ module WebsocketExtension
+ WEBSOCKET_RECEIVE_CALLBACK = 'websocket.receive_callback'.freeze
+
+ def websocket?
+ @env['HTTP_CONNECTION'] == 'Upgrade' && @env['HTTP_UPGRADE'] == 'WebSocket'
+ end
+
+ def websocket_upgrade_data
+ location = "ws://#{@env['HTTP_HOST']}#{@env['REQUEST_PATH']}"
+
+ upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
+ upgrade << "Upgrade: WebSocket\r\n"
+ upgrade << "Connection: Upgrade\r\n"
+ upgrade << "WebSocket-Origin: #{@env['HTTP_ORIGIN']}\r\n"
+ upgrade << "WebSocket-Location: #{location}\r\n\r\n"
+
+ upgrade
+ end
+ end
+
+ class Websocket < Abstract
+ include PeriodicTimer
+
+ # TODO : Websockets shouldn't need this in an ideal world
+ include KeepConnectionAlive
+
+ class_inheritable_accessor :on_data_callbacks, :instance_reader => false
+ self.on_data_callbacks = []
+
+ class << self
+ def backend=(backend)
+ raise "Websocket backend #{backend} is unknown" unless [:thin, :rainbows].include?(backend.to_sym)
+ require "cramp/websocket/#{backend}_backend.rb"
+ end
+
+ def on_data(*methods)
+ self.on_data_callbacks += methods
+ end
+ end
+
+ def process
+ @env['websocket.receive_callback'] = method(:_on_data_receive)
+ super
+ end
+
+ def render(body)
+ @body.call("\x00#{body}\xff")
+ end
+
+ def _on_data_receive(data)
+ data = data.split(/\000([^\377]*)\377/).select{|d| !d.empty? }.collect{|d| d.gsub(/^\x00|\xff$/, '') }
+ self.class.on_data_callbacks.each do |callback|
+ data.each do |message|
+ EM.next_tick { send(callback, message) }
+ end
+ end
+ end
+
+ end
+end
2  lib/cramp/controller/websocket/rainbows_backend.rb → lib/cramp/websocket/rainbows_backend.rb
View
@@ -1,7 +1,7 @@
require 'rainbows'
class Rainbows::EventMachine::Client
- include Cramp::Controller::WebsocketExtension
+ include Cramp::WebsocketExtension
def websocket_handshake!
@state = :websocket
2  lib/cramp/controller/websocket/thin_backend.rb → lib/cramp/websocket/thin_backend.rb
View
@@ -30,7 +30,7 @@ def receive_data(data)
end
class Thin::Request
- include Cramp::Controller::WebsocketExtension
+ include Cramp::WebsocketExtension
end
class Thin::Response
12 test/controller/base_test.rb
View
@@ -1,8 +1,8 @@
require 'test_helper'
-class BaseTest < Cramp::Controller::TestCase
+class BaseTest < Cramp::TestCase
- class WelcomeController < Cramp::Controller::Action
+ class WelcomeController < Cramp::Action
def start
render "Hello World"
finish
@@ -17,7 +17,7 @@ def test_headers
get '/' do |status, headers, body|
assert_equal 200, status
assert_equal "text/html", headers["Content-Type"]
- assert_kind_of Cramp::Controller::Body, body
+ assert_kind_of Cramp::Body, body
stop
end
@@ -32,9 +32,9 @@ def test_body
end
end
-class CustomHeadersTest < Cramp::Controller::TestCase
+class CustomHeadersTest < Cramp::TestCase
- class CustomHeadersController < Cramp::Controller::Action
+ class CustomHeadersController < Cramp::Action
def respond_with
[201, {'Content-Type' => 'application/json'}]
end
@@ -53,7 +53,7 @@ def test_headers
get '/' do |status, headers, body|
assert_equal 201, status
assert_equal "application/json", headers["Content-Type"]
- assert_kind_of Cramp::Controller::Body, body
+ assert_kind_of Cramp::Body, body
stop
end
4 test/controller/callback_test.rb
View
@@ -1,8 +1,8 @@
require 'test_helper'
-class CallbackTest < Cramp::Controller::TestCase
+class CallbackTest < Cramp::TestCase
- class CallbackController < Cramp::Controller::Action
+ class CallbackController < Cramp::Action
cattr_accessor :logs
self.logs = []
4 test/controller/keep_alive_test.rb
View
@@ -1,8 +1,8 @@
require 'test_helper'
-class KeepAliveTest < Cramp::Controller::TestCase
+class KeepAliveTest < Cramp::TestCase
- class KeepAliveController < Cramp::Controller::Action
+ class KeepAliveController < Cramp::Action
keep_connection_alive :every => 0
end
4 test/controller/multiple_rendering_test.rb
View
@@ -1,8 +1,8 @@
require 'test_helper'
-class MultipleRenderingTest < Cramp::Controller::TestCase
+class MultipleRenderingTest < Cramp::TestCase
- class MultipleController < Cramp::Controller::Action
+ class MultipleController < Cramp::Action
def start
render "Camera"
render "Obscura"
6 test/controller/periodic_timer_test.rb
View
@@ -1,8 +1,8 @@
require 'test_helper'
-class PeiodicTimerTest < Cramp::Controller::TestCase
+class PeiodicTimerTest < Cramp::TestCase
- class SendDataController < Cramp::Controller::Action
+ class SendDataController < Cramp::Action
periodic_timer :send_data, :every => 0
def send_data
@@ -10,7 +10,7 @@ def send_data
end
end
- class FinishingTimerController < Cramp::Controller::Action
+ class FinishingTimerController < Cramp::Action
periodic_timer :finish_soon, :every => 0
def finish_soon
4 test/controller/websocket_test.rb
View
@@ -1,8 +1,8 @@
require 'test_helper'
-class WebSocketTest < Cramp::Controller::TestCase
+class WebSocketTest < Cramp::TestCase
- class WebSocketAction < Cramp::Controller::Websocket
+ class WebSocketAction < Cramp::Websocket
cattr_accessor :logs
self.logs = []
2  test/test_helper.rb
View
@@ -4,7 +4,7 @@
Bundler.setup
Bundler.require :default, :test
-require 'cramp/controller'
+require 'cramp'
require 'test/unit'
require 'usher'
Please sign in to comment.
Something went wrong with that request. Please try again.