<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_moonz-wu</title><subtitle type="text">获得人生中的成功需要的专注与坚持不懈多过天才与机会|机会永远是给有准备的人|事业是需要一生时间去经营</subtitle><id>http://feed.cnblogs.com/blog/u/20427/rss</id><updated>2012-05-15T04:09:04Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/20427/rss"/><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/05/15/2501301.html</id><title type="text">git的小技巧</title><summary type="text">git做为分布式版本管理工具，功能很强大。 其中一点，你可以让任意一个local repository变成server。只要做以下几个步骤即可实现：1. 在项目目录下面的.git/文件夹下创建一个git-daemon-export-ok的空文件2. 运行git daemon在远端机器上通过git clone git://localhost/project_path就可以pull代码了。</summary><published>2012-05-15T04:09:00Z</published><updated>2012-05-15T04:09:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/05/15/2501301.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/05/15/2501301.html"/><content type="html">&lt;p&gt;git做为分布式版本管理工具，功能很强大。 其中一点，你可以让任意一个local repository变成server。只要做以下几个步骤即可实现：&lt;/p&gt;&lt;p class="p2"&gt;1. &lt;span class="s2"&gt;在&lt;/span&gt;&lt;span class="s1"&gt;项目&lt;/span&gt;&lt;span class="s2"&gt;目&lt;/span&gt;&lt;span class="s1"&gt;录&lt;/span&gt;&lt;span class="s2"&gt;下面的&lt;/span&gt;.git/&lt;span class="s2"&gt;文件夹下&lt;/span&gt;&lt;span class="s1"&gt;创建&lt;/span&gt;&lt;span class="s2"&gt;一个&lt;/span&gt;git-daemon-export-ok&lt;span class="s2"&gt;的空文件&lt;/span&gt;&lt;/p&gt;&lt;p class="p2"&gt;2. &lt;span class="s1"&gt;运行&lt;/span&gt;git daemon&lt;/p&gt;&lt;p class="p3"&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="p1"&gt;在&lt;span class="s1"&gt;远端&lt;/span&gt;机器上通&lt;span class="s1"&gt;过&lt;/span&gt;git clone git://localhost/project_path就可以pull代码了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2501301.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/05/15/2501301.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/02/20/2170393.html</id><title type="text">对于结对编程的感悟</title><summary type="text">人说凡是美好的东西都有不美好的一面-结对编程作为极限编程的一个实践，它的好处是很明显的。但是在这里我想更客观的去看待这个实践，结对编程给我们带来了什么？1. 结对让你增加了交流，两个开发者必须不停的对一个问题进行探讨，才能写代码，这有助于知识的传递和方案的统一。2. 减少了一些不必要的失误，比如写错字母，忘记定义等等3. 经验的交流，两个开发者可以相互交流一下经验。4. 最重要的一点就是知识的传承。结对有利于减少项目中的知识孤岛。同时结对编程也给我们带来了这样的问题：1. 成本的增加，人/产品。（我想不承认这点的人很多）2. 对于那些性格差异比较大（一个很强势，一个很弱势）的人在一起结对，很有</summary><published>2012-02-20T15:54:00Z</published><updated>2012-02-20T15:54:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/20/2170393.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/20/2170393.html"/><content type="html">&lt;p&gt;人说凡是美好的东西都有不美好的一面-结对编程作为极限编程的一个实践，它的好处是很明显的。但是在这里我想更客观的去看待这个实践，结对编程给我们带来了什么？&lt;/p&gt;&lt;p&gt;1. 结对让你增加了交流，两个开发者必须不停的对一个问题进行探讨，才能写代码，这有助于知识的传递和方案的统一。&lt;/p&gt;&lt;p&gt;2. 减少了一些不必要的失误，比如写错字母，忘记定义等等&lt;/p&gt;&lt;p&gt;3. 经验的交流，两个开发者可以相互交流一下经验。&lt;/p&gt;&lt;p&gt;4. 最重要的一点就是知识的传承。结对有利于减少项目中的知识孤岛。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;同时结对编程也给我们带来了这样的问题：&lt;/p&gt;&lt;p&gt;1. 成本的增加，人/产品。（我想不承认这点的人很多）&lt;/p&gt;&lt;p&gt;2. 对于那些性格差异比较大（一个很强势，一个很弱势）的人在一起结对，很有可能是一个单挑的活，而且对另外一个弱势的人无疑是一个种打击。&lt;/p&gt;&lt;p&gt;3. 结对会产生依赖心理，和抱怨心理（这个问题需要两人很好的沟通和态度才能解决）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;总的来说，结对编程对项目是有益的，这个益处是长期的。这是软件开发方式的一种新的尝试（它不是银弹），你也可以选择不结对，因为至少我们单独编码的历史已经有好几十年了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2170393.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/02/20/2170393.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/02/16/2342113.html</id><title type="text">我们将生活在云上-云端开发，云端部署</title><summary type="text">相信云这个概念对于专业的开发人员来说已经不是什么新名词了。这年头搞个应用不与云沾点边都拿不出手。最近在研究node.js，我在想既然node.js能将javascript作为服务器端语言来用，那么只要将js脚本提交到云上是不是就可以直接运行了呢? 答案是可以的，来看看Cloud9吧！一个node.js的在线IDE，实现云端开发和云端部署不是梦。作为一个入门级的介绍文章，我还是从hello world开始。但在我们写代码之前，我们先来看看这个云端IDE的样子：怎么样,是不是很酷！酷的不仅仅是这些，它支持把代码直接push到Github和Bitbucket， 还支持直接deploy你的app到he</summary><published>2012-02-16T15:05:00Z</published><updated>2012-02-16T15:05:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/16/2342113.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/16/2342113.html"/><content type="html">&lt;p&gt;相信云这个概念对于专业的开发人员来说已经不是什么新名词了。这年头搞个应用不与云沾点边都拿不出手。最近在研究node.js，我在想既然node.js能将javascript作为服务器端语言来用，那么只要将js脚本提交到云上是不是就可以直接运行了呢? 答案是可以的，来看看Cloud9吧！一个node.js的在线IDE，实现云端开发和云端部署不是梦。作为一个入门级的介绍文章，我还是从hello world开始。但在我们写代码之前，我们先来看看这个云端IDE的样子：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012020723472831.png" alt="" width="800" height="400" /&gt;&lt;/p&gt;&lt;p&gt;怎么样,是不是很酷！酷的不仅仅是这些，它支持把代码直接push到Github和Bitbucket， 还支持直接deploy你的app到heroku,joyent和window azure云上。&lt;/p&gt;&lt;p&gt;下面的步骤告诉你如何实施一次云端开发和部署：&lt;/p&gt;&lt;p&gt;1. 你需要至少3个帐号:Cloud9, Github/Bitbucket, Heroku/Joyent/Azure。我个人建议是Cloud9, Github, Heroku组合，因为都是免费的。注册的事情我想就不需要多说了，不过有一点是建议都用一样的用户名和密码，这样不容易忘记^_^!&lt;/p&gt;&lt;p&gt;2. 登录到Cloud9，并激活Github/Bitbucket&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012020723554118.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;3. 创建一个在线工程，你可以选择新建一个或是从Git/Bit上clone一个（我相信用过Git或Hg的朋友们都知道）。&lt;/p&gt;&lt;p&gt;4. 打开这个工程，如果你第一次用的话可以看一下Cloud9的演示程序（我觉得蛮不错的）&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012020800022979.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;你可以右键工程文件夹来新建一个文件（提示：IDE有一个bug就是演示完的文件，你修改了是保存不了的，所以建议你新建一个文件，然后把原来的那个删除）。之后，请贴入如下代码：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; http = require('http');&lt;br /&gt;http.createServer(&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;(req, res) {&lt;br /&gt;    res.writeHead(200, {'Content-Type': 'text/plain'});&lt;br /&gt;    res.end('hello cloud9');&lt;br /&gt;}).listen(&lt;span style="color: #ff0000;"&gt;process.env.PORT&lt;/span&gt;);&lt;br /&gt;console.log('server is running on port : ' + process.env.PORT );&lt;/div&gt;&lt;p&gt;代码的含义我就不解释了，不懂的朋友可以去nodejs.org上看看先。唯一需要注意的是红色部分，在云端开发最重要的一个是端口的问题。Cloud9提供了自己的测试环境端口process.env.C9_PORT，但是这个端口在heroku上是不能工作的，这个后面会说。完了你可以在ruan那个地方去debug一下看看效果。（这里我不得不说一下，我们国家的网络真是......唉！！！啥也不说了，有vpn的用vpn，有ssh的用ssh, 没有的用代理）。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012020800204628.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;然后你访问你得到的网址看看输出结果。（这一步有可能会失败，如果你代码没有错，那么就是网络的原因）&lt;br /&gt;5. 如果以上的程序测试没有问题，那么我们下一步就准备将它部署到云上去了。请猛击Deploy按钮，在出现的Tab页面中点击右上角的+号&lt;/p&gt;&lt;p&gt;(&lt;/p&gt;&lt;p&gt;不过在此之前还需要将我们已有的代码提交到github上面，&lt;/p&gt;&lt;p&gt;&amp;gt; git add .&lt;/p&gt;&lt;p&gt;&amp;gt; git commit -m "init"&lt;/p&gt;&lt;p&gt;因为heroku是从github上去拽代码的）&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012021523531642.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;对于现在的cloud9来说它只支持3个云服务，heroku,joyent和Azure。每个云服务都有各自不同的配置文件，这里选择heroku来举例（因为它是免费的哦，请先注册一个）。对于heroku的云服务来说，配置还是比较简单的。只需要一个Procfile的文件（自己手动创建一个）即可，我们只需要在里面添加这样一行代码&lt;/p&gt;&lt;p&gt;web: node &lt;span style="color: #ff0000;"&gt;hello_tmpl&lt;/span&gt;.js&lt;/p&gt;&lt;p&gt;这个文件主要是告诉heroku在启动你的应用程序时，需要如何加载或执行你的文件。另外如果你用到了除nodejs核心库以外的模块，这里还需要用到一个package.json来告诉heroku帮你加载指定的模块。将所有依赖的模块都记录到这个文件中。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012021622520694.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;如果一切正常，最终我们登录到heroku网站后，可以在账户里看到自己创建的应用程序。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012021622594650.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;这样就可以通过url：&amp;nbsp;&lt;a href="http://hello-ace-com.herokuapp.com/"&gt;http://hello-ace-com.herokuapp.com/&lt;/a&gt;&amp;nbsp;来访问创建的应用程序了。&lt;/p&gt;&lt;p&gt;到此，基本的云端开发与云端部署流程已经结束。如果在运行应用程序时出现问题，可以通过heroku的客户端程序来查看log等内容（&lt;a href="http://devcenter.heroku.com/articles/node-js"&gt;点击这里看看&lt;/a&gt;）。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2342113.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/02/16/2342113.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html</id><title type="text">图模式的NoSQL数据库:Neo4j</title><summary type="text">Neo4J是什么？1. 一个高性能的图关系模型数据库2. 一个NoSQL的数据库3. 支持多种编程语言4. Neo4J擅长处理具有多关系的模型数据Neo4J中怎么删除与某个节点有关系的节点？1. 查找到目标节点所有关系2. 开启一个事务，删除所有关系的start node或end node3. 遍历所有找到的node并删除相关的RelationShip4. 然后删除node本身，提交事务 1 public static void DeleteRelativeNode(Node n) { 2 TraversalDescription td = Traversal.descript...</summary><published>2012-02-05T14:17:00Z</published><updated>2012-02-05T14:17:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html"/><content type="html">&lt;p&gt;&lt;span&gt;Neo4J是什么？&lt;/span&gt;&lt;/p&gt;&lt;div&gt;1. 一个高性能的图关系模型数据库&lt;/div&gt;&lt;div&gt;2. 一个NoSQL的数据库&lt;/div&gt;&lt;div&gt;3. 支持多种编程语言&lt;/div&gt;&lt;div&gt;4. Neo4J擅长处理具有多关系的模型数据&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Neo4J中怎么删除与某个节点有关系的节点？&lt;/div&gt;&lt;div&gt;1. 查找到目标节点所有关系&lt;/div&gt;&lt;div&gt;2. 开启一个事务，删除所有关系的start node或end node&lt;/div&gt;&lt;div&gt;3. 遍历所有找到的node并删除相关的RelationShip&lt;/div&gt;&lt;div&gt;4. 然后删除node本身，提交事务&lt;/div&gt;&lt;div&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; DeleteRelativeNode(Node n) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;         TraversalDescription td = Traversal.description().relationships(Types.Relative, Direction.BOTH)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;                 .evaluator(Evaluators.excludeStartPosition());&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         Traverser t = td.traverse(n);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;(Node tn : t.nodes()) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt;             Iterable&amp;lt;Relationship&amp;gt; relationships = tn.getRelationships();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (Relationship r : relationships) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (r.getStartNode().equals(n) || r.getEndNode().equals(n)) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;                     r.delete();&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;                 }&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             }&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!tn.hasRelationship()) {&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;                 tn.delete();&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             }&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;     }&lt;/div&gt;在Neo4j中删除节点的本身有一个条件，就是这个节点没有任何的关系存在。&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2339346.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html</id><title type="text">欲善其功，必先利其器--Nodejs调试技术总结</title><summary type="text">调试技术与开发技术构成了软件开发的基石。目前Nodejs作为新型的Web Server开发栈倍受开发者关注。总的来说Nodejs的应用程序主要有两部分：JavaScript编写的js模块和C语言编译的二进制模块。这里主要介绍三种avaScript模块的调试方法：基于Nodejs内建的调试器，基于V8调试插件和基于Chrome浏览器的调试器。以下所有的操作都将基于如下代码（example.js）：var http = require('http');var url = require('url');http.createServer(function (req, </summary><published>2012-01-15T13:35:00Z</published><updated>2012-01-15T13:35:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html"/><content type="html">&lt;p&gt;调试技术与开发技术构成了软件开发的基石。目前Nodejs作为新型的Web Server开发栈倍受开发者关注。总的来说Nodejs的应用程序主要有两部分：JavaScript编写的js模块和C语言编译的二进制模块。这里主要介绍三种avaScript模块的调试方法：基于Nodejs内建的调试器，基于V8调试插件和基于Chrome浏览器的调试器。以下所有的操作都将基于如下代码（example.js）：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; http = require('http');&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; url = require('url');&lt;br /&gt;http.createServer(&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; (req, res) {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; path = url.parse(req.url).pathname;&lt;br /&gt;        res.writeHead(200, {'Content-Type': 'text/plain'});&lt;br /&gt;        res.end(path);&lt;br /&gt;}).listen(1337, "127.0.0.1");&lt;br /&gt;console.log('Server running at http://127.0.0.1:1337/');&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1. 基于Nodejs内建的调试器&lt;/p&gt;&lt;p&gt;Nodejs提供了一个内建调试器来帮助开发者调试应用程序。想要开启调试器我们需要在代码中加入debugger标签，当Nodejs执行到debugger标签时会自动暂停（debugger标签相当于在代码中开启一个断点）。代码如下：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; path = url.parse(req.url).pathname;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #0000ff;"&gt;debugger&lt;/span&gt;;&lt;/strong&gt;&lt;br /&gt;res.writeHead(200, {'Content-Type': 'text/plain'});&lt;/div&gt;&lt;p&gt;执行命令：node debug example.js 就可以进入调试模式。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012011500104217.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;在debug模式下，可以使用内建命令如repl去评估变量和表达式的值（如2所示）。我们也可以通过help命令来获取完整的调试命令列表。&lt;/p&gt;&lt;p&gt;Commands: run (r), cont (c), next (n), step (s), out (o), backtrace (bt), setBreakpoint (sb), clearBreakpoint (cb),&lt;br /&gt;watch, unwatch, watchers, repl, restart, kill, list, scripts, breakpoints, version&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2. 基于V8插件的调试器&lt;br /&gt;Nodejs是基于google V8的引擎上构建的，Google为Eclipse提供了一个对应的调试插件。关于如何在Eclipse中安装和调试Nodejs程序就不再重复描述了，网上已经有很多的文章了（具体可以参考这篇文章http://cnodejs.org/blog/?p=911）。唯一要注意的是在默认情况下V8引擎支持的调试模式是本地模式。如果想要开启远程调试的话，我们需要修改Nodejs中的V8源文件：/deps/v8/src/platform-posix.cc&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;  addr.sin_family = AF_INET;&lt;br /&gt;  addr.sin_addr.s_addr = htonl(&lt;span style="color: #ff0000;"&gt;INADDR_LOOPBACK&lt;/span&gt;); --&amp;gt; &lt;span style="color: #ff0000;"&gt;INADDR_ANY&lt;/span&gt;&lt;br /&gt;  addr.sin_port = htons(port);&lt;/div&gt;&lt;p&gt;然后重新编译Nodejs。&lt;/p&gt;&lt;p&gt;提示：&lt;/p&gt;&lt;p&gt;用插件来调试nodejs程序，你有时候会遇到什么connect refuse, get version failed等等错误。那么请注意你使用的ip的地址， 一般下127.0.0.1的回环地址是都工作的。如果你使用真实的ip地址，请检查防火墙设置。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3. 基于Chrome浏览器的调试器&lt;/p&gt;&lt;p&gt;既然我们可以通过V8的调试插件来调试，那是否也可以借用Chrome浏览器的JavaScript调试器来调试呢？node-inspector模块提供了这样一种可能。我们需要先通过npm来安装node-inspector&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;npm install -g node-inspector &amp;nbsp;// -g 导入安装路径到环境变量&lt;/div&gt;&lt;p&gt;node-inspector是通过websocket方式来转向debug输入输出的。因此，我们在调试前要先启动node-inspector来监听Nodejs的debug调试端口。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012011521054045.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;默认情况下node-inspector的端口是8080，可以通过参数--web-port=[port]来设置端口。在启动node-inpspector之后，我们可以通过--debug或--debug-brk来启动nodejs程序。通过在浏览器输入http://[ip address]:8080/debug?port=5858，我们会得到如下的调试窗口：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012011521141853.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;这三种方法各自有优缺点，我个人比较欣赏node-inspector的方式。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2322120.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html</id><title type="text">TDD中的一些问题</title><summary type="text">1. 我需要去测试get/set方法吗？这个问题一直是TDD中比较典型的一个问题。有两个观点，一个是不需要测试，因为get/set代码很简单，测试没有什么意义，除非是有特别的逻辑在里面。另一个观点是需要测，否则你的TDD就有缺陷。对于这个问题，我个人觉得需要这样看，第一，你提供get/set方法用途是什么，第二是你要怎么去测试它们。如果你的测试代码是这么写的：@Testpublic void testGetSetX() { setX(23); assertEquals(23, getX());}或者@Testpublic void testGetSetX() { x = 23...</summary><published>2012-01-08T03:56:00Z</published><updated>2012-01-08T03:56:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html"/><content type="html">&lt;p&gt;1. 我需要去测试get/set方法吗？&lt;/p&gt;&lt;p&gt;这个问题一直是TDD中比较典型的一个问题。有两个观点，一个是不需要测试，因为get/set代码很简单，测试没有什么意义，除非是有特别的逻辑在里面。另一个观点是需要测，否则你的TDD就有缺陷。对于这个问题，我个人觉得需要这样看，第一，你提供get/set方法用途是什么，第二是你要怎么去测试它们。如果你的测试代码是这么写的：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;@Test&lt;br/&gt;public void testGetSetX() {&lt;br/&gt;    setX(23);&lt;br/&gt;    assertEquals(23, getX());&lt;br/&gt;}&lt;br/&gt;或者&lt;br/&gt;@Test&lt;br/&gt;public void testGetSetX() {&lt;br/&gt;    x = 23;&lt;br/&gt;    assertEquals(23, x);&lt;br/&gt;}&lt;br/&gt;或者&lt;br/&gt;@Test&lt;br/&gt;public void testGetSetX() {&lt;br/&gt;    assertEquals(23, 23);&lt;br/&gt;}&lt;br/&gt;&lt;/div&gt;&lt;p&gt;那么我觉得没有必要写这样的测试代码，因为这不是在测你自己的代码，而是在验证Java的编译器。但，如果是这样的代码&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;@Test&lt;br/&gt;public void testCreate() {&lt;br/&gt;    assertEquals(23, new MyClass(23).getX());&lt;br/&gt;}&lt;br/&gt;&lt;/div&gt;&lt;p&gt;那么显然是有意义的，通常我们可以验证带参数的构造函数是否正确工作。 而对于set来说也是一样，&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;@Test&lt;br/&gt;public void testPrintMessage() {&lt;br/&gt;    MyClass mc = new MyClass();&lt;br/&gt;    mc.setX(23);&lt;br/&gt;    assertEquals("the x is 23", mc.printMessage());&lt;br/&gt;}&lt;/div&gt;&lt;p&gt;这同时引出第二个问题&lt;/p&gt;&lt;p&gt;2. 什么才是真正意义上的TDD? TDD的T是test, D是driven, D是design. 这里test可以有多种解释: 单元测试, 业务逻辑测试,功能测试. 但我认为单元测试是比较符合含义的. 那么什么是单元测试? 很多人都不是真正的清楚. 就上面说的例子来看我可以为每一个函数添加测试, 那这样就是单元测试了吗? 不, 这不是单元测试. 这里指的单元是功能单元,而不是实现单元.一个类的每一个函数都可以称之为一个实现单元, 但一个实现单元并不一定是一个功能单元. 只有这个实现单元在业务逻辑上有单独的意义时,它才可称为功能单元(就上面的例子来说创建一个业务对象是一个功能单元), 也只有构建用于功能单元的测试才能称为单元测试. 之所以要以功能单元为最小测试单位是因为通常来说在软件开发过程中业务逻辑的变化频率要远少于实现逻辑的变化频率. 如果我们的测试构建于实现逻辑之上, 那么测试与实现是紧耦合的,我们就很难对实现进行重构或者优化(在项目的开发后期往往会陷入牵一发而动全身的情况). 而构建于功能单元之上的测试则不会有这样的缺陷.&lt;/p&gt;&lt;p&gt;3. 什么是Mock, Fake, Dummy? 在开发单元测试过程中,我们经常会听到Mock, Fake, Dummy的字样. 不过我想很少人会去注意它们之间的区别. 从字面意义上讲都是"假的"意思, 那么区别是什么? 首先是Mock, mock的含义是替换实现, 并加以验证. mock的通常的做法是构建一个伪接口来代替真实接口, 当程序调用到该接口时返回一个预置的对象(可以是真对象也可以是假对象). 最关键是我们要去验证该接口是否真的被调用. 所以我们通常可以看到一个verify操作在单元测试最后. Fake的含义是伪对象,就是构建一个假的对象来替换真实对象, Fake更倾向于数据实体. Dummy的含义是哑对象. 哑对象就是无意义的对象, 诸如null或是new object(对业务无价值的对象). 只起到一个占位的作用,而没有什么具体含义. 这里有篇文章很全面的阐释&lt;a href="http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html"&gt;相关的内容&lt;/a&gt;&lt;/p&gt;&lt;p&gt;总结一下,tdd是一个agile实践里面很重要的一个实践. 充分理解tdd的含义和目的将有助于更好的执行agile过程.&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2102388.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html</id><title type="text">参加hello radar回来</title><summary type="text">公司为了扩大大家的技术知识面，同时也对radar上的新技术进行一些探索，因此开始了hello radar系列session，这期的主题是nodejs。其实我在之前已经写过一些关于nodejs的文章。这回也算是总结一下这阶段的探索经历。nodejs无疑是目前互联网开发方面最热门的技术之一。究其原因一是其能够支持超高的并发连接（单服务器能做到&gt;8000的并发量）,二是使用事件异步编程模式,三是采用了javascript作为服务器端编程语言. 这三个方面也正是目前大多数主流框架正在解决但未解决好的.对于目前的web服务器来说, 单服务器的连接并发量能到3000~5000已经非常不错了. 但这样</summary><published>2012-01-07T15:24:00Z</published><updated>2012-01-07T15:24:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html"/><content type="html">&lt;p&gt;公司为了扩大大家的技术知识面，同时也对radar上的新技术进行一些探索，因此开始了hello radar系列session，这期的主题是nodejs。其实我在之前已经写过一些关于nodejs的文章。这回也算是总结一下这阶段的探索经历。&lt;/p&gt;&lt;p&gt;nodejs无疑是目前互联网开发方面最热门的技术之一。究其原因一是其能够支持超高的并发连接（单服务器能做到&amp;gt;8000的并发量）,二是使用事件异步编程模式,三是采用了javascript作为服务器端编程语言. 这三个方面也正是目前大多数主流框架正在解决但未解决好的.对于目前的web服务器来说, 单服务器的连接并发量能到3000~5000已经非常不错了. 但这样的并发量对于当前具有海量用户的大型网站来说还是非常的少. 主要的原因是大多数web服务器对每一个request请求要么使用一个线程要么使用一个进程来处理,这也就是说在这个request返回之前线程或进程占用的资源是不会释放的.以每个线程占用2m的内存来说, 5000个并发就需要10g的内存(很恐怖吧). 我们来看一下nodejs是怎么解决这一问题的? 我们都知道nodejs是一个单线程单进程的服务器, 它对于request的请求并不使用线程去处理, 而采用了注册回调的方式. 也就是说对于request请求并不等到整个处理结束就释放连接去服务另一个请求.而处理过程被委托到后台线程(这里的线程与rquest的线程是不同的)中执行, 直到之前的处理结束再将数据发送回客户端.这样nodejs服务器就可以处理大量的并发连接.另外由于js天生对事件模型的支持并且拥有广大的开发群体, Ryan很自然就选择js作为nodejs的开发语言.&lt;/p&gt;&lt;p&gt;那么我们说任何的新技术都不能可能解决所有的问题,nodejs也一样. 假设我们现在有10000个并发请求, 每一个请求需要10s去完成.那么根据nodejs的机制,我们大概可以知道每秒钟需要返回10000块数据回客户端, 如果每块数据100k, 那么传输的数据量就达到1g, 并且会有90000个请求等待返回. 这时候网络的I/O就成为了服务器的瓶颈.从这里可以看出nodejs并不适合处理这样的情况. 根据Ryan自己描述每个request请求处理不超过5ms会有较好的性能.具体的文章可以看&lt;a href="http://four.livejournal.com/963421.html"&gt;这里&lt;/a&gt;.那么什么样的应用符合这样的要求呢? 我认为微博, 聊天室和某些mobile应用是适合的.&lt;/p&gt;&lt;p&gt;作为完整的开发栈, nodejs提供了良好的包管理程序npm (node package management), 还有版本管理程序nvm (nodejs version management). nodejs的发展速度是惊人的,到目前为止已经有6000+的模块被开发出来, 这也是nodejs的一大特色. 关于npm可以看&lt;a href="http://npmjs.org/"&gt;这里&lt;/a&gt;. 关于nvm可以看&lt;a href="https://github.com/creationix/nvm"&gt;这里&lt;/a&gt;. 同样api文档对于开发者来说也是极其重要的, nodejs.org也提供了比较完善的&lt;a href="http://nodejs.org/docs/latest/api/index.html"&gt;api文档&lt;/a&gt;.对于任何程序来说,调试永远是必须的.nodejs是基于google的v8引擎实现的,那么我们同样可以使用eclipse的v8调试插件来实现对nodejs的调试.关于如何调试nodejs可以看&lt;a href="https://github.com/joyent/node/wiki/Using-Eclipse-as-Node-Applications-Debugger"&gt;这里&lt;/a&gt;&lt;/p&gt;&lt;p&gt;nodejs是一项新技术,尽管其发展的很快,给我们带来了很多新的开发理念. 但还有些领域处于摸索阶段, 一个是如何测试nodejs程序,特别是单元测试; 二是持续构建的框架.对于一个完整的项目来说测试和持续构建是重要的两个环节.&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2316008.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html</id><title type="text">时间匆匆，又到回顾时 - 2011年的最后一小时</title><summary type="text">很快再过几分钟就是2012了，这个传说中的世界末年就在眼前；当然那只不是人们的臆想罢了，太阳在2012照常的会东升西落，人们也会照常的工作和生活。那么在这样的时间点上，我想每个人都应该仔细的思考和总结一下2011年里的得失。在翻看自己2011年的博客时，我发现今年的博客比去年少写了，而且关于技术探讨的没有以前那么多了。在查看一下未发表的博客，原来这些兄弟们都在这里，还真是对不住这些兄弟们。没关系，我会在2012年里把你们都show出来的。闭上眼睛，仔细回顾2011年所发生的人和事。原来变化还是很大的，工作，家庭和生活都发生了变化，尽管这种变化并没有在今年里完成，但是给我带来了期许，我希望这些新</summary><published>2011-12-31T16:07:00Z</published><updated>2011-12-31T16:07:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html"/><content type="html">&lt;p&gt;很快再过几分钟就是2012了，这个传说中的世界末年就在眼前；当然那只不是人们的臆想罢了，太阳在2012照常的会东升西落，人们也会照常的工作和生活。那么在这样的时间点上，我想每个人都应该仔细的思考和总结一下2011年里的得失。在翻看自己2011年的博客时，我发现今年的博客比去年少写了，而且关于技术探讨的没有以前那么多了。在查看一下未发表的博客，原来这些兄弟们都在这里，还真是对不住这些兄弟们。没关系，我会在2012年里把你们都show出来的。&lt;/p&gt;&lt;p&gt;闭上眼睛，仔细回顾2011年所发生的人和事。原来变化还是很大的，工作，家庭和生活都发生了变化，尽管这种变化并没有在今年里完成，但是给我带来了期许，我希望这些新的变化能在新的一年里一一完结，而我的人生也将开启一个新的篇章。作为一个技术工作者，今年的回顾还是从技术开始吧！&lt;/p&gt;&lt;p&gt;从技术上，我从企业级的开发逐渐的转向了互联网开发，其中还有一些移动互联网的技术；从传统的c/c++转向Java/C#，进而向Javascript等脚本语言前进。工作平台也从windows扩展到了android。我希望这种转变能对我的技术能力有所改变，以适应行业新的发展趋势。2011年的技术要点是移动互联网，这个名词随着android和ios被揣到了大多数人的口袋里。2012年的主题依然还是移动互联网，但是会有所变化那就是与云计算的结合会更紧密，同时开发门槛会进一步提高。而对于我来说，我希望新的一年里能在android平台和互联网技术上更进一步。行业的另一个方向是方法论和新思想，从TDD到BDD到DDD，敏捷开发还是不二的主题，国内的IT公司在这方面依然相对落后。不过我想敏捷的13个实践或多或少会改变国内公司目前的业务流程和产品质量。而对于我来说，在新的一年里我希望能掌握其中3个实践：CI、重构与持续反馈。&lt;/p&gt;&lt;p&gt;从生活上，2011年做了很多的铺垫，这些铺垫有些是之前计划了的，有些是意外的。但是也正是因为这些的铺垫，所以我对2012年有很大的憧憬。2012年对于我来说将会是一个忙碌的一年。&lt;/p&gt;&lt;p&gt;从思想上，这一年经历了很多斗争，有决绝，有彷徨，有失落也有激动。正是这些复杂的情绪和社会的各种影响，使的我思想上发生了变化。尽管有些依然没有找到答案，但是我有所收获，这个收获就是读书-读书使人明智。因此我希望能在新的一年里坚持读完12本经典的书。&lt;/p&gt;&lt;p&gt;在写这句话的时候已经是2012年了，总结了那么多其实只要一句话就可以表达现在的心情：前方依旧迷茫，唯有认准方向，并坚持走下去，才能成功。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2309236.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2011/12/29/2305275.html</id><title type="text">SQL server中的GUID列排序与Cluster Index</title><summary type="text">今天在项目中调查一个defect，发现SQL server对GUID列排序与ClusterIndex的特殊处理。这里涉及到两个知识点，一是SQL server 对GUID列的排序算法实现，二是Cluster Index和NonCluster Index的区别。先说一下SQL Server对GUID列的排序是如何实现的。具体文章在这：http://blogs.msdn.com/b/sqlprogrammability/archive/2006/11/06/how-are-guids-compared-in-sql-server-2005.aspx简要的算法就是，GUID 格式是 {0000000</summary><published>2011-12-28T23:25:00Z</published><updated>2011-12-28T23:25:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2011/12/29/2305275.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2011/12/29/2305275.html"/><content type="html">&lt;p&gt;&lt;span&gt;今天在项目中调查一个defect，发现SQL server对GUID列排序与&lt;/span&gt;&lt;span&gt;Cluster&lt;/span&gt;&lt;span&gt;&amp;nbsp;Index的特殊处理。这里涉及到两个知识点，一是SQL server 对GUID列的排序算法实现，二是Cluster Index和NonCluster Index的区别。先说一下SQL Server对GUID列的排序是如何实现的。具体文章在这：&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div&gt;http://blogs.msdn.com/b/sqlprogrammability/archive/2006/11/06/how-are-guids-compared-in-sql-server-2005.aspx&lt;div&gt;简要的算法就是，GUID 格式是 {000000000-0000-0000-00000000}，比较是以字节为单位来比较的。先从10-15位开始比&lt;/div&gt;&lt;div&gt;，然后是8-9位，6-7位，4-5位，0-3位这样的方式来做的。因此要特别注意这种方法与.net里面的方法是不同的。再来说Cluster index与NonCluster Index的区别。第一个主要的区别是存储的方式不同，Cluster Index被建立后的行记录的存储是以物理位置优先为原则的。也就是说SQL server会尽可能的在同一个存储页，在相邻的位置去存储行记录信息（用的是追加的方式）。这样的话记录存储的非常连续，数据库在查找和读取的时候就会很快，因为不用在存储页间跳转。但是同时也带来一个问题就是为了保证行记录的连续性，在插入和更新行记录的时候需要移动其他记录的位置，这会导致插入的时候性能问题。而NonCluster Index的好处正在于此，它是逻辑存储的，索引信息记录了行记录在那个存储页和页内偏移，所有的索引信息以树的形式存储。这样对于插入数据来说是很容易的，只要能找到空闲页，记录页号与偏移即可。同时对于查询和读取来说，在树上定位索引再到指定的页面读取记录会相对的慢一些，因此如何设置表的索引需要三思而行。&lt;/div&gt;&lt;div&gt;而这里我要说的问题是，当GUID列被作为Cluster Index时无论GUID值是否发生改变，只要进行了Update操作，它的行序号就会发生改变。也就是说使用同样的select语句对相同的记录进行查询会得到不同的记录顺序。所以这个是在使用Cluster Index时要注意的问题。 &lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2305275.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2011/12/29/2305275.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2011/12/16/2289589.html</id><title type="text">websocket才刚刚开始</title><summary type="text">这两天搞nodejs与websocket的整合，弄了2天-客户端和服务器端就是不能通信。在不同浏览器下表现的还不一样，Firefox (v6)如果你这么写 var ws = new WebSocket(url), Firebug直接会报一个WebSockect not defined的错误。经过调查原来在FireFox中，WebSockect的类叫MozWebSocket.Chrome (v15)WebSocket能正常创建，但是只要一收到数据就Close。就是这个问题搞了我两天，结果发现google的论坛里好多人都有这个问题。这显然是一个BugSafari (v5)这哥们目前看起对WebSo</summary><published>2011-12-15T16:02:00Z</published><updated>2011-12-15T16:02:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2011/12/16/2289589.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2011/12/16/2289589.html"/><content type="html">&lt;p&gt;这两天搞nodejs与websocket的整合，弄了2天-客户端和服务器端就是不能通信。在不同浏览器下表现的还不一样，&lt;/p&gt;&lt;p&gt;Firefox (v6)&lt;/p&gt;&lt;p&gt;如果你这么写 var ws = new WebSocket(url), Firebug直接会报一个WebSockect not defined的错误。经过调查原来在FireFox中，WebSockect的类叫MozWebSocket.&lt;/p&gt;&lt;p&gt;Chrome (v15)&amp;nbsp;&lt;/p&gt;&lt;p&gt;WebSocket能正常创建，但是只要一收到数据就Close。就是这个问题搞了我两天，结果发现google的论坛里好多人都有这个问题。这显然是一个Bug&lt;/p&gt;&lt;p&gt;Safari (v5)&lt;/p&gt;&lt;p&gt;这哥们目前看起对WebSocket支持的挺好。最后也是在这个浏览器上跑通的。&lt;/p&gt;&lt;p&gt;IE&lt;/p&gt;&lt;p&gt;没去试，听说是要IE10才正式支持。&lt;/p&gt;&lt;p&gt;总结一下，WebSocket还是比较新的事物，至少主流的浏览器大多不支持。所以，我想我们还需要等待。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2289589.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2011/12/16/2289589.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
