位置: IT常识 - 正文

Node 下 Http Streaming 的跨浏览器实现

编辑:rootadmin
Node 下 Http Streaming 的跨浏览器实现 - CNodeNode 下 Http Streaming 的跨浏览器实现最近考虑把整个前端架构使用http streaming方式实现 对这 Node 下 Http Streaming 的跨浏览器实现

推荐整理分享Node 下 Http Streaming 的跨浏览器实现,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

最近考虑把整个前端架构使用http streaming方式实现

对这方面做了一下调研,并在在node上实现了一个简单的原型

顺带提一下,

楼下pengchun同学所提到的node chat使用的是longpoll的模型

和httpstreaming同属与http comet的解决方案.

不过在具体http连接的处理上有所不同

long poll在数据通道每次接收到一个数据包后即关闭连接,并立即重新打开数据通道

http streaming的数据通道始终处于打开状态.

具体的介绍可以看这里http://en.wikipedia.org/wiki/Comet_(programming)#Streaming

一些细节:

由于ie下在xhr readystate=3时无法取得responseText,

因此在ie下改为通过使用htmlfile控件调用iframe实现

另在输出正式数据前需现输出1k的噪音数据

以解决浏览器的阻塞问题

原型功能设计如下

具体代码如下

Node 下 Http Streaming 的跨浏览器实现

pipe.js: 主服务程序

var http = require('http'),fs = require('fs'),url = require('url'),page = null;// static files read & watchvar readFile = function(files) {var buffers = {};// sync readvar fread = function(file, cb){fs.readFile(file, 'binary', function(err, data){if (err) {throw err;}buffers[file] = new Buffer(data, 'binary');console.log('load', file)});}// watch changesvar watch = function watch(file) {fs.watchFile(file, {persistent: true, interval: 100}, function (curr, prev) {if (curr.mtime.getTime() != prev.mtime.getTime()) {fread(file);}});}// run all filesfor (var i = 0; i < files.length; i++) {watch(files[i]);fread(files[i]);}return buffers;}// http queryvar httpQuery = function(u, cb){console.log('http begin');// parse urlvar uinfo = url.parse(u);// create clientvar client = http.createClient(uinfo.port ? uinfo.port : 80, uinfo.hostname, false);var uri = uinfo.pathname + (uinfo.search ? uinfo.search : '');var req = client.request('GET', uri, {'host': uinfo.hostname});// send requestreq.end();console.log('http request sent');var len = 4096;var pointer = 0;var extendFactor = 2;// response startreq.on('response', function (res) {if (res.headers['content-length']) {len = parseInt(res.headers['content-length']);}// body initvar body = new Buffer(len);// chunk recivedres.on('data', function(chunk){// extendsif (pointer + chunk.length > len) {len *= extendFactor;body = body.copy(new Buffer(len), 0, 0);console.log('proxy extend to', len);}// copy chunk to bufchunk.copy(body, pointer, 0);// move pointerpointer += chunk.length;})// response endres.on('end', function() {cb(body.length > pointer ? body.slice(0, pointer) : body);console.log('proxy end', pointer);});})}// main servervar server = http.createServer(function (req, res){// main pageif (req.url == '/') {res.writeHeader(200);res.end(page["pipe.html"]);// time serve} else if (req.url == '/time') {res.writeHeader(200);res.end(new Date().toString());// iframe recv} else if (req.url.match(/^\/iframe\//)) {var clientid = parseInt(req.url.substr(8));pipeClient.add(clientid, res, pipeClient.iframe);console.log('iframe connect', clientid);// ajax recv} else if (req.url.match(/^\/ajax\//)) {var clientid = parseInt(req.url.substr(6));pipeClient.add(clientid, res, pipeClient.ajax);console.log('ajax connect', clientid);// request listen} else if (req.url.match(/^\/req\//)) {res.writeHeader(200,{'Cache-Control': 'no-cache, must-revalidate'});res.end();// url parsevar clientid = parseInt(req.url.substr(5, 13));// get pagehttpQuery("http://localhost:8000/time", function (data){console.log(data.toString());pipeClient.write(clientid, data);console.log("write", clientid, data.length);});// error pages} else {res.writeHeader(404, {"Content-Type" : "text/html"});res.end();}});var pipeClient = {timeout : 30000,client : {},prefix : "",iframe : 'iframe',ajax : 'ajax',noise : null,noiseSize : 1024,page : null,init : function(){this.noise = new Buffer(1024);for (var i = 0; i < this.noiseSize; i++) {this.noise[i] = 32;}this.page = readFile(['iframe.html']);},add : function(id, res, type) {if (type == this.ajax) {res.writeHeader(200, {'Cache-Control': 'no-cache, must-revalidate'});res.write(this.noise);} else {res.writeHeader(200, {"Content-Type" : "multipart/x-mixed-replace",'Cache-Control': 'no-cache, must-revalidate'});res.write(this.page['iframe.html']);res.write(this.noise);}this.client[id] = {res : res,type : type,tm : setTimeout(function(){pipeClient.close(id);}, this.timeout)};},close : function (id) {console.log("client close", id)this.client[id].res.end();this.client[id].res = null;delete this.client[id];},write : function (id, data) {clearTimeout(this.client[id].tm);this.client[id].tm = setTimeout(function(){pipeClient.close(id);}, this.timeout);this.client[id].res.write(this.format(data, this.client[id].type));},format : function(data, type) {// with iframeif (type == this.iframe) {var buf = new Buffer(this.prefix.length + data.length + this.suffix.length);buf.write(this.prefix, 0, 'binary');data.copy(buf, this.prefix.length, 0);buf.write(this.suffix, this.prefix.length + data.length);// with ajax} else {var buf = new Buffer(data.length + 8);// set lengthbuf.write(data.length.toString(16), 0, 'binary');// space paddingfor (var i = data.length.toString(16).length; i < 8; i++) {buf[i] = 32;}// set datadata.copy(buf, 8, 0);}console.log(buf.toString());return buf;}}pipeClient.init();page = readFile(['pipe.html']);setTimeout(function(){server.listen(8000);}, 500);

