欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Node.js利用Net模塊實現(xiàn)多人命令行聊天室的方法

 更新時間:2016年12月23日 11:17:39   投稿:daisy  
Node.js Net 模塊提供了一些用于底層的網(wǎng)絡通信的小工具,包含了創(chuàng)建服務器/客戶端的方法,下面這篇文章主要給大家介紹了Node.js利用Net模塊實現(xiàn)命令行多人聊天室的方法,有需要的朋友們可以參考借鑒,下面來一起看看吧。

這篇文章介紹的是Node.js利用Net模塊實現(xiàn)命令行式的多人聊天室,下面話不多說,來看看詳細的介紹吧。

1、net模塊基本API

要使用Node.js的net模塊實現(xiàn)一個命令行聊天室,就必須先了解NET模塊的API使用。NET模塊API分為兩大類:

Server和Socket類、工廠方法。

Server類如下圖所示:

net.Server類可以用來創(chuàng)建一個TCP或本地服務器,繼承了EventEmitter。

Socket類如下:


net.Socket類一般用創(chuàng)建一個socket客戶端或者是net.Server connection事件的參數(shù)。

工廠方法如下:

以上三個圖展示了API的使用,其實NET模塊的內(nèi)部原理和C++網(wǎng)絡編程差不多的,都是以下步驟。

服務端:

  1. 創(chuàng)建socket套接字
  2. 綁定IP和端口
  3. 啟動監(jiān)聽
  4. 等待客戶端連接
  5. 與客戶端進行通信
  6. 關閉socket

客戶端:

  1. 創(chuàng)建socket套接字
  2. 連接server服務器
  3. 與服務器進行通信
  4. 關閉socket

如下圖所示:

2、聊天室的設計和實現(xiàn)

上面學習了NET模塊API的使用,接下來便開始實現(xiàn)命令行聊天室,我們不需要做的很復雜,只需實現(xiàn)如下功能即可:

  1. 用戶自定義昵稱,不可更改
  2. 當有新的用戶進入聊天室,或者用戶離開聊天室,廣播給其他用戶
  3. 用戶發(fā)送信息,需廣播給其他用戶
  4. 客戶端與服務端建立心跳機制
  5. 用戶輸入'exit'或者'quit'可以退出聊天室

確定功能之后,便開始代碼的編寫。這里我就不一步步分析,直接上代碼了,首先是服務端:

Server:

const net = require('net');
const server = net.createServer();
const clients = {};//保存客戶端的連接
var client = null;//當前客戶連接
var uid = 0;
server.on('connection',(socket)=>{
 //啟動心跳機制
 var isOnline = !0;
 var keepAliveTimer = socket.timer = setInterval(()=>{
  if(!isOnline){
   isOnline = !1;
   client = socket;
   quit(socket.nick);
   return;
  }
  if(socket.writable){
   socket.write('::');
  }else{
   client = socket;
   quit(socket.nick);
  }
 },3000);
 socket.on('end',()=>{
  console.log(`client disconnected.\n\r`);
  socket.destroy();
 });
 socket.on('error',(error)=>{
  console.log(error.message);
 });
 socket.on('data',(chunk)=>{
  client = socket;
  var msg = JSON.parse(chunk.toString());
  if(msg.cmd=='keep'){
   isOnline = !0;
   return;
  }
  dealMsg(msg);
 });
});
server.on('error',(err)=>{
 console.log(err);
});
server.on('listening',()=>{
 console.log(`listening on ${server.address().address}:${server.address().port}\n\r`);
});
server.listen(8060);//啟動監(jiān)聽
/**
 * 處理用戶信息
 */
function dealMsg(msg){
 const cmd = msg.cmd;
 const funs = {
  'login':login,
  'chat':chat,
  'quit':quit,
  'exit':quit
 };
 if(typeof funs[cmd] !== 'function') return !1;
 funs[cmd](msg);
}
/**
 * 釋放連接資源
 */
function freeConn(conn){
 conn.end();
 delete clients[conn.uuid];
 conn.timer&&clearInterval(conn.timer);
}
/**
 * 用戶首次進入聊天室
 */
function login(msg){
 var uuid = '';
 uuid = getRndStr(15)+(++uid);//產(chǎn)生用戶ID
 client.write(`歡迎你,${msg.nick}:這里總共有${Object.keys(clients).length}個小伙伴在聊天.\r\n`)
 client.nick = msg.nick;
 client.uuid = uuid;
 clients[uuid] = client;
 broadcast(`系統(tǒng):${msg.nick}進入了聊天室.`);

}
/**
 * 廣播消息
 */
function broadcast(msg){
 Object.keys(clients).forEach((uuid)=>{
  if((clients[uuid]!=client)& clients[uuid].writable){
   clients[uuid].write(msg);
  }
 });
}
/**
 * 退出聊天室
 */
function quit(nick){
 var message = `小伙伴${nick}退出了聊天室.`;
 broadcast(message);
 freeConn(client);
}

