迈出nodejs的第二步,用nodejs+socket.io搭建一个websocket聊天室
发布于 12 年前 作者 kiloo 37216 次浏览 最后一次编辑是 8 年前

<p><strong>一.引言</strong></p>

<p>这段时间需要做个东西,于是开始接触nodejs,算下来有一个星期时间了.重点是:走了超级多的弯路!!毕竟nodejs还算一个"新人",各方面资料和书籍相比php,jsp之类的,实在是太少了,很多还都没有翻译,如果你像我一样运气也不行,那走点弯路干着急是在所难免的了.所以以下文字希望对有相似方向的初学者有所帮助.</p>

<p>题目叫迈出nodejs的第二步,没错,因为第一步已经有一个人可以教你怎么迈了,那便是node入门,作者写的很好告诉了你node是什么能干什么之类最基本的问题.里面还有一个例子帮助你搭建了第一个node服务器,而且真的很简单.</p>

<p>那么接下来就是第二步.做一个假设,你对websocket有兴趣,正好nodejs可以与websocket很好的结合,你想用node做服务器,做一个实现了websocket技术的例子.这样开个头,以便接下来node与ws更多高级应用的学习.</p>

<p>如果你是这样想的,你与作者不谋而合!这里就要说到socket.io,它可以与nodejs结合并实现websocket应用(同类型的还有node-websocket-server,暂不做讨论). 接下来就可以开始动手实现,查阅api阅读文档等等,但我不知道你是否做好了准备,毕竟阅读繁多的英文文档是件有挑战的事情.那么我们还可以在网上搜一个现成的例子,比如聊天室的例子,分析源代码,这样去学习.如果你也是这样想,那我们又一次不谋而合!</p>

<p>网上有好几个这方面的例子,你是否能成功运行呢?这里抛去作者众多失败的经历,详细分析一个确保成功的案例.希望我前面的赘述不算太啰嗦,而后面的表达足够详细!</p>

<p><strong>二.正文</strong></p>

<p>原帖如下 <a href=“http://superisaac.iteye.com/blog/1284195”>猛击</a> </p>

<p>下面是实现的详细步骤</p>

<p>1.</p>

<p>win7平台下,在nodejs官网下载msi安装包,安装到比如C:\programe and files\nodejs 路径下(本人版本为v0.6.10)</p>

<p>2.</p>

<p>安完你会发现,生成了一个文件夹node<em>modules,该文件夹存放各种模块,这些模块也是必须的但很奇怪为什么装的时候不能直接一起装了.现在你需要安装这些模块.方法有两种(1)开始->运行->cmd调出命令框,输入npm install 模块名(2)直接下载一个node</em>modules然后复制粘贴 <a href=“http://1.nodejsdemo.sinaapp.com/node_modules.zip”>地址</a> </p>

<p>这里需要指出的是,在之后的运行中,如果出现cannot find module ‘xxx’,说明你缺xxx模块,你需要做的就是输入命令npm install xxx.之后将会自动下载安装,如果提示不成功,再来一遍</p>

<p>3.</p>

<p>下载原文中的代码</p>

<p>包括</p>

<p>1服务端代码-node.js</p>

<p>2浏览器端javascript-mchat.js</p>

<p>3页面html代码-client.html</p>

<p>4页面中引用的jQuery</p>

<p>前三个自己复制粘贴,jQuery地址如下 <a href=“http://code.jquery.com/jquery-1.7.min.js”>地址</a> </p>

<p>文中开头提到的shell代码暂无视</p>

<p>4.代码已经下载好了,但恐怕不能正常运行,这时我们需要改一改.</p>

<p>首先将四个文件放在一文件夹中,我们给它命名wstest,并保存到Administrator.然后在client.html头部做如下修改</p>

<pre><code>script src=“jquery-1.7.min.js" script src=”/Program Files/nodejs/node_modules/socket.io-client/dist/socket.io.js" script src=“mchat.js” </code></pre>

