最近在學(xué)習(xí)node,其中一個(gè)很感興趣的項(xiàng)目是制作聊天工具。
起初是建立服務(wù)端與客戶端的一個(gè)socket連接,然后互相發(fā)消息,
現(xiàn)在想做兩個(gè)客戶端之間通訊,問(wèn)題來(lái)了..
clients變量是一個(gè)數(shù)組,里面存儲(chǔ)了socket對(duì)象,一旦有新的連接那么就會(huì)把新的socket對(duì)象push進(jìn)去,
如果做群發(fā)消息的話,只要給clients遍歷然后發(fā)消息,那么每個(gè)客戶端都能收到消息,
現(xiàn)在的問(wèn)題是我想做客戶端與客戶端之間的通訊,那么就要從這個(gè)數(shù)組中取出這個(gè)特定的客戶端, 請(qǐng)問(wèn)怎么能拿出那個(gè)特定的客戶端?
問(wèn)題轉(zhuǎn)化成了怎么成數(shù)組中拿出這個(gè)特定的對(duì)象..
下圖這樣寫(xiě)會(huì)報(bào)錯(cuò)
附上全部源代碼:
server.js:
// 建立一個(gè)Socket服務(wù)端
const net = require('net');
// 用于存儲(chǔ)所有的連接
var clients = [];
var server = net.createServer((socket) => {
//socket對(duì)象push進(jìn)去
clients.push(socket);
console.log(`${socket.remoteAddress}上線了,當(dāng)前在線${clients.length}人`);
socket.on('data',clientData).on('error',(err)=>{
clients.splice(clients.indexOf(socket),1);
console.log(`${socket.remoteAddress} 下線了 當(dāng)前在線${clients.length}人`);
});
//廣播方法
function broadcast(signal){
console.log(signal);
// 肯定有用戶名和消息
var username = signal.from;
var message = signal.message;
// 我們要發(fā)給客戶端的東西
var send = {
protocal:signal.protocal,
from:username,
message:message
};
// 廣播消息
clients.forEach(client => {
client.write(JSON.stringify(send));
});
}
//點(diǎn)對(duì)點(diǎn)消息
function p2p(signal){
console.log(signal);
// 肯定有用戶名和消息
var username = signal.from;
var target = signal.to;
var message = signal.message;
// 我們要發(fā)給客戶端的東西
var send = {
protocal:signal.protocal,
from:username,
message:message
};
console.log(`${username}要發(fā)給${target}的內(nèi)容是${message}`);
// 發(fā)送消息
//clients[target].write(JSON.stringify(send));
}
function clientData( chunk) {
// chunk:broadcast|張三|弄啥咧!
// 協(xié)議 用戶名 消息
// 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('協(xié)議的protocal字段有問(wèn)題!');
break;
}
// var username = signal.from;
// var message = signal.message;
}
catch (err) {
socket.write('數(shù)據(jù)格式有問(wèn)題!');
throw err;
}
// 有任何客戶端發(fā)消息都會(huì)觸發(fā)
// 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(`服務(wù)器正常啟動(dòng)監(jiān)聽(tīng)【${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('姓名有問(wèn)題!');
//創(chuàng)建與服務(wù)端的連接
//還可以傳入一個(gè)參數(shù)host:192.xx...
var socket = net.createConnection({ port: 2080 }, () => {
//登入操作;
var user = {
protocol: 'signin',
username: name
}
console.log(`Welcome ${socket.remoteAddress} ${name} to 2080 chatroom`);
//監(jiān)聽(tīng)服務(wù)端發(fā)過(guò)來(lái)的數(shù)據(jù)
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}"說(shuō)了:${signal.message}`);
rl.prompt();
break;
case 'p2p':
console.log(`[p2p]${signal.from}說(shuō)了:${signal.message}`);
rl.prompt();
break;
default:
server.write('數(shù)據(jù)協(xié)議字段有問(wèn)題');
break;
}
}
catch (err) {
socket.write('數(shù)據(jù)格式有問(wèn)題!');
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) {
//點(diǎn)對(duì)點(diǎn)消息
console.log('這是一個(gè)點(diǎn)對(duì)點(diǎn)消息');
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
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。