日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Nodejs]初探nodejs学习笔记- 如何使用nodejs搭建简单的UDP聊天功能

發布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Nodejs]初探nodejs学习笔记- 如何使用nodejs搭建简单的UDP聊天功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

何為UDP(User Datagram Protocol)?

從baidu摘過來一段:UDP,用戶數據報協議,與所熟知的TCP(傳輸控制協議)協議一樣,UDP協議直接位于IP(網際協議)協議的頂層。根據OSI(開放系統互連)參考模型,UDP和TCP都屬于傳輸層協議。UDP協議的主要作用是將網絡數據流量壓縮成數據包的形式。一個典型的數據包就是一個二進制數據的傳輸單位。每一個數據包的前8個字節用來包含報頭信息,剩余字節則用來包含具體的傳輸數據。

UDP報文沒有可靠性保證、順序保證和流量控制字段等,可靠性較差。但是正因為UDP協議的控制選項較少,在數據傳輸過程中延遲小、數據傳輸效率高,適合對可靠性要求不高的應用程序,或者可以保障可靠性的應用程序,如DNS、TFTP、SNMP等。

好了,接下來簡要說明一下我實現的效果:

????????? ????? 防工具盜鏈抓取【如果顯示此文字,代表來自第三方轉發】 freddon所有? ??? ???????????

有Fred、Lenka、Nick三個人,均處于同一聊天室中:

即:Nick發的消息,Fred、Lenka均能收到;

????? ?Fred、Lenka只能互相發消息。

OK,就這么簡單。為了說明問題,就不過度封裝代碼,以說明為主。

????????? ????? 防工具盜鏈抓取【如果顯示此文字,代表來自第三方轉發】 freddon所有? ??? ???????????

Server端:

