位置: 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服务器地址怎么填)

  • 笔记本电脑创建wifi热点(win7笔记本做wifi热点)(笔记本电脑创建新用户)

    笔记本电脑创建wifi热点(win7笔记本做wifi热点)(笔记本电脑创建新用户)

  • vivox70pro+重量(vivox70pro机身尺寸)

    vivox70pro+重量(vivox70pro机身尺寸)

  • 红米usb调试在哪里打开(红米的usb调试)

    红米usb调试在哪里打开(红米的usb调试)

  • feedme笔记本电脑是什么牌子(feedme笔记本电脑官网)

    feedme笔记本电脑是什么牌子(feedme笔记本电脑官网)

  • 滴答预约顺风车取消要给钱吗(滴答预约顺风车车主取消了会怎样)

    滴答预约顺风车取消要给钱吗(滴答预约顺风车车主取消了会怎样)

  • 双十一能退货退款吗(双十一退货退款时已抵扣红包怎么办)

    双十一能退货退款吗(双十一退货退款时已抵扣红包怎么办)

  • 如何让群二维码失效(如何让群二维码固定)

    如何让群二维码失效(如何让群二维码固定)

  • 小米网关是什么(小米网关是干嘛用的)

    小米网关是什么(小米网关是干嘛用的)

  • 网易云音乐怎么购买单曲(网易云音乐怎么下载到U盘)

    网易云音乐怎么购买单曲(网易云音乐怎么下载到U盘)

  • 苹果怎么看自动续费的东西(苹果怎么看自动续费有没有关闭)

    苹果怎么看自动续费的东西(苹果怎么看自动续费有没有关闭)

  • 荣耀30s支持多屏协同吗(荣耀30s可以双屏吗)

    荣耀30s支持多屏协同吗(荣耀30s可以双屏吗)

  • 苹果13.3.1系统怎么设置来电闪光灯(苹果13.6系统怎样)

    苹果13.3.1系统怎么设置来电闪光灯(苹果13.6系统怎样)

  • b站的音频区在哪里(b站音频区在哪个版本可以看)

    b站的音频区在哪里(b站音频区在哪个版本可以看)

  • win7我的电脑怎么添加到桌面(win7我的电脑怎么添加到桌面图标)

    win7我的电脑怎么添加到桌面(win7我的电脑怎么添加到桌面图标)

  • 天猫拒收退货流程(天猫拒收退货流程图)

    天猫拒收退货流程(天猫拒收退货流程图)

  • 小米cc9pro需要贴膜吗(小米cc9pro支持防水吗)

    小米cc9pro需要贴膜吗(小米cc9pro支持防水吗)

  • 荣耀4手环什么时候出(荣耀手环什么时候出8)

    荣耀4手环什么时候出(荣耀手环什么时候出8)

  • 手机酷狗怎么桌面歌词(手机酷狗怎么桌面显示音乐)

    手机酷狗怎么桌面歌词(手机酷狗怎么桌面显示音乐)

  • iphonexra2108什么意思(iphone xr2108是什么型号)

    iphonexra2108什么意思(iphone xr2108是什么型号)

  • 京东购物如何使用商品对比的功能(京东购物如何使用白条支付)

    京东购物如何使用商品对比的功能(京东购物如何使用白条支付)

  • 小米mix2s无线充电在哪设置(小米mix2s无线充电功率)

    小米mix2s无线充电在哪设置(小米mix2s无线充电功率)

  • 一加手机代言人是谁(一加手机代言人胡歌)

    一加手机代言人是谁(一加手机代言人胡歌)

  • 附近充电宝(附近充电宝租借自助机位置)

    附近充电宝(附近充电宝租借自助机位置)

  • 真正有效解决vue addRoute动态添加路由后刷新页面白屏的靠谱方法及思路,切实可行!(真正有效解决近视的方法)

    真正有效解决vue addRoute动态添加路由后刷新页面白屏的靠谱方法及思路,切实可行!(真正有效解决近视的方法)

  • 金税盘年费能全额抵扣吗
  • 财务报表没有申报表
  • 多缴纳个人所得税怎么办
  • 知道销项税怎么算进项
  • 货物已到发票未到怎么做账
  • 关联方借款的企业所得税政策
  • 资产负债表和利润表和现金流量表的关系
  • 高速公路通行费专用发票可以抵扣吗
  • 软件企业增值税退税的账务处理
  • 公司客车高速费如何抵扣进项税?
  • 代账公司收取服务费能开增值税票吗?
  • 金税盘增值税普通发票红冲操作流程
  • 其他应付款质保金到期怎么附单据
  • 资产基金科目如何选择
  • 进项税额忘了抵扣
  • 政府补贴专项资金如何入账
  • 个人汽车贷款所购车辆
  • 个体工商户减免房租政策2022年
  • 当月有进项税额转出怎么结转未交增值税
  • win10开机选择系统%1
  • 个人独资企业没有章程
  • 开办费计入长期待摊费用汇算清缴时怎么填写
  • win11资源管理器怎么打开
  • PHP:mb_encode_mimeheader()的用法_mbstring函数
  • 附有退货条款的销售
  • 金融资产包括哪三大类及会计科目
  • win7系统怎么设置最佳性能
  • PHP:mcrypt_enc_self_test()的用法_Mcrypt函数
  • 混合成本的分解方法很多,通常有
  • 投资收益怎么做不影响利润
  • 最小的成像传感器
  • 工程项目成本费用的分类有哪些?
  • Laravel5.* 打印出执行的sql语句的方法
  • phpseclib
  • django pypi
  • android应用程序开发语言
  • emerge命令
  • 税务局清税
  • 小企业会计准则财务报表至少包括
  • 代扣税费分录
  • 扶贫款分红怎么做账
  • 购买材料发票未到如何做账?
  • 新会计准则其他收益核算内容
  • 其他综合收益和营业外收入的区别
  • 暂估入库有时间限制吗
  • 内账税金如何做分录
  • 可转换债券发行主体
  • 产权交易所交易流程
  • 个体工商户对公账户需要交税吗
  • 猪肉蔬菜是免税农产品吗
  • mysql 5.5 5.6
  • win2000停止服务
  • Win10预览版更新弹窗如何关闭
  • windows隐藏文件夹开启
  • solaris syslog配置
  • Ubuntu上安装anaconda
  • mac安装mysql详细教程
  • pps是什么文件
  • win7关闭混合睡眠
  • mac itunes
  • windows7cmd命令不能执行
  • 如何设置win10用户名
  • Linux mysql如何更改root密码以及忘记root密码的修改方法
  • 如何解决windows资源管理器已停止工作
  • win10系统桌面图标有白色方框的解决方法图...
  • win7开机系统恢复
  • javascript访问用户cookie
  • ghost详细说明
  • unity3d 游戏开发 消息通信
  • 使用vue-cli快速搭建vue项目
  • Ubuntu修改用户名
  • android+
  • js面向对象的原理
  • jquery编写Tab选项卡滚动导航切换特效
  • android刷题
  • javascript面向对象吗
  • 江苏税务怎么登陆
  • 国家税务局天津市税务总局官网
  • 计算消费税为什么要除1-比例税率
  • 海员证办理流程需要什么手续时间多长
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设