国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

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

2019-11-19 18:18:07
字體:
來源:轉載
供稿:網友

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

1、net模塊基本API

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

Server和Socket類、工廠方法。

Server類如下圖所示:

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

Socket類如下:


net.Socket類一般用創建一個socket客戶端或者是net.Server connection事件的參數。

工廠方法如下:

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

服務端:

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

客戶端:

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

如下圖所示:

2、聊天室的設計和實現

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

  1. 用戶自定義昵稱,不可更改
  2. 當有新的用戶進入聊天室,或者用戶離開聊天室,廣播給其他用戶
  3. 用戶發送信息,需廣播給其他用戶
  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);//啟動監聽/** * 處理用戶信息 */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);//產生用戶ID client.write(`歡迎你,${msg.nick}:這里總共有${Object.keys(clients).length}個小伙伴在聊天./r/n`) client.nick = msg.nick; client.uuid = uuid; clients[uuid] = client; broadcast(`系統:${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(`請輸入昵稱:`);//監聽命令行輸入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}`); });}/** * 創建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);}

執行結果如下如下:

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

總結

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建瓯市| 增城市| 三亚市| 沧源| 吉安县| 新邵县| 光泽县| 门头沟区| 教育| 海伦市| 当阳市| 松滋市| 定州市| 阜城县| 皮山县| 丰县| 修水县| 长垣县| 西贡区| 水城县| 新邵县| 凤凰县| 灵武市| 渭源县| 博野县| 文水县| 丹巴县| 长海县| 呼玛县| 吉安市| 扎赉特旗| 鹤山市| 登封市| 张家川| 灵武市| 纳雍县| 高州市| 赤壁市| 北安市| 宁河县| 兴宁市|