Ruby使用eventmachine为HTTP服务器添加文件下载功能


Posted in Python onApril 20, 2016

思路:
使用ruby eventmachine和em-http-server gem,完成一个简单的提供文件下载功能的HttpServer;
使用了EM的FileStreamer来异步发送文件,发送文件时先组装了header,然后调用FileStreamer。

代码:

require 'rubygems'
require 'eventmachine'
require 'em-http-server'
 
class HTTPHandler < EM::HttpServer::Server
 attr_accessor :filename, :filesize, :path
 
 def process_http_request
  #send file async
  if @http_request_method.to_s =~ /GET/ && @http_request_uri.to_s.end_with?(filename)
   send_data "HTTP/1.1 200 OK\n"
   send_data "Server: XiaoMi\n"
   send_data "Connection: Keep-Alive\n"
   send_data "Keep-Alive: timeout=15\n"
   send_data "Content-Type: application/octet-stream\n"
   send_data "Content-Disposition: filename='#{filename}'\n"
   send_data "Content-Length: #{filesize}\n"
   send_data "\n"
 
   streamer = EventMachine::FileStreamer.new(self, path)
   streamer.callback {
    # file was sent successfully
    close_connection_after_writing
   }
  else
   response = EM::DelegatedHttpResponse.new(self)
   response.status = 200
   response.content_type 'text/html'
   response.content = "Package HttpServer<br>usage: wget http://host:port/#{filename}"
   response.send_response
  end
 end
 
end
 
EM::run do
 path = '/tmp/aaa.tar.gz'
 EM::start_server("0.0.0.0", 8080, HTTPHandler) do |conn|
  conn.filename = File.basename(path)
  conn.filesize = File.size(path)
  conn.path = path
 end
end

PS:关于eventmachine安装错误的问题
在windows上安装 eventmachine 总是报错:
 

Building native extensions. This could take a while...
ERROR: Error installing eventmachine:
    ERROR: Failed to build gem native extension.

或者另外一种:

ERROR: Error installing ruby-debug:
      The 'linecache' native gem requires installed build tools.
   
  Please update your PATH to include build tools or download the DevKit
  from 'http://rubyinstaller.org/downloads' and follow the instructions
  at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'

后来经过了漫长的Google,找到了2个solution:

1.用更低版本的eventmachine
 
这个提示一直不断,下面还有一大难错误,都是C的编译错误后来网上找了两个方法
(1)

gem install eventmachine-win32

这个貌似安装的是较低版本的
(2)gem install

eventmachine --pre

这个貌似安装的是 beta 1.0.0的。

 
2.升级devkit
 
看了一下,上面没有提具体的解决方案,但是给出了问题产生的两个可能原因:
(1)没有C编译环境
(2)路径当中有空格
看看上面的错误日志,发现可能就是编译环境的问题。于是找了一下。
我的ruby是用one-click installer装的,版本是1.8.6-p398。
在rubyinstaller的addon页面,找到了DevKit。
看了一下DevKit的说明:

//Sometimes you just want RubyGems to build that cool native,
//C-based extension without squawking.
//Who's your buddy? DevKit!
看来这就是我需要的。
 
出错的原因是安装eventmachine的时候,需要build tools,但系统中没有。出错信息中同时也给出了解决的法案:
(1) 到 http://rubyinstaller.org/downloads/ 去下载dev kit ? DevKit-tdm-32-4.5.1-20101214-1400-sfx.exe
(2)按照 http://github.com/oneclick/rubyinstaller/wiki/Development-Kit/ 安装dev kit
主要安装步骤如下:
如果原来系统中已经安装了旧版的dev kit, 则删除它
下载上面提到的dev kit
解压下载下来的文件到指定的目录,如c:/devkit。(注意:目录不能有空格)
运行ruby dk.rb,然后按照提示分别运行ruby dk.rb init 和 ruby dk.rb install来增强ruby
可以运行

gem install rdiscount ?platform=ruby