function chat(msg){
 if(msg.msg.toLowerCase()=='quit'||msg.msg.toLowerCase()=='exit'){
  quit(msg.nick);
  return ;
 }
 var message = `${msg.nick}說:${msg.msg}`;
 broadcast(message);
} 
/**
 * 隨機指定長度(len)的字符串
 */
function getRndStr(len=1){
 var rndStr = '';
 for (; rndStr.length < len; rndStr += Math.random().toString(36).substr(2));
 return rndStr.substr(0, len);
}

客戶端代碼如下:

client:

const net = require('net');
const cout = process.stdout;
const cin = process.stdin;

var client = null;
var nick = '';

cout.write(`請輸入昵稱:`);
//監(jiān)聽命令行輸入
cin.on('data',(chunk)=>{
 if(chunk.toString()!='\r\n'){
  if(client === null){
   nick = (chunk+'').replace(/[\r\n]/ig,"");
   createClient();
  }else{
   msg = (chunk+'').replace(/[\r\n]/ig,"");
   client.write(JSON.stringify({
    cmd: 'chat',
    msg: msg,
    nick: nick
   }));
   //如果輸入是exit或quit則斷開連接并退出
   if(msg.toLowerCase() == 'exit' || msg.toLowerCase() == 'quit'){
    client.end();
    cin.end();
    return;
   }
   cout.write(`你說:${msg}\n\r`);
  }
 }else{
  cout.write(`請輸入昵稱:`);
 }
});

function addListener(client) {
 client.on('connect', () => {
  cout.write(`已連接到服務器\n\r`);
  client.write(JSON.stringify({
   cmd: 'login',
   msg: 'hello server',
   nick: nick
  }));
 });
 client.on('end', (chunk) => {
  cout.write(`與服務器斷開連接.\n\r`);
 });
 client.on('data', (chunk) => {
  //如果是心跳信息則回應keep命令
  if(chunk.toString()=='::'){
   client.write(JSON.stringify({
    cmd: 'keep',
    msg: '',
    nick: nick
   }));
   return ;
  }
  cout.write(`${chunk}\n\r`);
 });
 client.on('error', (err) => {
  cout.write(`an error has occured.\n\r${err}`);
 });
}
/**
 * 創(chuàng)建socket并連接服務器
 */
function createClient(){
 console.log('\033[2J');//清屏操作
 cout.write(`輸入'EXIT OR QUIT'退出聊天室.\r\n`);
 client = new net.Socket()
 client.connect({port:8060/*,host:'1.1.1.69'*/});
 addListener(client);
}

執(zhí)行結果如下如下:

到此,一個命令行聊天室便做完了。

總結

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

相關文章

  • node項目使用http模塊發(fā)送get-post請求方式

    node項目使用http模塊發(fā)送get-post請求方式

    這篇文章主要介紹了node項目使用http模塊發(fā)送get-post請求方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • nodeJS(express4.x)+vue(vue-cli)構建前后端分離實例(帶跨域)

    nodeJS(express4.x)+vue(vue-cli)構建前后端分離實例(帶跨域)

    這篇文章主要介紹了nodeJS(express4.x)+vue(vue-cli)構建前后端分離實例(帶跨域) ,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 使用nodejs搭建一個簡易HTTP服務的實現(xiàn)示例

    使用nodejs搭建一個簡易HTTP服務的實現(xiàn)示例

    本文主要介紹了使用nodejs搭建一個簡易HTTP服務的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • Node.js中process模塊常用的屬性和方法

    Node.js中process模塊常用的屬性和方法

    Node.js中的process模塊用來與當前進程互動,可以通過全局變量process訪問,不必使用require命令加載。它是一個EventEmitter對象的實例。下面這篇文章給大家介紹了Node.js中process模塊常用的屬性和方法,有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-12-12
  • linux 下以二進制的方式安裝 nodejs

    linux 下以二進制的方式安裝 nodejs

    這篇文章主要介紹了linux 下以二進制的方式安裝 nodejs,文中給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • Node8中AsyncHooks異步生命周期

    Node8中AsyncHooks異步生命周期

    這篇文章主要介紹了Node8中AsyncHooks異步生命周期,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Node.js中的package.json與cnpm命令行工具介紹

    Node.js中的package.json與cnpm命令行工具介紹

    這篇文章介紹了Node.js中的package.json與cnpm命令行工具,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • Node.js中package.json中庫的版本號(~和^)

    Node.js中package.json中庫的版本號(~和^)

    這篇文章主要介紹了Node.js中package.json中庫的版本號(~和^),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • Nodejs使用express連接數(shù)據(jù)庫mongoose的示例

    Nodejs使用express連接數(shù)據(jù)庫mongoose的示例

    數(shù)據(jù)庫并進行操作通常需要使用第三方庫,其中最流行的是mongoose,本文主要介紹了Nodejs使用express連接數(shù)據(jù)庫mongoose的示例,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06
  • 淺談Node.js 子進程與應用場景

    淺談Node.js 子進程與應用場景

    這篇文章主要介紹了淺談Node.js 子進程與應用場景,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01

最新評論