﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-庄周梦蝶-随笔分类-node.js</title><link>http://www.blogjava.net/killme2008/category/48752.html</link><description>生活、程序、未来</description><language>zh-cn</language><lastBuildDate>Wed, 10 Dec 2014 16:39:32 GMT</lastBuildDate><pubDate>Wed, 10 Dec 2014 16:39:32 GMT</pubDate><ttl>60</ttl><item><title>Another URL Shortener using NodeJS</title><link>http://www.blogjava.net/killme2008/archive/2012/11/25/391936.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sun, 25 Nov 2012 12:31:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2012/11/25/391936.html</guid><description><![CDATA[It's my weekend project&#8212;&#8212;node-shorten: URL Shortener just like t.cn,goo.gl etc.<br />
<br />
Is is written in&nbsp;<a href="http://nodejs.org/">NodeJS</a>,using <a href="http://expressjs.com/">express.js</a> for MVC framework,and using MySQL for storage and Redis for caching.<br />
<br />
A demo online: <a href="http://fnil.me/">http://fnil.me/</a><br />
<br />
The project is at <a href="https://github.com/killme2008/node-shorten">https://github.com/killme2008/node-shorten</a><br />
<br />
Feel free to modify and use it.Have fun.<img src ="http://www.blogjava.net/killme2008/aggbug/391936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2012-11-25 20:31 <a href="http://www.blogjava.net/killme2008/archive/2012/11/25/391936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Zookeeper的web管理应用</title><link>http://www.blogjava.net/killme2008/archive/2011/06/06/351793.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sun, 05 Jun 2011 17:13:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2011/06/06/351793.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/351793.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2011/06/06/351793.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/351793.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/351793.html</trackback:ping><description><![CDATA[&nbsp; &nbsp; Update: 如果遇到在search不存在的path报段错误，这是node-zookeeper的一个bug，我暂时修复了下并提交了pull request，你可以暂时用我修改的node-zookeeper &nbsp;<a href="https://github.com/killme2008/node-zookeeper">https://github.com/killme2008/node-zookeeper<br /></a><br />&nbsp;&nbsp;&nbsp; 我们已经开始在产品使用<a href="http://zookeeper.apache.org/">zookeeper</a>了，那么维护工具也必然需要，所谓兵马未动，粮草先行。请同事帮忙看过几个开源项目后，并没有特别让人满意的。<br />&nbsp;&nbsp;&nbsp; 我想要的功能比较简单。首先，希望能将zookeeper集群的数据展示为树形结构，跟zookeeper模型保持一致。可以逐步展开每层的节点，每次展开都是延迟加载从zk里取数据，这样不会对zk造成太大压力。其次，除了展示树形结构外，我还希望它能展示每个path的属性和数据，更进一步，如果数据是文本的，我希望它可编辑。当然，因为编辑功能是比较危险的行为，我还希望这个管理工具有个简单的授权验证机制。<br /><br />&nbsp;&nbsp;&nbsp; 最终，我自己写了这么个东西，取名为<a href="https://github.com/killme2008/node-zk-browser">node-zk-browser</a>，基于node.js的<a href="http://expressjs.com/">express.js</a>框架和<a href="https://github.com/yfinkelstein/node-zookeeper">node-zookeeper</a>客户端实现的。我将它放在了github上<br /><br />&nbsp;&nbsp;&nbsp;<a href="https://github.com/killme2008/node-zk-browser"> https://github.com/killme2008/node-zk-browser</a><br /><br />&nbsp;&nbsp;&nbsp; 你可以自己搭建这个小app， npm几乎能帮你搞定大部分工作。界面不美观，实用为主，几张运行时截图<br /><br /><br /><img alt="" src="http://www.blogjava.net/images/blogjava_net/killme2008/zk1.png" height="494" width="531" /><br /><br /><img alt="" src="http://www.blogjava.net/images/blogjava_net/killme2008/zk2.png" height="579" width="618" /><br /><br /><br /><img alt="" src="http://www.blogjava.net/images/blogjava_net/killme2008/zk3.png" height="187" width="639" /><img src ="http://www.blogjava.net/killme2008/aggbug/351793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2011-06-06 01:13 <a href="http://www.blogjava.net/killme2008/archive/2011/06/06/351793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Node.js Undocumented(2)</title><link>http://www.blogjava.net/killme2008/archive/2011/06/04/351744.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 04 Jun 2011 10:09:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2011/06/04/351744.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/351744.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2011/06/04/351744.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/351744.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/351744.html</trackback:ping><description><![CDATA[<br />&nbsp;&nbsp;&nbsp; <a href="http://www.blogjava.net/killme2008/archive/2011/05/31/351368.html">Node.js Undocumented(1)</a><br />&nbsp;&nbsp;&nbsp; <a href="http://www.blogjava.net/killme2008/archive/2011/06/04/351744.html">Node.js Undocumented(2)</a><br /><br />&nbsp;&nbsp;&nbsp; 写这种系列blog，是为了监督自己，不然我估计我不会有动力写完。这一节，我将介绍下Buffer这个module。js本身对文本友好，但是处理二进制数据就不是特别方便，因此node.js提供了Buffer模块来帮助你处理二进制数据，毕竟node.js的定位在网络服务端，不能只对文本协议友好。<br /><br />&nbsp;&nbsp;&nbsp; Buffer模块本身其实没有多少未公开的方法，重要的方法都在文档里提到了，有两个方法稍微值的提下。<br /><br />&nbsp;&nbsp;<strong>&nbsp; Buffer.get(idx)</strong><br /><br />&nbsp;&nbsp;&nbsp; 跟buffer[idx]是一样的，返回的是第idx个字节，返回的结果是数字，如果要转成字符，用String.fromCharCode(code)即可。<br /><br />&nbsp;&nbsp;&nbsp; <strong>Buffer.inspect()</strong><br />&nbsp;&nbsp;&nbsp; 返回Buffer的字符串表示，每个字节用十六进制表示，当你调用console.dir的时候打印的就是这个方法返回的结果。<br /><br />&nbsp;&nbsp;&nbsp; Buffer真正值的一提的是它的内部实现。Buffer在node.js内部的cpp代码对应的是SlowBuffer类（src/node_buffer.cc)，但是两者之间并不是一一对应。<strong>对于创建小于8K的Buffer，其实是从一个pool里slice出来，只有大于8K的Buffer才是每次都new一个SlowBuffer</strong>。查看源码（lib/buffer.js)：<span style="color: #000000;"><br /></span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">Buffer.poolSize&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">8</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1024</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.length&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;Buffer.poolSize)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Big&nbsp;buffer,&nbsp;just&nbsp;alloc&nbsp;one.</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.parent&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;SlowBuffer(</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.length);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.offset&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Small&nbsp;buffer.</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">!</span><span style="color: #000000; ">pool&nbsp;</span><span style="color: #000000; ">||</span><span style="color: #000000; ">&nbsp;pool.length&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;pool.used&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.length)&nbsp;allocPool();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.parent&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;pool;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.offset&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;pool.used;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pool.used&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.length;<br />&nbsp;&nbsp;&nbsp;&nbsp;}</span></div><span style="color: #000000; ">&nbsp; <br /></span><br />&nbsp;&nbsp;&nbsp; 因此，我们可以修改Buffer.poolSize这个&#8220;静态&#8221;变量来改变池的大小<br /><br />&nbsp;&nbsp;&nbsp; <strong>Buffer.poolSize</strong><br />&nbsp;&nbsp;&nbsp; Buffer类创建的池大小，大于此值则每次new一个SlowBuffer，否则从池中slice返回一个Buffer，如果池剩余空间不够，则新创建一个SlowBuffer做为池。下面的例子打印这个值并修改成16K:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">console.log(Buffer.poolSize);<br />Buffer.poolSize</span><span style="color: #000000; ">=</span><span style="color: #000000; ">16</span><span style="color: #000000; ">*</span><span style="color: #000000; ">1024</span><span style="color: #000000; ">;</span></div><br />&nbsp;&nbsp; <strong>SlowBuffer类</strong><br />&nbsp;&nbsp; SlowBuffer类我们可以直接使用的，如果你不想使用Buffer类的话，SlowBuffer类有Buffer模块的所有方法实现，例子如下：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;SlowBuffer</span><span style="color: #000000; ">=</span><span style="color: #000000; ">require('buffer').SlowBuffer<br /></span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;buf</span><span style="color: #000000; ">=</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;SlowBuffer(</span><span style="color: #000000; ">1024</span><span style="color: #000000; ">)<br />buf.write(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">hello</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,'utf</span><span style="color: #000000; ">-</span><span style="color: #000000; ">8</span><span style="color: #000000; ">');<br />console.log(buf.toString('utf</span><span style="color: #000000; ">-</span><span style="color: #000000; ">8</span><span style="color: #000000; ">',</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,</span><span style="color: #000000; ">5</span><span style="color: #000000; ">));<br />console.log(buf[</span><span style="color: #000000; ">0</span><span style="color: #000000; ">]);<br /></span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;sub</span><span style="color: #000000; ">=</span><span style="color: #000000; ">buf.slice(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,</span><span style="color: #000000; ">3</span><span style="color: #000000; ">);<br />console.log(sub.length);</span></div>&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 请注意，SlowBuffer默认不是Global的，需要require buffer模块。<br /><br />&nbsp;&nbsp;&nbsp; <strong>使用建议和性能测试</strong><br /><br />&nbsp;&nbsp;&nbsp; Buffer的这个实现告诉我们，要使用好Buffer类还是有讲究的，每次创建小于8K的Buffer最好大小刚好能被8k整除，这样能充分利用空间；或者每次创建大于8K的Buffer，并充分重用。我们来看一个性能测试，分别循环1000万次创建16K,4096和4097大小的Buffer，看看耗时多少：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">function</span><span style="color: #000000; ">&nbsp;benchmark(size,repeats){<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;total</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;console.log(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">create&nbsp;%d&nbsp;size&nbsp;buffer&nbsp;for&nbsp;%d&nbsp;times</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,size,repeats);<br />&nbsp;&nbsp;&nbsp;&nbsp;console.time(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">times</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">repeats;i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total</span><span style="color: #000000; ">+=</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Buffer(size).length;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;console.timeEnd(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">times</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />}<br /></span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;repeats</span><span style="color: #000000; ">=</span><span style="color: #000000; ">10000000</span><span style="color: #000000; ">;<br /><br />console.log(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">warm&nbsp;up<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br />benchmark(</span><span style="color: #000000; ">1024</span><span style="color: #000000; ">,repeats);<br />console.log(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">start&nbsp;benchmark</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br />benchmark(</span><span style="color: #000000; ">16</span><span style="color: #000000; ">*</span><span style="color: #000000; ">1024</span><span style="color: #000000; ">,repeats);<br />benchmark(</span><span style="color: #000000; ">4096</span><span style="color: #000000; ">,repeats);<br />benchmark(</span><span style="color: #000000; ">4097</span><span style="color: #000000; ">,repeats);<br /></span></div><br />&nbsp;&nbsp;&nbsp; 创建1024的Buffer是为了做warm up。在我机器上的输出：<br />&nbsp;&nbsp;&nbsp;&nbsp; <br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">start&nbsp;benchmark<br />create&nbsp;</span><span style="color: #000000; ">16384</span><span style="color: #000000; ">&nbsp;size&nbsp;buffer&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">10000000</span><span style="color: #000000; ">&nbsp;times<br />times:&nbsp;81973ms<br />create&nbsp;</span><span style="color: #000000; ">4096</span><span style="color: #000000; ">&nbsp;size&nbsp;buffer&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">10000000</span><span style="color: #000000; ">&nbsp;times<br />times:&nbsp;80452ms<br />create&nbsp;</span><span style="color: #000000; ">4097</span><span style="color: #000000; ">&nbsp;size&nbsp;buffer&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">10000000</span><span style="color: #000000; ">&nbsp;times<br />times:&nbsp;138364ms<br /><br /></span></div>&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 创建4096和创建4097大小的Buffer，只差了一个字节，<strong>耗时却相差非常大</strong>，为什么会这样？读者可以自己根据上面的介绍分析下，有兴趣的可以留言。<br />&nbsp;&nbsp;&nbsp; 另外，可以看到创建16K和创建4K大小的Buffer，差距非常小，平均每秒钟都能创建10万个以上的Buffer，这个效率已经足以满足绝大多数网络应用的需求。<br /><img src ="http://www.blogjava.net/killme2008/aggbug/351744.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2011-06-04 18:09 <a href="http://www.blogjava.net/killme2008/archive/2011/06/04/351744.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>node-leveldb的memcached adapter</title><link>http://www.blogjava.net/killme2008/archive/2011/05/31/351447.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 31 May 2011 08:45:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2011/05/31/351447.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/351447.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2011/05/31/351447.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/351447.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/351447.html</trackback:ping><description><![CDATA[&nbsp; &nbsp; <a href="http://code.google.com/p/leveldb/">leveldb</a>是google最近开源的一个实现，但是它仅是个lib，还需要包装才能使用。<a href="https://github.com/creationix/node-leveldb">node-leveldb</a>就是一个用node.js包装leveldb的项目，你可以用javascript访问leveldb。<a href="https://github.com/creationix/node-leveldb">node-leveldb</a>仅提供API，不提供网络接口供外部访问。我fork了个分支，搞了个memcached的adapter，将node-leveldb的API暴露为memcached的文本协议，这样一来你可以直接用现有的memcached client甚至直接telnet上去进行测试。感兴趣的朋友可以测试下。adpater就一个文件<a href="https://github.com/killme2008/node-leveldb/blob/master/memcached-adapter/memcached.js">memcached.js</a>。<br />&nbsp; &nbsp;&nbsp;<br />&nbsp; &nbsp; fork的分支在：<br />&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://github.com/killme2008/node-leveldb" title="https://github.com/killme2008/node-leveldb">https://github.com/killme2008/node-leveldb<br /><br /></a>&nbsp;&nbsp;&nbsp;&nbsp;编译node-leveldb之后，执行<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">node&nbsp;memcached</span><span style="color: #000000; ">-</span><span style="color: #000000; ">adpater</span><span style="color: #000000; ">/</span><span style="color: #000000; ">memcached.js</span></div><br />&nbsp; &nbsp; 即可启动memcached adapter在11211端口，你可以telnet上去测试。目前仅支持get/set/delete/quit协议，不支持flag和exptime。<br /><img src ="http://www.blogjava.net/killme2008/aggbug/351447.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2011-05-31 16:45 <a href="http://www.blogjava.net/killme2008/archive/2011/05/31/351447.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Node.js Undocumented(1)</title><link>http://www.blogjava.net/killme2008/archive/2011/05/31/351368.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 30 May 2011 16:33:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2011/05/31/351368.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/351368.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2011/05/31/351368.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/351368.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/351368.html</trackback:ping><description><![CDATA[<a href="http://nodejs.org/"><br />&nbsp;&nbsp;&nbsp; node.js</a>的API文档做的不是很好，有些部分干脆没文档，最终还是要看代码才能解决。我这里将记录下看源码过程中看到的一些API并补充一些测试例子。在玩<a href="http://nodejs.org/">node.js</a>的朋友可以瞧瞧。<br /><br /><br />&nbsp;&nbsp;&nbsp; <strong>process.reallyExit(status)</strong><br /><br />&nbsp;&nbsp;&nbsp; 用于进程主动退出，status设置退出的状态码。请注意，reallyExit退出的进程不会调用'exit'事件，下面的代码不会有任何输出：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;interval</span><span style="color: #000000; ">=</span><span style="color: #000000; ">setInterval(</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;process.reallyExit(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">);<br />},</span><span style="color: #000000; ">1000</span><span style="color: #000000; ">);<br />process.on('exit',</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;console.log(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">hello</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />});</span></div><br />&nbsp;&nbsp; <strong>process._kill(pid,sig)</strong><br /><br />&nbsp;&nbsp; 用于给指定pid的进程发送指定信号（类似kill命令），这是个&#8220;private&#8221;方法，你需要慎重使用，下面的代码会杀死自身的进程：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;pid</span><span style="color: #000000; ">=</span><span style="color: #000000; ">process.pid<br />process._kill(pid,</span><span style="color: #000000; ">9</span><span style="color: #000000; ">);</span></div><br />&nbsp;&nbsp; <strong>process.binding(name)</strong><br /><br />&nbsp;&nbsp; 非常有用的方法，很奇怪API文档里竟然没提到，这个方法用于返回指定名称的内置模块。例如下面的代码将打印node_net模块所有的可以调用的方法或变量（很多是文档没有提到的并且没有exports的，后续我会介绍下）：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">var</span><span style="color: #000000; "> binding</span><span style="color: #000000; ">=</span><span style="color: #000000; ">process.binding('net');<br />console.dir(binding);</span></div><strong><br />&nbsp;&nbsp; process.dlopen(filename,target)</strong><br />&nbsp;&nbsp; 看源码注释说是用来动态加载node.module的动态链接库的，以后尝试写扩展的时候也许可以尝试一下。<br /><br />&nbsp;&nbsp; <strong>定时器</strong><br />&nbsp;&nbsp; Node.js的定时器模块的实现是有讲究的，对于超时时间after&lt;=0的callback，会在内部new一个Timer并start（本质是使用libev的timer机制）；但是对于after&gt;0的callback，却不是这样。因为在实际应用中，大多数定时器事件的超时时间都是一样的，如果每个事件都new一个Timer并start，代价太高。因此node.js采用了一个类似哈希表的方案，将相同after超时时间的定时器事件组织成链表，以after为key，以链表为value整体构成一张表。每个链表只new一个Timer,这个Timer负责整个链表的定时器事件，当某个事件超时调用后，利用ev_timer_again来高效地重新设置超时时间。<br />&nbsp;&nbsp; 如果你确实希望对于after&gt;0的定时器也每次new一个Timer来处理，那也可以做到，这就要用到前面提到的process.binding方法来获取timer模块,一个例子：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;Timer&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;process.binding('timer').Timer;<br /><br /></span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;timer</span><span style="color: #000000; ">=</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Timer();<br />timer.callback</span><span style="color: #000000; ">=</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(){<br />&nbsp;&nbsp;&nbsp;&nbsp;console.log(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">callback&nbsp;called</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />};<br />timer.start(</span><span style="color: #000000; ">1000</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);</span></div>&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; <strong>timer.callback</strong><br />&nbsp;&nbsp;&nbsp; 设定timer的回调函数，当超时的时候调用。<br /><br />&nbsp;&nbsp;&nbsp; <strong>timer.start(after,repeat)</strong><br />&nbsp;&nbsp;&nbsp; 启动定时器，在after毫秒之后调用超时回调；如果repeat==0，则自动停止定时器；如果repeat&gt;0，则在repeat毫秒之后再次调用callback，以repeat毫秒为间隔不断重复下去。<br /><br />&nbsp;&nbsp;&nbsp; ps.这篇blog刚好是我的第499篇blog，不出意外，第500篇还是继续介绍node.js。<br />&nbsp;&nbsp;&nbsp;<img src ="http://www.blogjava.net/killme2008/aggbug/351368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2011-05-31 00:33 <a href="http://www.blogjava.net/killme2008/archive/2011/05/31/351368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>