0 前言

如有错误欢迎指出,如需转载,请注明原文链接。

1 Rack是什么

一句话介绍,Rack是一个Web接口,定义了一系列的标准,具体实现的工作是交给服务器(puma, thin等)做的。

如果你了解J2EE,Rails开发和J2EE开发对比,大概是这么个关系

  • Rack - Servlet
  • puma, thin等 - tomcat, weblogic等
  • Rails - J2EE中常用的开发框架,如spring-mvc, structs2, mybatis等

2 Rack程序长什么样子

Rack的标准非常简单:

一个Rack程序是一个对象,这个对象要求能响应call方法,并且接受一个Hash参数,并返回一个数组,这个数组里面分别是:

  • HTTP响应码 [Integer]
  • HTTP响应头 [Hash]
  • HTTP响应体 [需要能响应each方法]

一个简单的Rack程序,我们把它保存为rack_app.rb

require 'rack'

app = Proc.new do |env|
    [
      200,
      { 'Content-Type' => 'text/html; charset=utf-8' },
      [
        '<h1>一个简单的Rack程序</h1>',
        '<p>其它内容...</p>'
      ]
    ]
end

详细标准请阅读Rack的说明文档

3 运行Rack程序

我们将下面的代码保存到config.ru

require_relative 'rack_app'

Rack::Handler::WEBrick.run(app, Port: 9000)

这里,WEBrick是一个Rack自带的实现,我们可以用它来运行我们的Rack应用程序。另外,在运行之前,我们需要确保我们已经安装Rack的gem包。如果你不确定,可以运行gem install rack来安装。

现在,我们运行ruby config.ru,就可以看到下面的输出

[2016-11-02 19:06:46] INFO  WEBrick 1.3.1
[2016-11-02 19:06:46] INFO  ruby 2.3.1 (2016-04-26) [x86_64-linux]
[2016-11-02 19:06:46] INFO  WEBrick::HTTPServer#start: pid=28184 port=9000

在浏览器里面访问localhost:9000即可看到页面。

当然,你也可以用任何其它基于Rack的服务器来运行我们的程序。比如puma,首先运行gem install puma来安装puma的gem包,然后修改我们的config.ru:

require_relative 'rack_app'
require 'puma'
require 'rack/handler/puma'

Rack::Handler::Puma.run(app, Port: 9000)

运行ruby config.ru,就可以看到下面的输出

Puma starting in single mode...
* Version 3.6.0 (ruby 2.3.1-p112), codename: Sleepy Sunday Serenity
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:9000
Use Ctrl-C to stop

总之,Rack提供了一个统一的接口,基于Rack开发的任何应用(或者说是Web框架)都可以在实现了Rack接口的服务器上运行。

4 Rack中间件

参考原文:Understanding Rack Middleware

Rack服务器在运行应用之前,可以先经过若干个中间件。在请求到达我们的应用前,中间件预先对他们做一些处理。Rack中间件是一个类,它的构造方法接受一个能响应call方法的对象,它必须有一个call实例方法。

我们写一个简单的中间件,保存为my_middleware.rb。

这个中间件的功能是:

  1. 如果PATH_INFO中有'please_return_404'字符串,则返回一个404响应,否则交给下一个中间件处理(最后一个中间件就是我们的Rack应用程序)
  2. 在最终的响应体后面加一行'Hi, I am middleware.'
class MyMiddleware
  # 实例化中间件的时,会把下一个中间件传进来
  # 最后一个"中间件"就是我们的应用程序
  def initialize(app)
    @app = app
  end

  def call(env)
    if env['PATH_INFO'].include?('please_return_404')
      [ 404, { 'Content-Type' => 'text/plain' }, ['Error, 404!'] ]
    else
      response = @app.call(env)
      response[2] << 'Hi, I am middleware.'
      response
    end
  end
end

要使用这个中间件来运行我们的应用,修改我们的config.ru:

require_relative 'rack_app'
require_relative 'my_middleware'

app2 = Rack::Builder.app do
  use MyMiddleware
  # use AnotherMiddleware
  # 你还可以使用更多的中间件
  # ...
  run app
end
Rack::Handler::WEBrick.run(app2, Port: 9000)

最后,我们运行ruby config.ru即可启动我们的程序。

此时:

  1. 访问 localhost:9000/hi/hello 会返回我们的页面,而且下面多了一行字,'Hi, I am middleware'.
  2. 访问 localhost:9000/hello/please_return_404 则会返回404错误页面。

最新文章

  1. jrebel注意事项
  2. Windows Phone 8 下载文件进度
  3. Java bean validation 规范与参考实现
  4. Ubuntu格式化分区时的一个小错误
  5. Mongo:将查询结果转换为自定义类
  6. jquery 单行滚动、批量多行滚动、文字图片翻屏滚动效果代码
  7. git分享:Git_DataPro
  8. Android之ksoap2-android详解与调用天气预报Webservice完整实例
  9. R语言机器学习之caret包运用
  10. Sublime Text保存文件时自动去掉行末空格
  11. 3)C语言数组(C自考学习)
  12. MangoDb的安装及使用
  13. python-之-深浅拷贝一
  14. Jquery.Datatable 控件后端分页实例 (后台使用ashx、aspx-webmethod)
  15. bzoj 4591 超能粒子炮&#183;改 - Lucas
  16. VSTO:使用C#开发Excel、Word【7】
  17. python-day48--mysql之视图、触发器、事务、存储过程、函数
  18. 带你快速进入.net core的世界(转)
  19. IPMI相关漏洞利用及WEB端默认口令登录漏洞
  20. HTML 5之meta标签viewport应用

热门文章

  1. dom4j创建xml
  2. Java从零开始学四十二(DOM解析XML)
  3. android 定制自己的日志工具
  4. 使用docker搭建lnmp环境
  5. zobrist hashing
  6. Linux Shell 02 流程控制语句
  7. 斐波那契数列 递归 尾递归 递推 C++实现
  8. nyoj 203 三国志 dijkstra+01背包
  9. XSLT
  10. mysql中count(),group by使用