迈出Nodejs的第二步,用Nodejs+socket.io搭建一个websocket聊天室
迈出Nodejs的第二步,用Nodejs+socket.io搭建一个websocket聊天室
<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>
踏出Nodejs的第二步: 用Nodejs + socket.io 搭建一个WebSocket聊天室
一. 引言
这段时间需要做个东西,于是开始接触Nodejs。这段时间大约一个星期,重点是:走了超级多的弯路!毕竟Nodejs还算一个“新人”,各方面资料和书籍相比PHP、JSP之类的,实在太少了,很多还没有翻译。如果你像我一样运气不好,那走点弯路干着急是在所难免的了。所以以下文字希望对有相似方向的初学者有所帮助。
题目叫迈出Nodejs的第二步,没错,因为第一步已经有一个人可以教你怎么迈了,那便是Node入门。作者写的很好,告诉了你Node是什么,能干什么之类最基本的问题。里面还有一个例子帮助你搭建了第一个Node服务器,而且真的很简单。
那么接下来就是第二步。假设你对WebSocket有兴趣,正好Nodejs可以与WebSocket很好地结合,你想用Node做服务器,做一个实现了WebSocket技术的例子。这样开个头,以便接下来Node与WS更多高级应用的学习。
如果你是这样想的,你与作者不谋而合!这里要说的就是Socket.io,它可以与Nodejs结合并实现WebSocket应用(同类型的还有node-websocket-server,暂不做讨论)。接下来就可以开始动手实现,查阅API阅读文档等等,但我不知道你是否做好了准备,毕竟阅读繁多的英文文档是件有挑战的事情。那么我们还可以在网上搜一个现成的例子,比如聊天室的例子,分析源代码,这样去学习。如果你也是这样想,那我们又一次不谋而合!
网上有好几个这方面例子,你是否能成功运行呢?这里抛去作者众多失败的经历,详细分析一个确保成功的案例。希望我前面的赘述不算太啰嗦,而后面的表达足够详细!
二. 正文
下面是实现的详细步骤:
-
在Win7平台下,在Nodejs官网下载msi安装包,安装到比如
C:\program files\nodejs
路径下(本人版本为v0.6.10)。 -
安装完成后,你会发现在安装目录下生成了一个
node_modules
文件夹,该文件夹存放各种模块。这些模块也是必须的,但很奇怪为什么装的时候不能直接一起装了。现在你需要安装这些模块。方法有两种:- 开始 -> 运行 -> cmd调出命令框,输入
npm install 模块名
- 直接下载一个
node_modules
然后复制粘贴 下载地址
这里需要指出的是,在之后的运行中,如果出现
cannot find module 'xxx'
,说明你缺xxx
模块,你需要做的就是输入命令npm install xxx
。之后将会自动下载安装,如果提示不成功,再来一遍。 - 开始 -> 运行 -> cmd调出命令框,输入
-
下载原文中的代码:
- 包括服务端代码
node.js
- 浏览器端JavaScript
mchat.js
- 页面HTML代码
client.html
- 页面中引用的jQuery
前三个自己复制粘贴,jQuery地址如下:下载地址
- 包括服务端代码
-
将四个文件放在一个文件夹中,我们给它命名
wstest
,并保存到Administrator
目录下。然后在client.html
头部做如下修改:
<script src="jquery-1.7.min.js"></script>
<script src="/Program Files/nodejs/node_modules/socket.io-client/dist/socket.io.js"></script>
<script src="mchat.js"></script>
最最最重要的就是引入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"
。总之引入就好了。
- 还有一点,应该是原作者的一个小遗漏,很容易发现:
在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
,然后自己试吧,与原文中截图一致。
至此,大功告成。
三. 总结
首先得感谢所有的创造者和贡献者,使我们有了这项技术,有了虽然不多但十分有用的文档资料。
当然许多像原文作者一样,将自己的例子放在网上供大家参考,也为众多初学者提供了极大的便利。
希望本文足够细致能让每个人都能成功的运行,而不再浪费更多的时间走弯路。共同努力!
四. 源码
- node.js
var express = require('express');
var app = express();
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.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');
- 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>
- 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.emit('say', { w: words });
$('#text').val('');
}
}
function status(w) {
$('#status').html(w);
}
function initialize() {
$(document).delegate('textarea', 'keydown', function (evt) {
if (evt.keyCode == 13 && evt.ctrlKey) {
$('#send').focus().click();
}
});
}
希望这些步骤和代码可以帮助你成功搭建一个WebSocket聊天室。
html代码不知道怎么插入,原文在人人网上也发了 http://blog.renren.com/blog/288187891/804068006
好好整理下吧= =
这里没有多少人有人人帐号,这么长的文章格式比内容重要,markdown wiki里有详细的帮助。
感谢啊,,终于跑通了第一个websocket+nodejs
改了,貌似不太美观,不过我试了复制后代码没问题的.现在全了
呵呵 恭喜你 写了好长时间才写完,看来没白写喽 :)
嗯
能说具体点么?
解决了,好像必须建个public文件
好
找不到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 不好用?
为了实现一个基于 Node.js 和 socket.io 的 WebSocket 聊天室,你可以按照以下步骤操作,并使用示例代码。
步骤
-
安装 Node.js: 确保已经安装了 Node.js。
-
创建项目目录:
mkdir chatroom cd chatroom npm init -y
-
安装依赖:
npm install express socket.io
-
创建服务器端代码
server.js
:const express = require('express'); const http = require('http'); const socketIo = require('socket.io'); const app = express(); const server = http.createServer(app); const io = socketIo(server); app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.use('/static', express.static('public')); let users = {}; io.on('connection', (socket) => { console.log('A user connected:', socket.id); socket.on('newUser', (name) => { users[socket.id] = name; io.emit('userJoined', { id: socket.id, name }); }); socket.on('message', (data) => { io.emit('message', { id: socket.id, name: users[socket.id], message: data.message }); }); socket.on('disconnect', () => { console.log('A user disconnected:', socket.id); delete users[socket.id]; io.emit('userLeft', { id: socket.id, name: users[socket.id] }); }); }); server.listen(3000, () => { console.log('Server is running on port 3000'); });
-
创建客户端代码
public/index.html
:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Chat Room</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <style> #chat { width: 400px; margin: 0 auto; } textarea { width: 300px; height: 100px; } </style> </head> <body> <div id="chat"> <input id="username" type="text" placeholder="Enter your username"> <button id="join">Join</button> <div id="messages"></div> <textarea id="message"></textarea> <button id="send">Send</button> </div> <script> let socket; $('#join').click(() => { const username = $('#username').val(); socket = io('http://localhost:3000'); socket.emit('newUser', username); }); $('#send').click(() => { const message = $('#message').val(); if (message.trim()) { socket.emit('message', { message }); $('#message').val(''); } }); socket.on('userJoined', (data) => { $('#messages').append(`<p>${data.name} has joined the chat.</p>`); }); socket.on('message', (data) => { $('#messages').append(`<p><strong>${data.name}</strong>: ${data.message}</p>`); }); socket.on('userLeft', (data) => { $('#messages').append(`<p>${data.name} has left the chat.</p>`); }); </script> </body> </html>
运行
node server.js
打开浏览器访问 http://localhost:3000
,输入用户名并加入聊天室,然后就可以与其他用户进行实时通信了。