pipe.html: 客户端程序

Comet Pipe Demo

iframe.html: ie下iframe模式运行的输出头

标签:

原创文章

qingdu 在 2011-1-21 15:28发布

qingdu 在 2012-1-19 12:10重新编辑

分享到 weibo

4 回复

#1 pengchun

developerworks上的一篇经典的文章:

http://www.ibm.com/developerworks/cn/web/wa-lo-comet/

pengchun 在 2011-1-21 21:24回复

#2 anonymous

30秒后由服务器端向客户端传输 数据的通道就关闭了?

anonymous 在 2011-1-24 16:27回复

{1}

qingdu

对, 这里是开发时为了方便,避免浏览器的http并发上限阻塞用的

实际系统中可以去掉这块

或者在client中增加重连的功能

qingdu 在 2011-1-25 14:17回复

#3 suqian

原来就在这里。。。先收藏

suqian 在 2011-2-16 22:09回复

#4 suqian

pipe通道在一段时间没有数据返回将会中断,服务器端再向它发送数据就会无效了。监听response的error事件又无法捕获到错误事件,这样会导致坏死的client链接越来越多。需要一种机制来处理这个问题。

suqian 在 2011-2-18 17:48回复

本文链接地址:https://www.jiuchutong.com/zhishi/303296.html 转载请保留说明!

上一篇:portal.php怎么去掉(php消除警告)

