迈出nodejs的第二步,用nodejs+socket.io搭建一个websocket聊天室
发布于 3年前 作者 kiloo 13892 次浏览

一.引言

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

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

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

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

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

二.正文

原帖如下 猛击

下面是实现的详细步骤

1.

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

2.

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

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

3.

下载原文中的代码

包括

1服务端代码-node.js

2浏览器端javascript-mchat.js

3页面html代码-client.html

4页面中引用的jQuery

前三个自己复制粘贴,jQuery地址如下 地址

文中开头提到的shell代码暂无视

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

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

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"

最最最重要的就是引入socket.io.js文件

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

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

Uncaught TypeError: Cannot call method 'emit' of undefined

Uncaught TypeError: Cannot call method 'send' of undefined

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

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

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

在mchat.js中将第一行

var socket = io.connect("http://localhost"); 改为

var socket = io.connect("http://localhost:3000");

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

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

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

调出命令框 输入命令

node wstest\node.js

正确的情况控制台会输出

info -socket.io started

...start on http://localhost:3000

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

至此 大功告成

三.总结

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

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

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

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

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

四.源码

1.node.js

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');

2.client.html

<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>


3.mchat.js

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(); } }); }
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 不好用?

回到顶部