来测试是否成功。
按照安装步骤,完成了DevKit的安装,非常简单。

然后,再次安装eventmachine:

gem install eventmachine
Python 相关文章推荐
Python记录详细调用堆栈日志的方法
May 05 Python
python文件特定行插入和替换实例详解
Jul 12 Python
python编程羊车门问题代码示例
Oct 25 Python
Python3.6安装及引入Requests库的实现方法
Jan 24 Python
数组保存为txt, npy, csv 文件, 数组遍历enumerate的方法
Jul 09 Python
Django实现一对多表模型的跨表查询方法
Dec 18 Python
Python WEB应用部署的实现方法
Jan 02 Python
scrapy-redis的安装部署步骤讲解
Feb 27 Python
Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解
Feb 28 Python
Python自定义函数计算给定日期是该年第几天的方法示例
May 30 Python
Django通过dwebsocket实现websocket的例子
Nov 15 Python
Keras 数据增强ImageDataGenerator多输入多输出实例
Jul 03 Python
Python实现HTTP协议下的文件下载方法总结
Apr 20 #Python
详解Python命令行解析工具Argparse
Apr 20 #Python
利用Python如何生成随机密码
Apr 20 #Python
Python自动化部署工具Fabric的简单上手指南
Apr 19 #Python
python实现简单socket通信的方法
Apr 19 #Python
python实现域名系统(DNS)正向查询的方法
Apr 19 #Python
python安装与使用redis的方法
Apr 19 #Python
You might like
php顺序查找和二分查找示例
2014/03/27 PHP
Joomla使用Apache重写模式的方法
2016/05/04 PHP
php版微信js-sdk支付接口类用法示例
2016/10/12 PHP
php将print_r处理后的数据还原为原始数组的解决方法
2016/11/02 PHP
Javascript客户端脚本的设计和应用
2006/08/21 Javascript
javascript新手语法小结
2008/06/15 Javascript
javascript 内存回收机制理解
2011/01/17 Javascript
js判断变量是否未定义的代码
2020/03/28 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
2013/05/14 Javascript
node.js中的fs.readlink方法使用说明
2014/12/17 Javascript
如何编写高质量JS代码(续)
2015/02/25 Javascript
JavaScript实现广告弹窗效果
2016/08/09 Javascript
js友好的时间返回函数
2016/08/24 Javascript
bootstrap输入框组使用方法
2017/02/07 Javascript
Node.js 8 中的 util.promisify的详解
2017/06/12 Javascript
NodeJs实现定时任务的示例代码
2017/12/05 NodeJs
详解如何实现一个简单的 vuex
2018/02/10 Javascript
js代码规范之Eslint安装与配置详解
2018/09/08 Javascript
jQuery实现获取当前鼠标位置并输出功能示例
2019/01/05 jQuery
小白教程|一小时上手最流行的前端框架vue(推荐)
2019/04/10 Javascript
vue实现移动端返回顶部
2020/10/12 Javascript
python self,cls,decorator的理解
2009/07/13 Python
python 生成器生成杨辉三角的方法(必看)
2017/04/10 Python
Python语言的变量认识及操作方法
2018/02/11 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
2018/04/08 Python
python3写的简单本地文件上传服务器实例
2018/06/04 Python
Sanic框架应用部署方法详解
2018/07/18 Python
JavaScript中的模拟事件和自定义事件实例分析
2018/07/27 Python
django项目中使用手机号登录的实例代码
2019/08/15 Python
Python用dilb提取照片上人脸的示例
2020/10/26 Python
Perfume’s Club法国站:购买香水和化妆品
2019/05/02 全球购物
Richards网上商店:当代时尚,遍布巴西
2019/11/03 全球购物
C#如何进行LDAP用户校验
2012/11/21 面试题
教师职称自我鉴定
2014/02/12 职场文书
金融与证券专业求职信
2014/06/22 职场文书
写好求职信的技巧解密
2019/05/14 职场文书