licode

来源:互联网 发布:驾校抢约车软件 编辑:程序博客网 时间:2024/05/20 04:27

mongodb

基于分布式文件存储,非关系数据库,类似json的bson格式http://www.mongodb.org/downloadsmongo 10.50.141.25/nuvedb  // 用IP连接某个数据库 mongo --port 27017show dbs // 显示所有数据库use nuvedb // 进入某个数据库show collections // 显示此数据库的所有表db.records.find().count()  // 显示某表的所有记录的数目db.records.find({"state":{$gt:4}}, {filename:true}) //查询状态大于4的且只显示文件名db.records.distinct("state")  // [ 5, 3, 4, -1 ] 显示状态列且不重复db.records.update({filename:/c71129a/},{$inc:{"state":1}},false,true) // 条件,设置加1,插入否,多条更新是db.records.remove({state:4}) // 删除记录db.records.drop() // 删除表服务器端:mongod --dbpath ./testMongo/master/ --port 10000 --master --logpath ./masterlog.txt --logappend // 启动主服务器echo ''>./masterlog.txt // 服务器运行时,清空后继续写日志;删除日志文件后,后续的就写不了mongod --dbpath ./testMongo/slave/ --source 10.50.141.43:10000 --slave --port 10001 --logpath ./testMongo/slave/mylog/slave.log // 启动从服务器,带logmongodump -h 10.50.141.43:10001 -d masterDing -o ./testMongo/slave/mydump/ // 备份哪个服务的什么库到什么地方mongorestore -h 10.50.141.43:27017 --directoryperdb ./testMongo/slave/mydump/ // 恢复到哪个服务,用什么数据部署:主从,副本集,分片    副本集就是有自动故障恢复功能的主从集群。问题:1. 快:空间换时间,加载到内存的数据不会主动释放(索引,命中的数据块),多了导致宕机2. 数据量过万,不稳定3. collections层的删除,并没有直接释放空间,长期导致大量碎片,如下当在mongodb中删除了大量的数据后, 日志中会出现以下信息:[conn154] info DFM::findAll(): extent 2:8c6c000 was empty, skipping ahead. ns:eu3g.rankings_general意思是太多闲置的空间(删除体积较大的集合,或删除大量文档后腾出的空间)。可以通过修复命令来压缩数据: db.repairDatabase();

socket

WebSocket    是一个基于TCP的协议,就是握手链接的时候跟HTTP相关(发了一个HTTP请求),这个请求被Server切换到(Upgrade)websocket协议了。websocket把 80 端口作为默认websocket连接端口,而websocket的运行使用的是443端口。它是实现了浏览器与服务器的全双工信息传输。经过简单的握手协议,建立一个长连接,按照协议的规则进行数据的传输。     socket.io// 建立socket服务器:var io = require("socket.io").listen(5000);  io.sockets.on("connection", function(socket){        socket.on("initconnection", function(data, callback) {  })  });客户端:var socket = io.connect(url);   socket.emit("initconnection", {say:'h r u?', user:'dld'}, function(res) {  });//中转消息 : clientA:emit("A")--->Server--->clientB:on("B")服务器: socket.on("A", function(data, callback){          io.sockets.socket(socketId).emit("B", data); });

design

<pre class="html" name="code">基于WebRTC实现的: 网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年收购的。
one2Many 把多对多的通信,分解为每个点对应的一个one2Many结构。 MCU分配: 原则,尽量避免跨MCU,减小碎片。方法,排序后把数目最接近的进行分配。 log:log文件太大,会影响系统的运行。log分级,分模块,加时间。 void log(enum PrintLevel level, const char* _format, ...); #define INFO_LOG(format,args...) _log.log(INFO_LOG, format, ##args) wiucs::Testlog _log; // 每个使用打印的类定义一个这样的成员变量

利用amqp来完成rpc(远程过程调用,即通过网络从远程计算机程序上请求服务)

    erizoController.js -----{client}--rpc(amqp)-{server}-----nuve(管理多个eCtrl)
                   \----------------{server}--socket.io/websocket--{client}----client.js

