Nodejs实现web静态服务器对多媒体文件的支持
前几天,一个同事说他写的web静态服务器不支持音视频的播放,现简单实现一下。
原理:实现http1.1协议的range部分。
其实这一点都不神秘,我们常用的下载工具,如迅雷,下载很快,还支持断点续传,就是利用http协议的range和多线程实现的。假如下载一个1MB的文件,如果开一个线程下载,那么只能从头到尾依次下载这个文件,这样不可能提升速度。通常,下载工具会开很多个线程,这里暂且假设是4个,然后这4个线程同时分别下载这1MB的0~255KB、256-511KB、512~767KB和768~1024KB,很显然,理论上速度提升了4倍。
那么怎么将服务器上的1MB文件分成4份呢?这就是range的强大功能了!
当请求下载文件时,带有
Range: bytes=0-255[,256-511] //这里表示0~255个字节,如果请求多个分段,用逗号隔开
服务器响应请求时发现头部带有Range,那么做出响应:
Content-Range: bytes 0-255/789 //789就是整个文件的大小了
Content-Length: 256
同时status变为,而不是200,并发送这一段数据给客户端,这样客户端接收到的数据就是整个文件的一部分了!
range的请求头还可以是:
- Range: bytes=0- //整个文件
- Range: bytes=-200 //最后200个字节
- Range: bytes=200- //200字节后的所有字节
- Range: bytes=0-0,-1 //第一、最后一个字节
看代码如何实现
//判断是请求头中是否有range部分
if(request.headers.range){
var size = stat.size;//获取文件大小
//暂且写在这里
function getRange(){
var range = request.headers.range; if(range.indexOf(",") != -1){//这里只处理了一个分段的情况
return false;
}
//range大约长这样子:bytes=0-255[,256-511]
var parts = range.replace(/bytes=/, '').split("-");
var partiaStart = parts[0];
var partialEnd = parts[1]; var start = parseInt(partiaStart);//起始位置
//如果是bytes=0-,就是整个文件大小了
var end = partialEnd ? parseInt(partialEnd) : size - 1; if(isNaN(start) || isNaN(end)) return false;
//分段的大小
var chunkSize = end - start + 1; return {'start': start, 'end': end, 'chunkSize': chunkSize};
} var rangeData = getRange();
if(rangeData){
//createReadStream这东西原生支持range,是不是很爽?
var raw = fs.createReadStream(realPath, {'start': rangeData.start, 'end': rangeData.end});
//状态码当然是206了
response.writeHead(206, 'Partial Content', {
'Content-Type' : contentType,
'Content-Range' : 'bytes ' + rangeData.start + '-' + rangeData.end + '/' + size,
'Content-Length' : rangeData.chunkSize
});
raw.pipe(response);
}else{
response.writeHead(416, "not ok!");
response.end();
}
}else{
//状态码200
}
大概就是这样子,其他部分略去。
用html5的audio标签试验下mp3的播放:
<audio src="audio/test.mp3" controls="controls" preload="auto" autoplay="autoplay"></audio>
得到的请求和响应头如下:
下图是MP3文件加载到6MB时的截图,这时音乐已经播放超过一半了,所以可不是加载完成才播放的。
这样web服务器就实现range功能,可以处理多媒体文件了,当然只是非常简单的实现,想了解更多可以查阅W3的网站(前面说的下载、断点续传什么的就不验证了,客户端也搞不明白)
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Nodejs实现web静态服务器对多媒体文件的支持的更多相关文章
- Web静态服务器
Web静态服务器 编程微刊 Web静态服务器-1-显示固定的页面 #coding=utf-8 import socket def handle_client(client_socket): " ...
- Python建立web静态服务器
原文地址:http://www.bugingcode.com/blog/python_html_web_server.html python作为工具,提供了很多好用的命令,比如有时候突然需要建立一个解 ...
- 08.Web服务器-3.Web静态服务器
1.显示固定的页面 from socket import * from multiprocessing import * import os def handleClient(clientSocket ...
- nodejs 搭建本地静态服务器
1. http-server 参看 https://www.npmjs.com/package/http-server 使用http-server搭建本地静态服务器 全局安装http-server n ...
- python高级编程之 web静态服务器
返回固定数据 import socket def request_handler(new_client_socket): """ 响应客户端请求的核心函数 "& ...
- [置顶] java web 动态服务器
写了一个java web 动态服务器,主要通过内部类来实现,动态类使用了外部类,采用了 classforname 实例化,动态类的构造方法不能带参数, 效果都出来了,分享给有需要的 朋友.判断做的不够 ...
- nodejs http静态服务器
使用nodejs写的很简单的静态服务器,没有做cluster处理,没有做缓存处理,不支持访问文件夹,功能只有一个,就是获取到文件后再返回文件内容. var fs = require('fs'); va ...
- 安装nodeJs静态服务器(NodeJs Express MVC 框架)
安装 NodeJs Express MVC 框架 新建项目文件夹 打开cmd 执行以下操作: 一.使用Express框架 1)安装express3 $: npm install -g ex ...
- Web前端页面的浏览器兼容性测试心得(一)搭建测试用本地静态服务器
自从实习以来,我体验了由一个人编程再到多人协作编程的转换.同时也接触了很多新鲜事物,学到了很多东西.工作时,常常需要多个人协同测试一张H5页面(PC.手机.平板等跨设备测试),也会经常把页面给PM或老 ...
随机推荐
- UML中的六大关系
转自:http://www.cnblogs.com/shengtianlong/archive/2010/10/23/1858953.html UML定义的关系主要有六种:依赖.类属.关联.实现.聚合 ...
- JAVA算术运算符、关系运算符和位运算符
算术运算符 1.java的算数运算符包括+(加).-(减).*(乘)./(除).%(取余),在运算过程中出现的隐式转换原则和C语言一样:2. 高位数据向低位数据转化要使用强制转化: 关系运算符 1.j ...
- margin-top相对谁的问题
根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠.意思便是:如果你只想margin相对于父标 ...
- Careercup - Google面试题 - 5735304249999360
2014-05-03 23:18 题目链接 原题: Insert a element in a sorted circular linked list 题目:题意简单明了,向一个有序的循环单向链表中插 ...
- [book]awesome-machine-learning books
https://github.com/josephmisiti/awesome-machine-learning/blob/master/books.md Machine-Learning / Dat ...
- FACL的使用
ACL的使用 ACL即Access Control List 主要的目的是提供传统的owner,group,others的read,write,execute权限之外的具体权限设置,ACL可以针对单一 ...
- 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- asynDBcenter(复习)
asynDBCenter asynDBCenter是GS和DBCenter之间的模块,有了他GS访问数据库就是异步的了,以前是同步的,加入某个操作很耗时那么GS就在那等待这个返回值. .对于std:: ...
- .htaccess文件讲解
.htaccess文件(或者"分布式配置文件")提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作为用户 ...
- T-SQL操作表结构(转)
在网上整理的一牛人资料,收集与此与君共享 用SQL语句添加删除修改字段1.增加字段 ALTER TABLE [yourTableName] ADD [newColumnName] newCo ...