一.引言
这段时间需要做个东西,于是开始接触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(); } }); }
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目录下
为啥我遇到的问题一个接一个的 问题一: 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"
非常感谢