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


22 回复

踏出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阅读文档等等,但我不知道你是否做好了准备,毕竟阅读繁多的英文文档是件有挑战的事情。那么我们还可以在网上搜一个现成的例子,比如聊天室的例子,分析源代码,这样去学习。如果你也是这样想,那我们又一次不谋而合!

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

二. 正文

下面是实现的详细步骤:

  1. 在Win7平台下,在Nodejs官网下载msi安装包,安装到比如C:\program files\nodejs路径下(本人版本为v0.6.10)。

  2. 安装完成后,你会发现在安装目录下生成了一个node_modules文件夹,该文件夹存放各种模块。这些模块也是必须的,但很奇怪为什么装的时候不能直接一起装了。现在你需要安装这些模块。方法有两种:

    • 开始 -> 运行 -> cmd调出命令框,输入npm install 模块名
    • 直接下载一个node_modules然后复制粘贴 下载地址

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

  3. 下载原文中的代码:

    • 包括服务端代码node.js
    • 浏览器端JavaScriptmchat.js
    • 页面HTML代码client.html
    • 页面中引用的jQuery

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

  4. 将四个文件放在一个文件夹中,我们给它命名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"。总之引入就好了。

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

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,然后自己试吧,与原文中截图一致。

至此,大功告成。

三. 总结

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

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

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

四. 源码

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

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

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

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

能说具体点么?

解决了,好像必须建个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 聊天室,你可以按照以下步骤操作,并使用示例代码。

步骤

  1. 安装 Node.js: 确保已经安装了 Node.js。

  2. 创建项目目录:

    mkdir chatroom
    cd chatroom
    npm init -y
    
  3. 安装依赖:

    npm install express socket.io
    
  4. 创建服务器端代码 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');
    });
    
  5. 创建客户端代码 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,输入用户名并加入聊天室,然后就可以与其他用户进行实时通信了。

回到顶部