<p><strong>最最最重要的就是引入socket.io.js文件</strong></p>

<p>在原文中引入是这样的:src="/socket.io/socket.io.js"</p>

<p>可能是版本的原因,这个路径有点问题,现在安装后路径应该是"/Program Files/nodejs/node_modules/socket.io-client/dist/socket.io.js".如果没能成功导入这个文件,会导致client.html页面打开后无法连接到服务器.用Chrome审查元素时Console中可能会输出如</p>

<p>Uncaught TypeError: Cannot call method ‘emit’ of undefined</p>

<p>Uncaught TypeError: Cannot call method ‘send’ of undefined</p>

<p>这应该就是没有正确引入socket.io.js所导致的</p>

<p>当然,如果你把socket.io.js复制到与client.html同文件夹中,引入可以简便一点 src=“socket.io.js”.总之引入就好了</p>

<p>5.还有最后一点,应该是原作者的一个小遗漏,很容易发现</p>

<p>在mchat.js中将第一行</p>

<p>var socket = io.connect(“http://localhost”); 改为</p>

<p>var socket = io.connect(“http://localhost:3000”); </p>

<p>这个不用解释了吧,与服务端对应!</p>

<p>其他因素还有防火墙,不过windows防火墙好像是不会影响的</p>

<p>以上就是所有需要做的.下面我们来运行</p>

<p>调出命令框 输入命令</p>

<p>node wstest\node.js</p>

<p>正确的情况控制台会输出</p>

<p>info -socket.io started</p>

<p>…start on http://localhost:3000</p>

<p>服务端成功运行了之后,用Chrome打开你的client.html,然后自己试吧,与原文中截图一致</p>

<p>至此 大功告成</p>

<p><strong>三.总结</strong></p>

<p>首先得感谢所有的创造者和贡献者,使我们有了这项技术,有了虽然不多但十分有用的文档资料</p>

<p>当然许多像原文作者一样,将自己的例子放在网上供大家参考,也为众多初学者提供了极大的便利</p>

<p>中说"这不是一本从入门到精通的书,而是一本从入门到高级入门的书"</p>

<p>而本文作者也正是学习了不到10天的高级入门选手</p>

<p>希望本文足够细致能让每个人都能成功的运行,而不再浪费更多的时间走弯路.共同努力</p>

<p><strong>四.源码</strong></p>

<p>1.node.js</p>

<pre><code>var express = require(‘express’); var app = express.createServer(); var io = require(‘socket.io’).listen(app); app.configure(function () { app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.logger()); app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session({ secret: “skjghskdjfhbqigohqdioukd”, })); }); var conns = {}; io.sockets.on(‘connection’, function (socket) { var cid = socket.id; for(var ccid in conns) { var soc = conns[ccid]; soc.emit(‘join’, {cid: socket.id}); } conns[cid] = socket; socket.on(‘disconnect’, function () { delete conns[cid]; for(var cid in conns) { var soc = conns[cid]; soc.emit(‘quit’, {cid: cid}); } }); socket.on(‘say’, function (data) { data.cid = cid; for(var ccid in conns) { var soc = conns[ccid]; soc.emit(‘broadcast’, data); } }); }); app.get(’/’, function (req, res) { res.sendfile(__dirname + ‘/public/index.html’); }); app.use(’/public’, express.static(__dirname + ‘/public’)); app.listen(3000); console.log(‘daemon start on http://localhost:3000’); </code></pre>

<hr/>

<p>2.client.html</p>

<p><code><html> <head> <script src="/Program Files/nodejs/node_modules/socket.io-client/dist/socket.io.js"></script> <script src=“jquery-1.7.min.js”></script> <script src=“mchat.js”></script> <style type=“text/css”> #content { width: 600px; margin: 0 auto; } textarea { width: 400px; height: 40px;} </style> <script> $(document).ready(function() { initialize(); }); </script> </head> <body> <div id=“content”> <h1>Micro Chat</h1> <div id=“status”></div> <div id=“thread”> </div> <div> <textarea id=“text” name=“text”></textarea> </div> <div> <button id=“send” onclick=“say();”>Send</button> </div> </div> </body> </html></code></p>

<hr/>

<p>3.mchat.js</p>

<pre><code>var socket = io.connect(“http://localhost:3000”); socket.on(‘quit’, function (data) { status(‘Client ’ + data.cid + ’ quits!’); }); socket.on(‘join’, function (data) { status(‘Client ’ + data.cid + ’ joins!’); }); socket.on(‘broadcast’, function (data) { $(’#thread’).append($(’<div>’).html(‘client ’ + data.cid + ’ says:<br/>’ + data.w)); }); function say() { var words = $(’#text’).val(); if($.trim(words)) { //socket.send(words); socket.emit(‘say’, {w: words}); $(’#text’).val(’’); } } function status(w) { $(’#status’).html(w); } function initialize() { $(document).delegate(‘textarea’, ‘keydown’, function (evt) { //console.info(evt.keyCode); if(evt.keyCode == 13 && evt.ctrlKey) { $(’#send’).focus().click(); } }); } </code></pre>

22 回复

html代码不知道怎么插入,原文在人人网上也发了 http://blog.renren.com/blog/288187891/804068006

好好整理下吧= =

这里没有多少人有人人帐号,这么长的文章格式比内容重要,markdown wiki里有详细的帮助。

感谢啊,,终于跑通了第一个websocket+nodejs

改了,貌似不太美观,不过我试了复制后代码没问题的.现在全了

呵呵 恭喜你 写了好长时间才写完,看来没白写喽 :)

我打开后显示 Cannot GET / 求解哦

@muyuan 等待上线修复代码标签问题

能说具体点么?

解决了,好像必须建个public文件

@weixiang096 我明白你什么意思了.你是看了服务器之后,从浏览器里直接输入127001:3000对吧.我这样做的话也是Cannot GET/ 怎么解决的?我还不会

找不到express啊,但是明明有了呀,按照楼主给的包覆盖了还是不行,重安装也不行,怎么回事?

服务器能打开么?正常情况控制台会输出socket.io started 等等

我也试成功了,高科技!

1.在wstest下建立public文件夹,然后将jquery-1.7.min.js,mchat.js,client.html拷贝到该目录下 2.把node.js中的public.html改为client.html 3.最后再把socket.io文件夹拷贝到wstest目录下,应该就可以了;client.html中的文件的路径还是按照原来文件的地址写 看node.js的意思,好像静态文件的访问都在public目录下

哈,补充下,node node.js貌似不行。需要改个名字 . 还有socketIo文件里没有js文件。可以把socket.io.js文件拿出来放在socketIo文件下。

直接打开html页面可以使用,但是我把项目挂到iis上面再访问就用不了了,难道只能直接打开html文件吗?如果是聊天室,其他电脑的人要怎么加入进来呢?求解…

为啥我遇到的问题一个接一个的 问题一: Error: connect.cookieParser(“secret”) required for security when using sessions 于是将: app.use(express.cookieParser()); app.use(express.session({ secret: “skjghskdjfhbqigohqdioukd”, })); 修改为(网上搜索到的方法): app.use(express.cookieParser(‘skjghskdjfhbqigohqdioukd’)); app.use(express.session());

问题又来: Cannot GET /socket.io/1/?t=1334822213800

无解,求解~

我测试的过程中提示Uncaught ReferenceError: require is not defined的错误,应该是加载socket.io.js失败。 经过google发现另外的解决方案。使用服务端的socket.io.js 如:服务器:localhost 端口:3000 src=“http://localhost:3000/socket.io/socket.io.js

非常感谢

为什么加载本地的socket.io.js 不好用?

回到顶部