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简单实现计算过期时间的方法
Jun 09 Python
Python序列化基础知识(json/pickle)
Oct 19 Python
python机器学习理论与实战(六)支持向量机
Jan 19 Python
python生成器,可迭代对象,迭代器区别和联系
Feb 04 Python
将string类型的数据类型转换为spark rdd时报错的解决方法
Feb 18 Python
django-allauth入门学习和使用详解
Jul 03 Python
python简单实现矩阵的乘,加,转置和逆运算示例
Jul 10 Python
一文读懂Python 枚举
Aug 25 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
Nov 25 Python
matplotlib自定义鼠标光标坐标格式的实现
Jan 08 Python
Python并发编程实例教程之线程的玩法
Jun 20 Python
Python用tkinter实现自定义记事本的方法详解
Mar 31 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数学运算
2011/12/30 PHP
基于empty函数的输出详解
2013/06/17 PHP
利用PHP实现短域名互转
2013/07/05 PHP
PHP技术开发微信公众平台
2015/07/22 PHP
Yii基于数组和对象的Model查询技巧实例详解
2015/12/28 PHP
图文详解PHP环境搭建教程
2016/07/16 PHP
PHP抽象类与接口的区别详解
2019/03/21 PHP
thinkphp5框架实现的自定义扩展类操作示例
2019/05/16 PHP
JQuery中关于jquery.js与jquery.min.js的比较探讨
2013/05/15 Javascript
JavaScript实现大数的运算
2014/11/24 Javascript
jQuery 判断图片是否加载完成方法汇总
2015/08/10 Javascript
React.js入门实例教程之创建hello world 的5种方式
2016/05/11 Javascript
全面理解JavaScript中的闭包
2016/05/12 Javascript
jQuery解析XML 详解及方法总结
2016/09/28 Javascript
nodejs个人博客开发第二步 入口文件
2017/04/12 NodeJs
使用elementUI实现将图片上传到本地的示例
2018/09/04 Javascript
vue计算属性computed、事件、监听器watch的使用讲解
2019/01/21 Javascript
vue中@change兼容问题详解
2019/10/25 Javascript
JS canvas实现画板和签字板功能
2021/02/23 Javascript
[27:39]Ti4 循环赛第二日 LGD vs Fnatic
2014/07/11 DOTA
[03:01]2014DOTA2国际邀请赛 DC:我是核弹粉,为Burning和国土祝福
2014/07/13 DOTA
numpy中loadtxt 的用法详解
2018/08/03 Python
python字符串中匹配数字的正则表达式
2019/07/03 Python
使用python对多个txt文件中的数据进行筛选的方法
2019/07/10 Python
Python模拟登入的N种方式(建议收藏)
2020/05/31 Python
Python连接HDFS实现文件上传下载及Pandas转换文本文件到CSV操作
2020/06/06 Python
Paradigit比利时电脑卖场:购买笔记本、电脑、平板和外围设备
2016/11/28 全球购物
美国购买隐形眼镜网站:Lenses For Less
2020/07/05 全球购物
什么是会话Bean
2015/05/14 面试题
蛋糕店的商业计划书范文
2014/01/27 职场文书
党员公开承诺践诺书
2014/03/25 职场文书
优秀团员主要事迹范文
2015/11/05 职场文书
教师外出学习心得体会
2016/01/18 职场文书
幼儿园教师教学反思
2016/03/02 职场文书
浅谈Python数学建模之固定费用问题
2021/06/23 Python
SpringBoot集成MongoDB实现文件上传的步骤
2022/04/18 MongoDB