Nodejs用node.js和Websocket来做个多人聊天室吧

Nodejs用node.js和Websocket来做个多人聊天室吧

初学node.js和html5的相关技术(node方面大部分都是在cnodejs.org上面看技术文章学到的),想着学以致用,于是基于node.js和websocket来做了一个多人聊天室: <br/> <br/><strong>一、功能简介</strong> <br/>1、用户随意输入一个昵称即可登录 <br/>2、登录成功后 <br/>1) 对正在登录用户来说,罗列所有在线用户列表,罗列最近的历史聊天记录 <br/>2) 对已登录的用户来说,通知有新用户进入房间,更新在线用户列表 <br/>3、退出登录 <br/>1) 目前未支持直接退出,只能通过关闭网页来退出… <br/>2) 当有用户退出,其他所有在线用户会收到信息,通知又用户退出房间,同时更新在线用户列表 <br/>4、聊天 <br/>1) 聊天就是广播,把信息广播给所有连接在线的用户 <br/>5、一些出错处理 <br/>1) 暂时简单处理了系统逻辑错误、网络出错等特殊情况的出错提示 <br/> <br/><strong>二、技术简介</strong> <br/>1、node方面主要是基于node-websocket-server这个框架;服务器和客户端用JSON数据来通讯; <br/>2、其他的就不多说了,直接贴上这个小demo的源码地址: https://github.com/auzll/nodechat 。有兴趣的可以看看,欢迎各位网友批评指正。 <br/> <br/><strong>三、参考文章</strong> <br/>1、websocket与node.js的完美结合( http://cnodejs.org/blog/?p=273 ) 。从这里了解到node-websocket-server 这个框架的,一个node.js和websocket通讯的框架,本程序中有使用到。 <br/>2、nodejs: 真正的一份代码,到处运行( http://cnodejs.org/blog/?p=702 ) 。从这里了解到如何在svr和client中同时复用部分代码,当然,本程序也模仿了这里面的技术来做,例如我源码里面svr/chatLib.js其实是同时被svr和client公用的。 <br/> <br/><strong>四、附带几张效果图</strong> <br/>1、 进入源码目录,svr/Main.js,执行node Main.js来启动 <br/><img src=“http://ww3.sinaimg.cn/large/68603ab1tw1dl2p3rkpvnj.jpg” alt="" /> <br/>2、 输入昵称 <br/><img src=“http://ww2.sinaimg.cn/large/68603ab1tw1dl2p3y6udhj.jpg” alt="" /> <br/>3、 聊天主界面 <br/><img src=“http://ww1.sinaimg.cn/large/68603ab1tw1dl2p42g4tcj.jpg” alt="" /> <br/>4、 聊天主界面之“后登陆用户查看历史消息” <br/><img src=“http://ww3.sinaimg.cn/large/68603ab1tw1dl2p48b192j.jpg” alt="" />


16 回复

Nodejs用node.js和Websocket来做个多人聊天室吧

初学node.js和html5的相关技术(node方面大部分都是在cnodejs.org上面看技术文章学到的),想着学以致用,于是基于node.js和websocket来做了一个简单的多人聊天室:

一、功能简介

  1. 用户登录:用户随意输入一个昵称即可登录。
  2. 登录成功后
    • 对正在登录用户来说:罗列所有在线用户列表,罗列最近的历史聊天记录。
    • 对已登录的用户来说:通知有新用户进入房间,更新在线用户列表。
  3. 退出登录
    • 目前未支持直接退出,只能通过关闭网页来退出。
    • 当有用户退出,其他所有在线用户会收到信息,通知有用户退出房间,同时更新在线用户列表。
  4. 聊天
    • 聊天就是广播,把信息广播给所有连接在线的用户。
  5. 一些出错处理
    • 暂时简单处理了系统逻辑错误、网络出错等特殊情况的出错提示。

二、技术简介

  1. Node.js:主要基于ws库实现WebSocket通信。
  2. 服务器和客户端:用JSON数据来通讯。
  3. 代码结构:为了方便复用代码,部分代码(如chatLib.js)同时被服务器和客户端使用。

示例代码

服务器端 (server.js)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

let users = [];
let messages = [];

wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        const data = JSON.parse(message);
        switch (data.type) {
            case 'login':
                users.push(data.name);
                broadcast(JSON.stringify({
                    type: 'login',
                    name: data.name,
                    users: users,
                    messages: messages
                }));
                break;
            case 'chat':
                messages.push({ name: data.name, message: data.message });
                broadcast(message);
                break;
            default:
                console.error("Unknown event type " + data.type);
        }
    });

    ws.on('close', function() {
        const index = users.indexOf(data.name);
        if (index > -1) {
            users.splice(index, 1);
        }
        broadcast(JSON.stringify({
            type: 'logout',
            name: data.name,
            users: users
        }));
    });
});

function broadcast(message) {
    wss.clients.forEach(function each(client) {
        if (client.readyState === WebSocket.OPEN) {
            client.send(message);
        }
    });
}
客户端 (client.html)
<!DOCTYPE html>
<html>
<head>
    <title>多人聊天室</title>
</head>
<body>
    <input id="nickname" placeholder="请输入昵称">
    <button onclick="login()">登录</button>
    <div id="chat"></div>
    <input id="message" placeholder="请输入消息">
    <button onclick="sendMessage()">发送</button>

    <script>
        let ws;

        function login() {
            const nickname = document.getElementById('nickname').value;
            ws = new WebSocket(`ws://${window.location.host}`);
            ws.onopen = () => {
                ws.send(JSON.stringify({ type: 'login', name: nickname }));
            };
            ws.onmessage = function(event) {
                const data = JSON.parse(event.data);
                switch (data.type) {
                    case 'login':
                        updateUsers(data.users);
                        appendMessage(data.messages.map(m => m.name + ': ' + m.message).join('\n'));
                        break;
                    case 'chat':
                        appendMessage(data.name + ': ' + data.message);
                        break;
                    case 'logout':
                        updateUsers(data.users);
                        break;
                }
            };
        }

        function sendMessage() {
            const message = document.getElementById('message').value;
            ws.send(JSON.stringify({ type: 'chat', name: document.getElementById('nickname').value, message }));
        }

        function updateUsers(users) {
            document.getElementById('users').innerText = users.join(', ');
        }

        function appendMessage(message) {
            const chat = document.getElementById('chat');
            chat.innerHTML += '<p>' + message + '</p>';
        }
    </script>
</body>
</html>

三、参考文章

  1. websocket与node.js的完美结合
  2. nodejs: 真正的一份代码,到处运行

四、附带几张效果图

  1. 进入源码目录,server.js,执行node server.js来启动服务。
  2. 输入昵称。
  3. 聊天主界面。
  4. 聊天主界面之“后登录用户查看历史消息”。

希望这个简单的示例能帮助你理解如何使用Node.js和WebSocket构建一个多人聊天室。


我想问一下,用户的唯一标识UUID是如何创建的呢? <br/>数据存储是用什么呢?

为什么我运行不起来这个例子呢 ? <br/>我安装 express 的项目都能跑起来。。 <br/>但是这个项目,我node Main.js 后,启动起来后,,我访问 <br/>http://ip:9800/index.html 却访问不到页面 ? <br/> <br/>请教,这个为什么呢?

未来nodejs在websocket方面会成为重头戏

最近也做了个这样的聊天室,然后升级成了一个你画我猜的游戏,可惜还找不到支持websocket的免费服务器

客户端在打开web/index.html网页,而不是在浏览器中输出localhost:9800

我在windows下面用node.exe运行 提示我 process.stdout.flush(); 这个错误 说WriteStream has no method flush 这是怎么回事? 是缺少什么包吗?

chromium 18 chrome 出现无法连接服务器的问题 onopen事件 无法执行 这是怎么回事 浏览器的问题吗?我看了node-websocket-server的源码 他使用的75的标准 我在网上查到chrome貌似更新到76了 我修改node-websocket-server的源码让他使用76标准 同样无法运行.有谁能用chrome 运行起这个例子吗?教教我 谢了

我的chrome版本:15.0.874.121 m ,实现了draft10标准以后,整个系统能够跑起来,但有一个奇怪的问题,就是chat.js里在onopen以后,连续send了3个消息(login,list_user,list_history),这三个请求如果不间断的发送,会导致错误,错误的原因是发送的json格式出错,也就是未能正确的发送消息,但如果在其中插入alert的话,是可以正确发送3个消息。在node-websocket-server提供的chat实例里,也试过在onopen事件触发的时候连续发送多条消息,都会出现错误。不知哪位高人能给出一下解释?

