最近在学习node,其中一个很感兴趣的项目是制作聊天工具。
起初是建立服务端与客户端的一个socket连接,然后互相发消息,
现在想做两个客户端之间通讯,问题来了..
clients变量是一个数组,里面存储了socket对象,一旦有新的连接那么就会把新的socket对象push进去,
如果做群发消息的话,只要给clients遍历然后发消息,那么每个客户端都能收到消息,
现在的问题是我想做客户端与客户端之间的通讯,那么就要从这个数组中取出这个特定的客户端, 请问怎么能拿出那个特定的客户端?
问题转化成了怎么成数组中拿出这个特定的对象..
下图这样写会报错
附上全部源代码:
server.js:
// 建立一个Socket服务端
const net = require('net');
// 用于存储所有的连接
var clients = [];
var server = net.createServer((socket) => {
//socket对象push进去
clients.push(socket);
console.log(`${socket.remoteAddress}上线了,当前在线${clients.length}人`);
socket.on('data',clientData).on('error',(err)=>{
clients.splice(clients.indexOf(socket),1);
console.log(`${socket.remoteAddress} 下线了 当前在线${clients.length}人`);
});
//广播方法
function broadcast(signal){
console.log(signal);
// 肯定有用户名和消息
var username = signal.from;
var message = signal.message;
// 我们要发给客户端的东西
var send = {
protocal:signal.protocal,
from:username,
message:message
};
// 广播消息
clients.forEach(client => {
client.write(JSON.stringify(send));
});
}
//点对点消息
function p2p(signal){
console.log(signal);
// 肯定有用户名和消息
var username = signal.from;
var target = signal.to;
var message = signal.message;
// 我们要发给客户端的东西
var send = {
protocal:signal.protocal,
from:username,
message:message
};
console.log(`${username}要发给${target}的内容是${message}`);
// 发送消息
//clients[target].write(JSON.stringify(send));
}
function clientData( chunk) {
// chunk:broadcast|张三|弄啥咧!
// 协议 用户名 消息
// chunk:{'protocal':'broadcast','from':'张三','message':''}
// chunk:{'protocal':'p2p',from:'张三',to:'李四',message':''}
try {
var signal = JSON.parse(chunk.toString().trim());
var protocal = signal.protocal;
switch (protocal) {
case 'broadcast':
broadcast(signal);
break;
case 'p2p':
console.log('接收到了p2p消息!');
p2p(signal);
break;
case 'shake':
shake(signal);
break;
default:
socket.write('协议的protocal字段有问题!');
break;
}
// var username = signal.from;
// var message = signal.message;
}
catch (err) {
socket.write('数据格式有问题!');
throw err;
}
// 有任何客户端发消息都会触发
// var username = chunk.username;
// var message = chunk.messge;
// broadcast(username.message)
};
});
var port = 2080;
server.listen(port, (err) => {
if (err) {
console.log('端口被占用了');
return false;
}
console.log(`服务器正常启动监听【${port}】端口`);
});
client.js:
//客户端
const net = require('net');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What is your name? ', (name) => {
name = name.trim();
if (!name) throw new Error('姓名有问题!');
//创建与服务端的连接
//还可以传入一个参数host:192.xx...
var socket = net.createConnection({ port: 2080 }, () => {
//登入操作;
var user = {
protocol: 'signin',
username: name
}
console.log(`Welcome ${socket.remoteAddress} ${name} to 2080 chatroom`);
//监听服务端发过来的数据
socket.on('data', (chunk) => {
try {
var signal = JSON.parse(chunk.toString().trim());
var protocal = signal.protocal;
switch (protocal) {
case 'broadcast':
console.log(`[broadcast]"${signal.from}"说了:${signal.message}`);
rl.prompt();
break;
case 'p2p':
console.log(`[p2p]${signal.from}说了:${signal.message}`);
rl.prompt();
break;
default:
server.write('数据协议字段有问题');
break;
}
}
catch (err) {
socket.write('数据格式有问题!');
throw err;
}
});
rl.setPrompt(`${name}> `);
rl.prompt();
rl.on('line', (line) => {
line = line.toString().trim();
var temp = line.split(':');
var send;
if (temp.length === 2) {
//点对点消息
console.log('这是一个点对点消息');
send = {
protocal: 'p2p',
from: name,
to: temp[0],
message: temp[1]
};
} else {
//广播消息
// chunk:{'protocal':'broadcast','from':'张三','message':''}
send = {
protocal: 'broadcast',
from: name,
message: line.toString().trim()
};
}
socket.write(JSON.stringify(send));
rl.prompt();
}).on('close', () => {
console.log('Have a great day!');
process.exit(0);
});
});
});
使用:
--node server.js
--node client.js
代码好多,我是否理解最后的问题就是
只要
push
之前做好标示,这个socket
是哪个人的,比如clients.push({username:'one', socket:socket })
,然后需要的时候从clients.find({username:'one'))
就可以了。