效果图

首先开启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));
}
}

github 下载 https://github.com/lick468/chatroom

最新文章

  1. gitlab工作流程简介
  2. oracle归档模式和非归档模式的切换
  3. 安卓 android ListView 数据填充
  4. Android之Picasso --zz
  5. HTTP基础09--web(1)
  6. vs2013 类名颜色显示黑色,无法修改
  7. 不可或缺 Windows Native (9) - C 语言: 动态分配内存,链表,位域
  8. winform之判断验证码,,附加验证码的一般处理程序
  9. (中等) CF 311B Cats Transport,斜率优化DP。
  10. setTimeout 和 setInteval 的区别。
  11. jquery实现照片墙
  12. Android RecyclerView初探
  13. Yii2.0调用sql server存储过程并获取返回值
  14. MySQL 8.0 InnoDB新特性
  15. php Warning: require(): open_basedir restriction in effect File(/www/wwwroot/default/
  16. ICO图标下载地址
  17. Highchartsjs使用总结及实时动态刷新图
  18. Python Argparse模块
  19. Golden Eggs HDU - 3820(最小割)
  20. selenium中,8种 find element 方法

热门文章

  1. 1 spring如何通过组件扫描和自动装配实现自动化的配置
  2. 一种电平转换的方法,使用CPLD
  3. 【实战】Apache shiro<=1.2.4 getshell
  4. c# 克隆来创建对象副本
  5. c# 接口实现
  6. 华为SDN:解决传统网络3大问题
  7. git命令——git rm、git mv
  8. KVM虚拟机的管理
  9. 助教培训总结——熟练掌握GitHub及Git的使用方法
  10. python自动化