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="" />
Nodejs用node.js和Websocket来做个多人聊天室吧
初学node.js和html5的相关技术(node方面大部分都是在cnodejs.org上面看技术文章学到的),想着学以致用,于是基于node.js和websocket来做了一个简单的多人聊天室:
一、功能简介
- 用户登录:用户随意输入一个昵称即可登录。
- 登录成功后:
- 对正在登录用户来说:罗列所有在线用户列表,罗列最近的历史聊天记录。
- 对已登录的用户来说:通知有新用户进入房间,更新在线用户列表。
- 退出登录:
- 目前未支持直接退出,只能通过关闭网页来退出。
- 当有用户退出,其他所有在线用户会收到信息,通知有用户退出房间,同时更新在线用户列表。
- 聊天:
- 聊天就是广播,把信息广播给所有连接在线的用户。
- 一些出错处理:
- 暂时简单处理了系统逻辑错误、网络出错等特殊情况的出错提示。
二、技术简介
- Node.js:主要基于
ws
库实现WebSocket通信。 - 服务器和客户端:用JSON数据来通讯。
- 代码结构:为了方便复用代码,部分代码(如
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>
三、参考文章
四、附带几张效果图
- 进入源码目录,
server.js
,执行node server.js
来启动服务。 - 输入昵称。
- 聊天主界面。
- 聊天主界面之“后登录用户查看历史消息”。
希望这个简单的示例能帮助你理解如何使用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 库。
安装依赖
首先,确保安装了 express
和 socket.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>
解释
-
服务器端:
- 使用
socket.io
处理 WebSocket 连接。 - 用户登录时,将其添加到
users
数组,并向所有连接的客户端广播新的用户列表和加入消息。 - 用户断开连接时,从
users
数组中移除该用户,并向所有客户端广播用户离开的消息。
- 使用
-
客户端:
- 提供一个输入框用于输入昵称并登录。
- 另一个输入框用于输入消息,并发送给所有客户端。
- 接收服务器发来的消息并在页面上显示。
这个例子提供了一个基本的聊天室框架,你可以在此基础上增加更多的功能,如用户离线通知、消息持久化等。