底层音视频传输: 用到了SRTP,即安全实时传输协议(Secure Real-time Transport Protocol)


工具

<p><span style="font-family: Arial, Helvetica, sans-serif;">js打包工具compiler.jar   // </span><span style="font-family: Arial, Helvetica, sans-serif;">java -jar compiler.jar --js xxx.js</span></p>node-GYP 项目构建工具     node_addon  node调用Linux下的动态库,库由c++实现。<span style="white-space:pre"></span>需要node内部的库,比如ObjectWrap, Node已将所有依赖关系静态地编译成可执行文件,因此我们在编译自己的组件时不需要担心和这些类库的链接问题。


rabbit amqp(高级消息队列协议)

        生产者 ----- eXchange ---'routeKey1'--->Queue1-----消费者1                        |----'routeKey2'--->Queue2-----消费者2   1. 连接rabbitServer, 创建交换机,队列,将他们之间用关键字关联起来。        交换机:var exc =conn.exchange(Xname, option, cb);       队列:var q = conn.queue(Qname,cb);       绑定:q.bind(Xname, routeKey);   2. 队列1(nuve): 存放被别人调用的一些函数,取出执行并将结果存放到队列2。        如何存放:生产者为其调用者如:ec调用 callRpc = function (routeKey, method, args, callback)          实际处理为: var send = {method: method, args: args, corrID: corrID, replyTo: clientQueue.name                    exec.publish(routeKey, send)       执行并处理结果:q.subscribe(function (message) {                        rpcPublic[message.method](message.args, function (result) {                            exc.publish(message.replyTo, {data: result, corrID: message.corrID});                     });});    3. 队列2(clientQ):存放的是队列1执行的结果,将结果作为参数用回调函数处理        通过replyTo收到结果,通过corrID调用callback来处理: map[message.corrID].fn(message.data);   4. 多个不同的处理进程,可以在此进程注册后,再绑定相应的处理队列        如ec的处理:在注册到nuve后(ec[i] = {...}),再生成q = conn.queue(ec_id, cb);

keepAlive

   server:  nuve定时给每个mcu的keepAlive +1        checkKAInterval = setInterval(checkKA, INTERVAL_TIME_CHECK_KA);    // cloudHandler.js       checkKA = function() {...erizoControllers[ec].keepAlive += 1;...}  // cloudHandler.js    client:  mcu把nuve上面对应自己的设置为0       rpc.callRpc('nuve', 'keepAlive', myId, callback); //ec.js       keepAlive = function (id, callback) {... erizoControllers[id].keepAlive = 0; ...} // cloudHandler.js

event

   1. 增加监听(注册函数) addEventListen(type, listen); // eventListeners[eventType].push(listener);   2. 派遣(调用函数) dispatchEvent(event);  // 调用 eventListeners[event.type][listener](event);

js

 // 数组var arr = [];arr.push(1);arr.splice(index, count);// 模块导出var wiucs = wiucs || {}; //  wiucs.ex = ( function (wiucs) { return {}; } (wiucs) ); // 使用 wiucs.ex.returnSomeValue module.exports = wiucs;      函数定义后执行   (function(){})();    函数调用并后台执行:  ( run; ) &          捕捉信号并处理:      trap "exit_fun" 2 3 9 15    多个条件并列:        while [ $LENGTH -gt $INDEX -a "$EXIT_NOW" = "0" ];  // -a == and ?    结构以及数组   var rooms = {};rooms[roomid] = {};          rooms[roomid][ecid] = {streams:{}, sockets:{}}; // 结构带有标签rooms{roomid][ecid].streams[streamid] = {aSsrc:,...};          

nodejs及其组件的功能  

// 单线程而并发操作:Node.js事件轮询机制(event loop)创建webAppvar express = require("express");var app = express();// 创建webServervar http = require("http");var server = http.createServer(app);server.listen(8000);// 处理文件var fs = require("fs");// 执行linux 命令var exec = require("child_process").exec;exec(execStr, function(err, output){});//XMLhttprequest发送请求var req = new XMLHttpRequest();req.onreadystatechange = function() { if (req.readystate == 4) callback(req.responseText);} 

HTML杂项

iframe/window之间的信息传递    假设从A传递到B:    A:window.parent.BframeName.postMessage(message, "*");    B : window.attachEvent("onmessage",  callbackFunc);      // or addEventListener("message", func, false)         var callbackFunc = function(e) {   var data = e.data;}div中显示可缩放矢量图形(Scalable Vector Graphics,SVG)    document.getElementById("divId").innerHTML = "<svg>..."       https://code.google.com/p/svg-edit/  不缓存页面    服务器返回的消息中携带以下值,表示要不要客户端存    客户端:工具中的选项 表示 要不要用显示的内容 // printf("Content-type: text/html\n\n");// window调用iframe:document.getElementById("iframeId").contentWindow.iframeVar = "XXX"; (...contentWindow.iframeFunction();   ...contentWindow.document.getElementById();)// iframe调用window:parent.windowVar = "XXX"; (parent.winFunction();)// window传递数据给不同域的iframewindow: window.parent.iframeId.postMessage(msg, "*");iframe: window.addEventListener("message", msgFunc, false); var msgFunc = function(e) { console.log(e.data);}// 清除所选择的file<input type=file name="fileName"> fileName.outerHTML = fileName.outerHTML;  // maybe fileId// 增加divdocument.body.appendChild(div);// 增加livar ul = document.getElementById("ulid");var li = document.createElement("li");li.id = ;...ul.appendChild(li);// 删除某个li  if( lis.item(id).id == xxx )var lis = ul.childNodes;ul.removeChild(lis.item(id)); // 删除全部livar total = lis.length;for(var i = 0; i < total; i++) {// 每删除列表中的第一个li, 其他li会重新排列。lis.length, item(0)等都会变化     ul.removeChild(lis.item(0));  }//uuid的生成var uuid = Math.floor(Math.random()*16.0).toString(16);</svg>

chrome

      navigator.getUserMedia({          video: {            mandatory: {              minHeight:600,              maxBandwidth:500            },            optional: [              {                maxAspectratio: 1.333333333333,                minTimebetweenrefframes: 20,                minFramerate: 30,                enumAutowhitebalance: "on"              },              {                minTimebetweenrefframes: 40,                minFramerate: 10              },           ]         }      });

lib

ffmepg, libvpx     libwebm: 修改webm参数: 1440 *900; 25fms

media

PCM(Pulse-code modulation),即脉冲编码调制       放MP3,要把数据解压还原成最简单的原始数据才行。       waveXXX底层函数操作的都是pcm数据,也就是wave数据,也就是我们在音频里常说的原始数据。       MP3之类的是压缩过的数据,要让声卡放MP3,必须把MP3翻译(解压缩)成声卡认识的数据格式。声卡一般只认一种格式,就是wave那种原始的裸数据相关      每个采样点都记录下了原始模拟声波在某一时刻的状态,通常称之为样本(sample)      而每一秒钟所采样的数目则称为采样频率      对于采样过程中的每一个样本来说,数字音频系统会分配一定存储位来记录声波的振幅,一般称之为采样分辩率或者采样精度      采样就是每隔一定时间就读一次声音信号的幅度,而量化则是将采样得到的声音信号幅度转换为数字值      奈奎斯特(Harry Nyquist)采样理论:如果对某一模拟信号进行采样,则采样后可还原的最高信号频率只有采样频率的一半,            或者说只要采样频率高于输入信号最高频率的两倍,就能从采样信号系列重构原始信号。      帧率:Frames per Second,简:FPS。(30fps感受可以,60fps完美,75fps感受不到更好的差异。            屏幕的刷新频率一定要大于帧率,否则浪费帧!)      YUV帧: 「Y」表示明亮度(Luminance、Luma),「U」和「V」則是色度、濃度(Chrominance、Chroma),            采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。            如果用directx,是直接获得YUV数据. 如果是用api,则是位图,还得再转成YUV才能进行视频压缩.     cng是产生一段背景静音      Vorbis : 免费,多声道,流式,可变编码速率,音频编码      PCMA == G.711A  64kbps 宽带(低带宽: G723需要5.3/6.4kbps,G729需要8kbps)      音频 ISAC : 16000采样率, 16 bits采样精度, 1 channel通道      rtpHead.csrc * 4 ?      // csrc列表个数 * 每项4个字节      mkv :多种格式的音视频,多音轨,带字幕      录完了都要用视频编辑软件再编码压缩的...         我当初录游戏1680X1050分辨率的40分钟总共30G 压完了是1G的AVI X264编码 1440X900音视频同步      由开始记录的,第一个audio/video的rtp/rtcp包,得到第一个A,V rtp包的时间戳pts,单位纳秒 (1秒 == 1000 000 000 纳秒)        1)  有音频的rtp, rtcp包的时间戳的差值 / 采样频率 = 两包的时间差(秒),                  rtcp中有ntp,即64bit的标准时间(纳秒),从而可以得到音频的rtp包的时间(纳秒)         2)  音视频rtp包的时间之差,设置为大的pts时间,小的pts时间为0,将pts传入libwebm/ffmpeg的打包中,即可实现同步。     视频帧:    I帧:关键帧,P帧:猜测帧,B帧:双向帧     PTS 显示时间戳:是presentaion time stamp,是该包第一个音频采样的时间.     DTS 解码时间戳混音:     解压缩完之后是PCM, 进行叠加,overflow处理, 然后再压缩,发送.解压之后的PCM的采样率及精度是需要一致的.    直接将PCM的数据做加法,但要注意数据范围,如         8bit音量范围是0-255 , 8bit的相加的结果用short保存        16bit音量范围是-32767-32767 , 16bit的相加结果用int保存,否则你的判断可能是无效的        1,各个声源的采样率一定要一致,不一致的话就要重采样,使之采样率相等。       2,你要确定,你那16BIT到底是不是肯定为一个声音通道的。否则当然不能囫囵吞枣的加起来。       3,其次,检查你的运算代码的运算模式:一定要用浮点数进行计算,哪怕最后再转成整型也成。       4,最次是一些杂项问题,比如Big-ending和Little-ending问题等。html的video标签支持3中文件格式:       webm = vp8(just move off rtp/vp8 head) +vorbis(isac-->pcm-->vorbis)      mpeg4    = H.264 + aac      ogg   =  Theora 视频编码 + vorbis 音频编码                            libwebm = segment + clusters(= audio track + video track + block)webRtc中音频的处理流程      采集---〉ISAC编码---〉发送---〉接受---〉ISAC解码---〉播放                                       |--->rtp记录--->ISAC解码--->vorbis编码--->webm打包---> webm, vorbis解码后播放计算      音频帧的播放时间  =  一个帧对应的采样样本的个数  /  采样频率      一个AAC原始帧包含一段时间内1024个采样及相关数据,采样率 Samplerate 44100Hz             当前AAC一帧的播放时间是  = 1024个 * 1000ms / 44100个= 22.32(单位为ms)     时间戳 = 每个包/帧的时间 * 采样频率                       MPEG,每帧20ms,采样频率8000Hz,设定时间戳单位1/8000,而每个包之间就是 160 = (20ms * 8000个/1000ms)的增量。     130万的摄像头对应多少带宽?        130万像素的网络摄像机,其传输带宽大约需要1Mbps的带宽: 130万比特 * 25帧/秒   / 1024 /1024 / 30压缩比 = 1.03 Mb每秒     40万的?至少分辨率需要480 * 640       480 * 640 * 25 / 1024  / 30 = 250 Kb   //  实验数据也是200多Kb实验数据:     45分钟的屏幕录制:109MB;  20m: 44MB     音频  m=audio 33085 RTP/SAVPF 103 104 0 8 106 105 13 126        a=rtpmap:103 ISAC/16000        a=rtpmap:104 ISAC/32000        a=rtpmap:0 PCMU/8000        a=rtpmap:8 PCMA/8000           a=rtpmap:106 CN/32000        a=rtpmap:105 CN/16000        a=rtpmap:13 CN/8000      // 静音       a=rtpmap:126 telephone-event/8000   视频 m=video 33085 RTP/SAVPF 100 101 102       a=rtpmap:100 VP8/90000       a=rtpmap:101 red/90000       a=rtpmap:102 ulpfec/90000          视频格式     D1 :720 * 480(水平)。480i,隔行扫描。模拟电视水平     D4: 1280*720=921600像素. 720p,逐行扫描。高清,720P(100万像素)    1920*1080=2073600  这是1080p性能测试工具     CPU,内存:linux下比top好用的系统监视器htop      TCP,UDP:iperf for Linux 的安装与使用开发      linux:    #include    ;    -lasound -lm   ;   snd_pcm_open(...)    //alsa free and oss not,播放PCM数据          http://www.233.com/linux/fudao/20100122/091957660.html               linux音频编程,基本概念,系统调用open(/dev/dsp,mix...),read(录制),write(播放),close,ioctl(设置参数)...         http://www.rosoo.net/a/201010/10357.html   linux alsa 录音,播放,实例解析      window :   waveOutWrite(...)    // 传入采样频率, 采样精度,通道数,以及PCM数据后,生成wave后播放


 

2。用svg-editor 实现画图(老师画给学生看)  

1。老师客户端:svg-editor.html 用setinterval实现每2秒用xmlhttprequest发送{roomid, svgStr}到服务器nodejs (控制发送完毕后才能再次发送!!!)
            iframe得到父窗口的数据:roomid
   2。nodejs收到字串后用fs.writeFile保存为文件roomname.svg
   3。学生客户端在图画tab为可见时,每2秒刷新图画所在的iframe: draw.location.reload()

3。用express实现文件上传     1. 客户端
// 此代码直接隐式得将form中的file, post到/file-upload;  或者 用XMLHttpRequest显示的post,并且添加了progress等事件监听
<form method="post" enctype="multipart/form-data" action="/file-upload">
  <input type="file" name="thumbnail">
  <input type="submit">
</form>
 

2. 服务器端用nodejs的expressJS支持实现app.post('/file-upload', function(req, res) {
     // 注意:上传的临时路径为:/tmp/XXXXXXXXX,  文件名为随机字串         var tmp_path = req.files.thumbnail.path;
     var target_path = './xxx/' + req.files.thumbnail.name;
    // 文件重命名,并删除临时文件
    fs.rename(tmp_path, target_path, function(err) {
      if (err) throw err;
      fs.unlink(tmp_path, function() {
         if (err) throw err;
         res.send('File uploaded - ' + req.files.thumbnail.size + ' bytes');     });  });  });

6。将pptx转化为html1. 下载openoffice or libreoffice(ubuntu 12.04自带), jodconvert
2. 在后台运行office,并监听  (将运行命令写成脚本.sh)
3. 调用jodconvert进行文档转换:    java -jar  .../jodconvert...jar   old.pptx   htmldir/new.html
   注意;用chmod修改权限;   生成html文件存放的目录
NPAPI(Netscape Plugin Application Programming Interface,网景插件应用程序接口)GetEntryPoints, Initialize, Shutdownnptypes.h : NPAPI 的变量类型定义npapi.h : NPAPI 定义插件的接口函数说明和常用结构说明npruntime.h : 插件与JavaScript交互的结构说明 npfunctions.h : 调用浏览器的接口函数和结构

 

client widget:

$.fn.wiucsST=function(){

    var s;     // 存储初始化参数

    var methods={

        init:function(p){

            var o = $(this);   // 表示当前文档

            s = $.extend( {

                room: null,

                user:  null

            }, p );

            o.append();

            // s.room.getId() 

        },

        destory:function(){

        }

    }; // methods end

 

    var method = arguments[0];

    if(methods[method]) {

        method = methods[method];

        arguments = Array.prototype.slice.call( arguments, 1);

    } else if( typeof(method) === 'object' || !method ) {

        method =methods.init;

    } else {

        $.error( 'Method ' + method + 'does not exist on jQuery.pluginName' );

        return this;

    }

    return method.apply(this, arguments);

};

原创粉丝点击