node.js 简易聊天室
效果图
首先开启server.js 打开服务器端,然后打开client.js,注册用户。打开一个注册一个用户,打开三个,注册三个用户。
接下来,小王发布一个广播消息,小李和小刘都收到了此消息。
接下来,小李给小刘私信。格式是 小刘:*****
然后就是一番对话
然后小李发布一个广播消息
下面是具体代码
创建一个目录,chatroom。
其中,config 作为配置文件,可以不用文件后缀
config
module.exports={
"port":3000,
"host":"127.0.0.1"
}
client.js
/**
终端聊天室客户端
*/
var net = require('net');
var config = require('./config');
var client = net.createConnection({
port:config.port,
host:config.host
});
//用户注册成功后为该属性赋值
var username;
client.on('connect',function() {
console.log('请输入用户名:');
process.stdin.on('data',function(data){
data = data.toString().trim();
//判断用户是否存在
if(!username) {
var send = {
protocal : 'signup',
username : data
}
client.write(JSON.stringify(send));
return;
}
//判断是广播消息还是点对点
//name :内容
var regex = /(.{1,18}):(.+)/;
var matches = regex.exec(data);
if(matches) {
var from = username;
var to = matches[1];
var message = matches[2];
var send = {
protocal : 'p2p',
from : username,
to : to,
message : message
}
client.write(JSON.stringify(send));
}else {
var send = {
protocal : 'broadcast',
from : username,
message :data
}
client.write(JSON.stringify(send));
}
});
});
client.on('data',function(data){
data = JSON.parse(data);
switch(data.protocal) {
case 'signup':
var code = data.code;
switch(code) {
case 1000:
username = data.username;
console.log(data.message);
break;
case 1001:
console.log(data.message);
break;
default:
break;
}
break;
case 'broadcast':
console.log(data.message);
break;
case 'p2p':
var code = data.code;
switch(code){
case 2000:
var from = data.from;
var message = data.message;
message = from + '说:' + message;
console.log(message);
break;
case 2001:
console.log(data.message);
break;
default:
break;
}
break;
default:
break;
};
});
server.js
/**
终端聊天室服务器端
*/
var net = require('net');
var config = require('./config');
var broadcast = require('./broadcast.js');
var p2p = require('./p2p.js');
var signup = require('./signup.js');
var server = net.createServer();
var users = {};
server.on('connection',function(socket) {
socket.on('data',function(data) {
//解析客户端发送的数据
data = JSON.parse(data);
//根据客户端发送的数据类型,做相应的操作
switch(data.protocal) {
//用户注册
case 'signup':
signup.signup(socket,data,users);
break;
//广播消息
case 'broadcast':
broadcast.broadcast(data,users);
break;
//点对点消息
case 'p2p':
p2p.p2p(socket,data,users);
break;
//异常
default:
break;
}
});
socket.on('error',function(){
console.log('有客户端异常退出了');
});
});
//启动服务器,开启监听
server.listen(config.port, config.host, function() {
console.log('server listening at port '+ config.port);
});
p2p.js
/**
点对点消息
*/
exports.p2p = function(socket,data,users) {
var from = data.from;
var to = data.to;
var message = data.message;
//找到要发送人的socket地址对象
var receiver = users[to];
//如果接收人不存在,告诉客户端没有该用户
if(!receiver) {
var send = {
protocal: 'p2p',
code : 2001,
message : '用户不存在'
}
socket.write(Buffer.from(JSON.stringify(send)));
}else {
//如果接收人存在,则将消息发送给该用户
// *** 对你说 : ***
var send = {
protocal : 'p2p',
code : 2000,
from : data.from,
message : message
}
receiver.write(Buffer.from(JSON.stringify(send)));
}
}
broadcast.js
/**
广播消息
*/
exports.broadcast = function(data,users) {
var from = data.from;
var message = data.message;
message = from + ' 说:' + message;
var send ={
protocal : 'broadcast',
message : message
}
send = Buffer.from(JSON.stringify(send));
for(var username in users) {
var tmpSocket = users[username];
tmpSocket.write(send);
}
}
signup.js
/**
用户注册
*/
exports.signup = function(socket,data,users) {
//处理用户注册请求
var username = data.username;
//如果用户名不存在,则将用户名与socket地址绑定
if(!users[username]) {
users[username] = socket;
var send = {
protocal : 'signup',
code : 1000,
username : username,
message : '注册成功'
}
socket.write(JSON.stringify(send));
}else {
var send = {
protocal : 'signup',
code : 1001,
message : '用户名已被占用,请重新输入用户名:'
}
socket.write(JSON.stringify(send));
}
}