下一篇:phpcms提示服务器安全认证错误(php服务器地址怎么填)

  • iqooz1屏幕多大尺寸(iqooz1屏幕最高多少nit)

    iqooz1屏幕多大尺寸(iqooz1屏幕最高多少nit)

  • 优酷0.1元7天会员怎么解约(优酷0.1元7天会员是真的吗)

    优酷0.1元7天会员怎么解约(优酷0.1元7天会员是真的吗)

  • 倍思耳机怎么连蓝牙(倍思耳机怎么连接2个手机)

    倍思耳机怎么连蓝牙(倍思耳机怎么连接2个手机)

  • 荣耀x10和红米10x的区别有哪些(荣耀X10和红米note11TPor哪个好)

    荣耀x10和红米10x的区别有哪些(荣耀X10和红米note11TPor哪个好)

  • qq音乐歌词海报时间可不可以长一点(qq音乐歌词海报怎么没有了)

    qq音乐歌词海报时间可不可以长一点(qq音乐歌词海报怎么没有了)

  • 华为mate30pro有哪些黑科技(华为mate30Pro有哪些黑科技)

    华为mate30pro有哪些黑科技(华为mate30Pro有哪些黑科技)

  • 华为体验店可以免费贴膜吗(华为体验店可以修手机吗)

    华为体验店可以免费贴膜吗(华为体验店可以修手机吗)

  • 微信号只能改成字母吗(微信号只能改成自己的吗)

    微信号只能改成字母吗(微信号只能改成自己的吗)

  • 爱奇艺绑定身份证更换(爱奇艺绑定身份证号怎么解除)

    爱奇艺绑定身份证更换(爱奇艺绑定身份证号怎么解除)

  • 网络信息资源的八种类型(网络信息资源的表达形式)

    网络信息资源的八种类型(网络信息资源的表达形式)

  • 手机突然不能全屏播放为什么(手机不能全屏显示解决办法)

    手机突然不能全屏播放为什么(手机不能全屏显示解决办法)

  • 小米10充电要多久时间?(小米10充电要多少瓦)

    小米10充电要多久时间?(小米10充电要多少瓦)

  • 微软的聊天机器人叫什么(微软聊天机器人tay上线不到一天就紧急下线了)

    微软的聊天机器人叫什么(微软聊天机器人tay上线不到一天就紧急下线了)

  • 抖音为什么不显示音浪了(抖音为什么不显示火花)

    抖音为什么不显示音浪了(抖音为什么不显示火花)

  • 2560x1600分辨率高吗(2560x1600分辨率高吗笔记本)

    2560x1600分辨率高吗(2560x1600分辨率高吗笔记本)

  • 抖音消息免打扰对方知道吗(抖音消息免打扰怎么设置)

    抖音消息免打扰对方知道吗(抖音消息免打扰怎么设置)

  • 快手直播视频用什么软件(快手直播视频用什么软件下载)

    快手直播视频用什么软件(快手直播视频用什么软件下载)

  • 苹果和华为之间怎么定位(苹果和华为之间可以手机克隆吗)

    苹果和华为之间怎么定位(苹果和华为之间可以手机克隆吗)

  • fttb是什么意思(fttb含义)

    fttb是什么意思(fttb含义)

  • 微信封8天能不能提前解封(微信封了8天)

    微信封8天能不能提前解封(微信封了8天)

  • 为什么苹果相机照出来是反的(为什么苹果相机拍出来的照片是反的)

    为什么苹果相机照出来是反的(为什么苹果相机拍出来的照片是反的)

  • 苹果x插耳机怎么没用(苹果x插耳机怎么用)

    苹果x插耳机怎么没用(苹果x插耳机怎么用)

  • 手机怎么制作透明图片(手机怎么制作透明背景的文字图片)

    手机怎么制作透明图片(手机怎么制作透明背景的文字图片)

  • 苹果官网换购流程(苹果官网买手机换购)

    苹果官网换购流程(苹果官网买手机换购)

  • 小度音箱如何控制灯(小度音箱如何控制空调)

    小度音箱如何控制灯(小度音箱如何控制空调)

  • ps精修人脸技巧(ps修人脸教程)

    ps精修人脸技巧(ps修人脸教程)

  • 支付宝怎么绑定亲情号(支付宝怎么绑定别人的信用卡)

    支付宝怎么绑定亲情号(支付宝怎么绑定别人的信用卡)

  • 惠普笔记本型号在哪里看(惠普笔记本型号在哪看)

    惠普笔记本型号在哪里看(惠普笔记本型号在哪看)

  • apt-key命令  管理APT软件包密钥信息(apt-key is deprecated)

    apt-key命令 管理APT软件包密钥信息(apt-key is deprecated)

  • 印花税应交税费
  • 房产证,契税
  • 哪些情况需要提高警惕小心毒品
  • 公司的股东就是公司的发起人
  • 失控发票一定要补税吗
  • 财务会计和预算会计是两套账吗
  • 小规模超过30万附加税减半吗
  • 小规模纳税人残保金
  • 小规模纳税人印花税是季报还是月报
  • 知识产权局专利审查协作中心
  • 购进蔬菜的进项税额
  • 工程项目结算方式有哪几种
  • 员工借款怎么入账
  • 会计凭证的填制与审核过程
  • 行政单位财务长期挂账处理办法
  • 劳务派遣公司发放工资是按照劳务报酬嘛
  • 实际缴纳增值税税额是什么意思
  • 火腿属于免税产品吗
  • 商贸公司购买货物会计分录
  • 全资子公司如何证明自己的财产完全独立于母公司
  • 平均应收账款金额
  • 在建工程转固定资产后如何计提折旧
  • 企业购地流程
  • 公司logo设计费是业务宣传费吗
  • php获取ftp文件目录
  • PHP:pg_options()的用法_PostgreSQL函数
  • 进项税额转出会计分录账务处理
  • 资产负债表左方烈士的资产按什么排列
  • 已领待用物资
  • 解决城市内涝的题目
  • php函数传值的引用是什么
  • 环境检测费计入什么费用
  • 前端经典面试题讲解
  • springboot aop切面
  • nor命令
  • 企业报表年报
  • 社保基数怎么申请下调
  • php匹配邮箱
  • 应收账款计提坏账准备是什么意思
  • 稽查查补的税款由谁追征
  • 公司银行销户钱转到哪里去
  • 餐饮发票要钱吗
  • 短期股票投资售出
  • 装修工程一般质保几年
  • sql2008数据库存放位置
  • 营业总收入和营业利润
  • 个体户如何做账?
  • 收到国税退回的税款分录
  • 预付款项怎么做分录
  • 申报抵扣了不做账怎么处理?
  • 免抵退账务处理流程
  • 印花税的通俗理解
  • 什么是内部报酬吗
  • 税后扣款怎么做账
  • 现金存入银行是什么凭证
  • 如果是车间不生气怎么办
  • 旅游服务会议费发票
  • 如何远程连接小米摄像头
  • Freebsd7.0 Apache2.2+MySQL5+PHP5安装和配置方法
  • 一台OpenSuSE系统的服务器的网络配置
  • dlg是什么意思中文
  • 苹果电脑安装中国银行网银助手
  • 在mac设备上用到什么
  • 苹果mac怎么复制文字
  • linux系统的配置设计过程
  • lnmp php
  • javascriptdom编程
  • jquery直接执行
  • node.js环境搭建
  • from tkinter import
  • unity 3d资源
  • java深入理解
  • unity双面材质
  • javascript中的splice
  • JavaScript中的数据类型
  • jquery的筛选
  • 安卓app活动
  • 车船税补办
  • 发票是去国税还是地税
  • 入库税收怎么根据完税证明
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设