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分割TXT文件成4K的TXT文件
May 23 Python
编写Python脚本把sqlAlchemy对象转换成dict的教程
May 29 Python
浅谈python中列表、字符串、字典的常用操作
Sep 19 Python
python进阶之多线程对同一个全局变量的处理方法
Nov 09 Python
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
Jul 06 Python
Python中使用gflags实例及原理解析
Dec 13 Python
pytorch 数据处理:定义自己的数据集合实例
Dec 31 Python
python如何运行js语句
Sep 09 Python
Python用dilb提取照片上人脸的示例
Oct 26 Python
详解Selenium 元素定位和WebDriver常用方法
Dec 04 Python
pycharm如何设置官方中文(如何汉化)
Dec 29 Python
python迷宫问题深度优先遍历实例
Jun 20 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 Directory 函数的详解
2013/03/07 PHP
php提高网站效率的技巧
2015/09/29 PHP
javascript入门·动态的时钟,显示完整的一些方法,新年倒计时
2007/10/01 Javascript
让FireFox支持innerText的实现代码
2009/12/01 Javascript
setTimeout的延时为0时多个浏览器的区别
2012/05/23 Javascript
javascript学习笔记(五) Array 数组类型介绍
2012/06/19 Javascript
jquery二级导航内容均分的原理及实现
2013/08/13 Javascript
通过JS来判断页面控件是否获取焦点
2014/01/03 Javascript
js二维数组排序的简单示例代码
2014/01/24 Javascript
在HTML中插入JavaScript代码的示例
2015/06/03 Javascript
对JavaScript客户端应用编程的一些建议
2015/06/24 Javascript
JS+CSS实现另类带提示效果的竖向导航菜单
2015/10/15 Javascript
bootstrapfileinput实现文件自动上传
2016/11/08 Javascript
Bootstrap 3 进度条的实现
2017/02/22 Javascript
详解react-router 4.0 下服务器如何配合BrowserRouter
2017/12/29 Javascript
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
swiper自定义分页器的样式
2020/09/14 Javascript
NumPy 如何生成多维数组的方法
2018/02/05 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
Python 多个图同时在不同窗口显示的实现方法
2019/07/07 Python
如何基于python实现脚本加密
2019/12/28 Python
Pytorch 的损失函数Loss function使用详解
2020/01/02 Python
详解pycharm连接不上mysql数据库的解决办法
2020/01/10 Python
纯CSS3实现地球自转实现代码(图文教程附送源码)
2012/12/26 HTML / CSS
HTML5新增的8类INPUT输入类型介绍
2015/07/06 HTML / CSS
女大学生个人求职信
2013/12/09 职场文书
校园达人秀策划书
2014/01/12 职场文书
九年级英语教学反思
2014/01/31 职场文书
面试后感谢信
2014/02/01 职场文书
加多宝凉茶广告词
2014/03/18 职场文书
小学学校门卫岗位职责
2014/08/03 职场文书
教学改革问题查摆整改措施
2014/09/27 职场文书
2015建军节87周年演讲稿
2015/03/19 职场文书
2015年大学生暑期实习报告
2015/07/13 职场文书
Redis 哨兵集群的实现
2021/06/18 Redis
Win11如何查看显卡型号 Win11查看显卡型号的方法
2022/08/14 数码科技