server.js
var?udp?=?require('dgram');var?server?=?udp.createSocket('udp4');/***?用于存儲人員之間的離線消息任務*?@type?{{tasks:?Array}}*/ var?msgTask?=?{//config:?{},tasks:?[] };/***?存醋當前在線的用戶*?@type?{{online:?Array,?pool:?Array}}*/ var?userPool?=?{online:?[],pool:?[] };/***?加入某個用戶的在線狀態*?@param?name*?@param?rinfo*/ var?pushIntoPool?=?function?(name,?rinfo)?{var?index?=?userPool.online.indexOf(name);if?(index?>=?0)?{userPool.online.splice(index,?1);userPool.pool.splice(index,?1);}userPool.online.push(name);userPool.pool.push({name:?name,?ip:?rinfo.address,?port:?rinfo.port}); };/***?移除在線狀態*?@param?name*/ var?pullFromPool?=?function?(name)?{var?index?=?userPool.online.indexOf(name);if?(index?>=?0)?{userPool.online.splice(index,?1);userPool.pool.splice(index,?1);return;} };/***?加入離線消息任務*?@param?msg*/ var?addInTask?=?function?(msg)?{msgTask.tasks.push({msg:?msg,?expireTime:?7?*?24?*?3600?+?new?Date().getTime()}); };/***?發送消息*?@param?m*?@param?rinfo*/ var?sendMsg?=?function?(m,?rinfo)?{process.nextTick(function?()?{if?(m.to){//獲取對方的服務地址\端口var?index?=?userPool.online.indexOf(m.to.name);if?(index?>=?0)?{//在線var?config?=?userPool.pool[index];var?msg?=?JSON.stringify(m);server.send(msg,?0,?Buffer.byteLength(msg,?encoding?=?'utf8'),?config.port,?config.ip,?function?(err,?bytes)?{if?(err)?{//發送失敗//緩存數據addInTask(m);}});}?else?{if?(rinfo)?{//離線var?content?=?JSON.stringify({content:?m.to.name?+?'不在線'});server.send(content,?0,?Buffer.byteLength(content,?encoding?=?'utf8'),?rinfo.port,?rinfo.address,?function?(err,?bytes)?{if?(err)?{//發送失敗}});}//不在線pullFromPool(m.to.name);//緩存數據addInTask(m);}}?else?{//群聊for?(var?i?=?0;?i?<?userPool.pool.length;?i++)?{var?to_cfg?=?userPool.pool[i];if?(to_cfg.name?==?m.from.name)?{continue;}?else?{var?msg?=?JSON.stringify(m);server.send(msg,?0,?Buffer.byteLength(msg,?encoding?=?'utf8'),?to_cfg.port,?to_cfg.ip,?function?(err,?bytes)?{if?(err)?{//發送失敗}});}}}}); };/***?后臺輪詢任務*/ var?backgroundTask?=?function?()?{for?(var?i?=?0;?i?<?msgTask.tasks.length;?i++)?{var?m?=?msgTask.tasks.splice(i,?1)[0];sendMsg(m.msg);}beginTask(); };var?tid;var?beginTask?=?function?()?{clearTimeout(tid);tid?=?setTimeout(backgroundTask,?1000); };server.on('message',?function?(msg,?rinfo)?{//注意msg為Buffer對象var?m?=?JSON.parse(msg.toString());pushIntoPool(m.from.name,?rinfo);if?(m.action?==?'online')?{console.log('當前聊天室在線人數%d::%s',?userPool.online.length,userPool.online.join(","));return;}//發送消息sendMsg(m,?rinfo); }).bind(8124,?function?()?{console.log('服務端啟動成功');//當服務啟動后,開啟后臺消息輪詢服務beginTask(); });

Client端:

Fred.js 用戶fred
var?udp=require('dgram'); var?mm=require('./msgmodel'); var?client=udp.createSocket('udp4'); var?from={name:'Fred',host:client.address,port:client.remotePort,content:'' }; var?msg=new?mm.FMsg(from); process.stdin.resume(); process.stdin.on('data',function(data){msg.setAction('chat');msg.setContent(data.toString('utf8'));//設置只能發送給Lenkamsg.setTo({name:'Lenka'});msg.udpSendMsg(client,function(err,bytes){if(err){//發送失敗}});}); client.on('message',function(data){var?data=JSON.parse(data.toString());if(!data.from){console.log(data.content);}else{if(!data.to){console.log("[%s]:%s",data.from.name,data.content);}else{console.log("[%s@%s]:%s",data.from.name,data.to.name,data.content);}} }); //默認連接后上線操作 msg.udpSendMsg(client,function(err,bytes){if(err==0){console.log("Fred上線!");} });
Lenka.js 用戶Lenka
var?udp=require('dgram'); var?mm=require('./msgmodel'); var?client=udp.createSocket('udp4'); var?from={name:'Lenka',host:client.address,port:client.remotePort,content:'' }; var?msg=new?mm.FMsg(from); process.stdin.resume(); process.stdin.on('data',function(data){msg.setAction('chat');msg.setContent(data.toString('utf8'));//設置只能發送給Fredmsg.setTo({name:'Fred'});msg.udpSendMsg(client,function(err,bytes){if(err){//發送失敗}});}); client.on('message',function(data){var?data=JSON.parse(data.toString());if(!data.from){console.log(data.content);}else{if(!data.to){console.log("[%s]:%s",data.from.name,data.content);}else{console.log("[%s@%s]:%s",data.from.name,data.to.name,data.content);}} }); //默認連接后上線操作 msg.udpSendMsg(client,function(err,bytes){if(err==0){console.log("Lenka上線!");} });
Nick.js 用戶Nick
var?udp=require('dgram'); var?mm=require('./msgmodel'); var?client=udp.createSocket('udp4'); var?from={name:'Nick',host:client.address,port:client.remotePort,content:'' }; var?msg=new?mm.FMsg(from); process.stdin.resume(); process.stdin.on('data',function(data){msg.setAction('chat');msg.setContent(data.toString('utf8'));//不設置發送給誰,默認發送給所有人msg.udpSendMsg(client,function(err,bytes){if(err){//發送失敗}});}); client.on('message',function(datas){var?data=JSON.parse(data.toString());if(!data.from){console.log(data.content);}else{if(!data.to){console.log("[%s]:%s",data.from.name,data.content);}else{console.log("[%s@%s]:%s",data.from.name,data.to.name,data.content);}} }); //默認連接后上線操作 msg.udpSendMsg(client,function(err,bytes){if(err==0){console.log("Nick上線!");} });

消息類msgmodel.js??

var?host?=?'127.0.0.1';//需要連接到服務器提供udp連接的ip var?port?=?8124;//需要連接到服務器提供udp連接的端口 var?ACTIONS=['online','chat','request','stranger','del','offline']; function?FMsg(from,?to,?content)?{this.from?=?from;this.to?=?to;this.content?=?content;this.action?=?'online';this.setAction?=?function?(action)?{this.action?=?action;};this.setTo?=?function?(to)?{this.to?=?to;};this.setContent?=?function?(content)?{this.content?=?content;};this.getMsg?=?function?()?{var?msg?=?{from:?this.from,to:?this.to,content:?this.content,action:this.action};return?JSON.stringify(msg);};this.udpSendMsg?=?function?(client,?callback)?{var?data?=?this.getMsg();client.send(data,?0,?Buffer.byteLength(data,encoding='utf8'),?port,?host,?callback);}; } exports.FMsg?=?FMsg;


接下來分別使用nodejs啟動服務端和客戶端。

啟動服務端后,只啟動Fred、Lenka中的一個(比如說啟動了Fred):

在Fred控制臺進行如下輸入:(Lenka不在線,所以該消息未發送成功)

然后啟動Lenka,(Lenka收到了離線消息)Lenka的控制臺為:

啟動Nick,Nick說話,然后觀察其他兩個客戶端,

server:

nick:

fred:


lenka:


Lenka、Fred說話,觀察Nick控制臺:

Lenka:

fred:

nick:




好啦,相當簡單的一個點對點和聊天室的功能就這樣搭好了。

????????? ????? 防工具盜鏈抓取【如果顯示此文字,代表來自第三方轉發】 freddon所有? ??? ???????????


轉載請注明:http://my.oschina.net/freddon/blog/518328





轉載于:https://my.oschina.net/freddon/blog/518328

總結

以上是生活随笔為你收集整理的[Nodejs]初探nodejs学习笔记- 如何使用nodejs搭建简单的UDP聊天功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。