Rails on Rack

作用:连接web server和web app,处理http requests.

图示:

rack app: A Rack application is a Ruby object that has a call method, which has a single argument, the environment,(corresponding to a HTTP request) and returns an array of 3 elements, status, headers and body(corresponding to a HTTP response, must respond to each method).

handlers: connect Rack to all these web application servers (WEBrick, Mongrel etc.).

adapters: connect Rack to various web frameworks (Sinatra, Rails etc.)

middleware: come between the calling client and the server, process the HTTP request before sending it to the server, and processing the HTTP response before returning it to the client.

安装和使用:

#安装
gem install rack

#创建rack对象,参考如上的说明,相应call方法,传递单个参数,返回status, headers, body, 如下所示
#proc对象
my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
#method对象
def my_method env
  [200, {}, ["method called"]]
end
my_rack_method = method(:my_method)


#在irb中情况使用
#使用proc对象作为Rack app
require 'rack'
Rack::Handler.constants #=>[:FastCGI, :CGI, :WEBrick, :LSWS, :SCGI, :Thin]
my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
my_rack_proc.call({}) #=>[200, {"Content-Type" => "text/plain"}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
Rack::Handler::WEBrick.run my_rack_proc #http://localhost/8080默认进行访问
Rack::Handler::WEBrick.run my_rack_proc, :Port=> 9879 #指定端口

#使用method对象作为Rack app
require 'rack'
def my_method env
  [200, {}, ["method called"]]
end
my_rack_method = method(:my_method)
Rack::Handler::WEBrick.run my_rack_method #http://localhost/8080默认进行访问

使用rackup

#只建立config.ru文件,作用是方便使用rack
#config.ru
Rack::Handler::WEBrick.run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
#执行
rackup config.ru

#建立config.ru和my_app.rb文件
#my_app.rb
class MyApp
  def call env
    [200, {"Content-Type" => "text/html"}, ["Hello Rack"]]
  end
end
#config.ru
require './my_app'  #my_app.rb和config.ru文件在同一个文件中
Rack::Handler::WEBrick.run MyApp.new
#执行
rackup config.ru

使用middleware

#简单使用middleware
#修改如上的config.ru文件
#my_app.rb
class MyApp
  def call env
    [200, {"Content-Type" => "text/html"}, ["Hello Rack"]]
  end
end
#config.ru
require './my_app'  
use Rack::Reloader #使用middleware的方式,这个插件作用是修改my_app.rb中的response中的内容,不用重启服务器
Rack::Handler::WEBrick.run MyApp.new

#创建middleware
#创建myrackmiddleware.rb文件,修改config.ru文件
#my_app.rb
class MyApp
  def call env
    [200, {"Content-Type" => "text/html"}, ["Hello Rack"]]
  end
end
#myrackmiddleware.rb
class MyRackMiddleware
  def initialize(appl)
    @appl = appl
  end
  def call(env)
    status, headers, body = @appl.call(env)
    append_s = "... greetings from RubyLearning!!"
    new_body = ""
    body.each { |string| new_body << " " << string }
    new_body << " " << append_s
    [status, headers, [new_body]]
  end
end
#config.ru
require './my_app'
require './myrackmiddleware'
use Rack::Reloader
use MyRackMiddleware
Rack::Handler::WEBrick.run MyApp.new

middleware成功案例

require "thin"

app = -> (env) do
  slee 3
  [ 200, { "Content-Type" => "text/plain" }, ["Hello World\n"] ]
end

class LoggingMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    before = Time.now.to_i
    status, headers, body = @app.call(env)
    after = Time.now.to_i
    log_message = "App took #{after - before} seconds."

    [status, headers, body << log_message]
  end
end

use LoggingMiddleware
run app

results matching ""

    No results matching ""