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

  • 锁屏音乐播放器如何关闭的呢(锁屏音乐播放器 不见了)

    锁屏音乐播放器如何关闭的呢(锁屏音乐播放器 不见了)

  • ios15相机怎么提取文字(ios15相机新功能怎么使用)

    ios15相机怎么提取文字(ios15相机新功能怎么使用)

  • 小米青春版如何关闭HD(小米青春版如何截屏)

    小米青春版如何关闭HD(小米青春版如何截屏)

  • airpods麦克风坏了(airpods麦克风坏了保修吗)

    airpods麦克风坏了(airpods麦克风坏了保修吗)

  • 小米充气宝能充汽车吗(小米充气宝能充suv小车吗)

    小米充气宝能充汽车吗(小米充气宝能充suv小车吗)

  • goldwave支持一次打开几个音频文件(goldwave使用方法 完全教程)

    goldwave支持一次打开几个音频文件(goldwave使用方法 完全教程)

  • 流量kb和mb哪个大(流量kb跟mb有什么区别)

    流量kb和mb哪个大(流量kb跟mb有什么区别)

  • 荣耀x10什么时候开售(荣耀X10什么时候停产)

    荣耀x10什么时候开售(荣耀X10什么时候停产)

  • 二进制数111111转换成十进制数是多少(二进制数1111111111转换成十进制数等于( ))

    二进制数111111转换成十进制数是多少(二进制数1111111111转换成十进制数等于( ))

  • 闲鱼退货卖家不处理(闲鱼退货卖家不签收)

    闲鱼退货卖家不处理(闲鱼退货卖家不签收)

  • stop:0x00000074蓝屏代码是什么意思

    stop:0x00000074蓝屏代码是什么意思

  • 陌陌互相关注不能视频(陌陌互相关注不显示距离)

    陌陌互相关注不能视频(陌陌互相关注不显示距离)

  • cd和dvd光盘是否通用(cd-r光盘和dvd-r)

    cd和dvd光盘是否通用(cd-r光盘和dvd-r)

  • 高斯克吕格投影是什么投影(高斯克吕格投影3度分带)

    高斯克吕格投影是什么投影(高斯克吕格投影3度分带)

  • iPhone11pro电池容量多大(iphone11pro电池容量多少毫安)

    iPhone11pro电池容量多大(iphone11pro电池容量多少毫安)

  • 华为荣耀8x有智能遥控吗(华为荣耀8x有智能语音唤醒吗)

    华为荣耀8x有智能遥控吗(华为荣耀8x有智能语音唤醒吗)

  • 手机腾讯视频怎么调全屏(手机腾讯视频怎么微信扫码登录)

    手机腾讯视频怎么调全屏(手机腾讯视频怎么微信扫码登录)

  • 百度云链接怎么形成(百度云链接怎么打开)

    百度云链接怎么形成(百度云链接怎么打开)

  • vivo120w快充什么时候上市(vivo120w快充支持哪些机型)

    vivo120w快充什么时候上市(vivo120w快充支持哪些机型)

  • 陌陌停车游戏在哪(陌陌停车游戏在哪里看帖了谁的车)

    陌陌停车游戏在哪(陌陌停车游戏在哪里看帖了谁的车)

  • 抖音怎么把视频和照片剪辑在一起(抖音怎么把视频放慢速度)

    抖音怎么把视频和照片剪辑在一起(抖音怎么把视频放慢速度)

  • 小米9最厚处厚度是多少(小米九厚度)

    小米9最厚处厚度是多少(小米九厚度)

  • pctal10是荣耀v20么(荣耀v20型号pct al10和tl10的区别)

    pctal10是荣耀v20么(荣耀v20型号pct al10和tl10的区别)

  • 小米手环3睡眠监测原理(小米手环3睡眠监测需要设置时间吗)

    小米手环3睡眠监测原理(小米手环3睡眠监测需要设置时间吗)

  • 【vue】 配置代理(vue3.0配置代理)

    【vue】 配置代理(vue3.0配置代理)

  • 应收账款的期末余额在借方表示什么意思
  • 企业留存的盈余公积属于哪个会计科目
  • 收到幼儿园园服费怎么做财务处理?
  • 网线的税收编码是多少
  • 汇算清缴a107020表
  • 公章更换后需要到工商局备案么
  • 非税收入如何审查
  • 金税盘的进项发票怎么导出
  • 企业外购消费品会计分录
  • 应交增值税已交税金的账务处理
  • 营改增后还有企业所得税吗?
  • 出口退税是按进项税额吗
  • 房屋装修费用计算器
  • 新疆税收扶持丝路古镇喀什重放异彩
  • 增值税在免税范围内,附加税怎么做
  • 公司还款给法人需要缴税吗
  • 上年工资计提多了才发现
  • 利润表与所得税申报表不符
  • 应付账款借方余额怎么平账
  • 转口贸易需要申报什么税
  • 未分配利润分配利润分录
  • 礼品应该计入会计分录
  • 银行与银行之间转账会计摘要
  • 税控盘技术服务费可以抵税吗
  • php html5
  • 代扣代缴个人工会经费 企业所得税
  • win7纯净版系统之家
  • windows搭建dvwa
  • 无运输工具承运业务的经营者适用免税政策
  • 建筑企业预缴企业所得税怎么计算
  • php删除数组中重复的元素
  • hbuilderx的使用视频
  • 购买办公楼之后怎么入账
  • 考研408怎么样
  • 拨缴经费收入上解部分
  • 社保缴费工资和实发工资不一样
  • 应付职工薪酬是负数是什么意思
  • vue开发环境配置
  • apache trace
  • 二手车减免增值税的规定
  • 账务处理相关内容
  • 企业增值税专用发票抵扣流程
  • 认缴怎么填
  • 营改增之后账务怎么处理
  • 以前年度损益调整科目编码是多少
  • 申报抵扣了不做账怎么处理?
  • 办公室清洁费计入办公费吗
  • 外购材料用于建筑工程会计分录
  • 进项发票已经认证,对方作废了
  • 民办非企业没有了吗
  • 建账有哪几种方法
  • sql查询包含特殊
  • linux 显示
  • fedora系统怎么安装
  • 海尔笔记本最新款
  • windows server 2016 百度网盘下载
  • winpsd.exe - winpsd是什么进程
  • 录制界面
  • PHP startup: Unable to load dynamic library错误的错误
  • diy组装电脑前置怎么样
  • win7系统的安装
  • windows8.1更新windows10
  • win7如何打开命令窗口
  • 延长药品使用时间的方法
  • windows 8.1安装教程
  • win7系统怎么关闭病毒防护
  • android开发环境配置
  • qt5 opengl
  • php滚动代码
  • bat获取当前路径的值
  • 字符有大小吗
  • android auto翻译
  • unity manifest
  • unity 角色
  • react navigate
  • 广州契税补贴2022政策
  • 全国企业信用信息系统网官网
  • 珠海南湾国际属于香洲哪个街道
  • 外贸公司销售额可以10亿以上吗
  • 《税收实务》
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设