我使用的0.6.6 Node.js,在Linux下运行 <br/> process.stdout.flush(); <br/> ^ <br/>TypeError: Object # has no method ‘flush’ <br/> at /root/jasper/monsocket/lib/ws/connection.js:43:22 <br/> at new Connection (/root/jasper/monsocket/lib/ws/connection.js:82:5) <br/> at Server. (/root/jasper/monsocket/lib/ws/server.js:65:7) <br/> at Server.emit (events.js:88:20) <br/> at Socket. (http.js:1389:14) <br/> at TCP.onread (net.js:348:27)

我的websocket 本地跑没问题,放NAE上也是能跑起来的,可是外面却连不上websocket服务器,为什么?

L我也是这个问题,求指导~

请教一下node Main.js以后怎么访问工程里面的html?我不管怎么访问 页面都显示No Implemeted.

点击“进入聊天室”没有反应啊,话说chatroom.htm里面也的button也没有绑定点击事件啊。。。怎么破

能不能控制只有经过验证的用户可以建立连接呢,类似与只有登录的用户才能建立websocket

基于 Node.js 和 WebSocket 实现一个多人聊天室是一个很好的练习项目。以下是一个简单的示例代码来实现这个聊天室的基本功能。

技术栈

  • Node.js: 用于构建后端服务。
  • WebSocket: 用于实现实时通信。
  • Express: 用于搭建HTTP服务器。
  • socket.io: 一个方便使用的 WebSocket 库。

安装依赖

首先,确保安装了 expresssocket.io

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

let users = [];

io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    // 用户登录
    socket.on('login', (nickname) => {
        const user = { id: socket.id, nickname };
        users.push(user);
        io.emit('usersList', users.map(u => u.nickname));
        io.emit('message', `${nickname} has joined the chat.`);
    });

    // 用户发送消息
    socket.on('sendMessage', (message) => {
        io.emit('message', message);
    });

    // 用户断开连接
    socket.on('disconnect', () => {
        users = users.filter(user => user.id !== socket.id);
        io.emit('usersList', users.map(u => u.nickname));
        io.emit('message', `${users.find(user => user.id === socket.id).nickname} has left the chat.`);
    });
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

客户端代码 (index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chat Room</title>
    <script src="/socket.io/socket.io.js"></script>
</head>
<body>
    <h1>Welcome to the Chat Room</h1>
    <input type="text" id="nickname" placeholder="Enter your nickname">
    <button onclick="login()">Login</button>
    <ul id="messages"></ul>
    <input type="text" id="message" placeholder="Type a message">
    <button onclick="sendMessage()">Send</button>

    <script>
        const socket = io();

        let nickname;

        function login() {
            nickname = document.getElementById('nickname').value;
            socket.emit('login', nickname);
        }

        function sendMessage() {
            const message = document.getElementById('message').value;
            socket.emit('sendMessage', `${nickname}: ${message}`);
            document.getElementById('message').value = '';
        }

        socket.on('message', (msg) => {
            const messages = document.getElementById('messages');
            const li = document.createElement('li');
            li.textContent = msg;
            messages.appendChild(li);
        });

        socket.on('usersList', (users) => {
            const usersList = document.getElementById('usersList');
            usersList.innerHTML = users.join('<br>');
        });
    </script>
</body>
</html>

解释

  1. 服务器端:

    • 使用 socket.io 处理 WebSocket 连接。
    • 用户登录时,将其添加到 users 数组,并向所有连接的客户端广播新的用户列表和加入消息。
    • 用户断开连接时,从 users 数组中移除该用户,并向所有客户端广播用户离开的消息。
  2. 客户端:

    • 提供一个输入框用于输入昵称并登录。
    • 另一个输入框用于输入消息,并发送给所有客户端。
    • 接收服务器发来的消息并在页面上显示。

这个例子提供了一个基本的聊天室框架,你可以在此基础上增加更多的功能,如用户离线通知、消息持久化等。

回到顶部