nodejs 服務(wù)器&telnet 實(shí)現(xiàn)區(qū)分多客戶端請求服務(wù)

緣由:因有多個(gè)客戶端會不定期的與服務(wù)器端建立聯(lián)系,想要區(qū)分哪個(gè)客戶端來完成相應(yīng)的處理

原版代碼:

var net = require('net');//1 引入net模塊  
var chatServer = net.createServer();//創(chuàng)建net服務(wù)器  
var clientList=[];//保存多個(gè)客戶端的數(shù)組  
chatServer.on('connection', function (client) {//服務(wù)器連接客戶端  
    client.name=client.remoteAddress+':'+client.remotePort;  
    /*增加name屬性*/  
    client.write('Hi'+client.name+'!\n');  
    clientList.push(client);  
    client.on('data', function (data) {  
    /*添加事件監(jiān)聽器,這樣就可以訪問到連接事件所對應(yīng)的client對象,當(dāng)client發(fā)送數(shù)據(jù)給服務(wù)器時(shí),這一事件就會觸發(fā)*/  
        for(var i=0;i<clientList.length;i++){  
            if(clientList[i]!==this){  
                // 把數(shù)據(jù)發(fā)送給其他客戶端  
                clientList[i].write(this.name+"says "+data);  
            }  
        }  
    });  
});  
chatServer.listen(9000, "127.0.0.1");//服務(wù)器端口

注意:這里有個(gè)坑——如果有個(gè)客戶端斷開連接,那么所有人都會玩完!
因?yàn)槿绻偻?wù)器發(fā)送消息,這時(shí)候服務(wù)器并不知道某個(gè)客戶端已經(jīng)斷開了連接,因此會繼續(xù)向其發(fā)送數(shù)據(jù),但是這時(shí)斷開的這個(gè)客戶端對應(yīng)的socket已經(jīng)無法寫入數(shù)據(jù),而對已關(guān)閉的socket進(jìn)行write()操作node程序會拋出異常,進(jìn)而導(dǎo)致全軍覆沒。所以,這個(gè)問題應(yīng)該從兩個(gè)方面來解決:
(1)當(dāng)客戶端斷開連接時(shí),通知服務(wù)器,將其從客戶端列表中移除,防止其調(diào)用write方法(V8引擎也會把響應(yīng)的socket對象作為垃圾回收,并釋放相應(yīng)的內(nèi)存);
(2)采用更保險(xiǎn)的方式調(diào)用write()方法。
改進(jìn)如下:

最后,監(jiān)聽客戶端關(guān)閉事件,并記錄錯(cuò)誤

var net = require('net');//1 引入net模塊  
var chatServer = net.createServer();//創(chuàng)建net服務(wù)器  
var clientList = [];//保存多個(gè)客戶端的數(shù)組  

chatServer.on('connection', function (client) {//服務(wù)器連接客戶端  
    // console.log(' client remoteAddress =' + client.remoteAddress);
    // console.log(' client remotePort = ' + client.remotePort);
    client.name = client.remoteAddress + ':' + client.remotePort;  

    /*增加name屬性*/  
    client.write('Hi' + client.name + '!\n');  
    // console.log(''client.name+'connected');
    clientList.push(client);  
    console.log('clientList length = ' + clientList.length);
    for(var i = 0; i<clientList.length; i++){
      console.log('client remoteAddress'+[i] + clientList[i].name);
    }
    client.on('data', function (data) {  
        /*添加事件監(jiān)聽器,這樣就可以訪問到連接事件所對應(yīng)的client對象,當(dāng)client發(fā)送數(shù)據(jù)給服務(wù)器時(shí),這一事件就會觸發(fā)*/  
       //廣播消息給其他客戶端  
        broadcast(data,client);  
    });  
  //監(jiān)聽客戶端終止  
    client.on('end',function(){  
        console.log(''+client.name+'quit');//如果某個(gè)客戶端斷開連接,node控制臺就會打印出來  
        clientList.splice(clientList.indexOf(client),1);  
    });  
    /*記錄錯(cuò)誤*/  
    client.on('error',function(e){  
        console.log(' error'+e);  
    });  
  
    function broadcast(message,client){  
        var cleanup=[];//斷開了的客戶端們  
        for (var i = 0; i < clientList.length; i++) {  
            if (clientList[i] !== client) {  
                //檢查socket的可寫狀態(tài)  
                if (clientList[i].writable) {  
                    // 把數(shù)據(jù)發(fā)送給其他客戶端  
                    clientList[i].write(client.name + "says " + message);  
                }else{  
                    /*socket不可寫,則將其從列表中移除*/  
                    cleanup.push(clientList[i]);  
                    clientList[i].destroy();  
                }  
            }  
        }  
        /*刪除掉服務(wù)器的客戶端數(shù)組中,已斷開的客戶端*/  
        for(var i=0;i<cleanup.length;i++){  
            clientList.splice(clientList.indexOf(cleanup[i]),1);  
        }  
    }  
});  
//服務(wù)器端口  
chatServer.listen(9000, function(){
    console.log("server bound : 9000");
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,680評論 19 139
  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個(gè)狀態(tài)的數(shù)量2)、lso...
    北辰青閱讀 9,732評論 0 11
  • iPhone的標(biāo)準(zhǔn)推薦是CFNetwork 庫編程,其封裝好的開源庫是 cocoa AsyncSocket庫,用它...
    Ethan_Struggle閱讀 2,365評論 2 12
  • 最近項(xiàng)目有這樣的需求,項(xiàng)目中有一個(gè)控制器顯示一個(gè)二維碼,然而把二維碼對準(zhǔn)打卡機(jī)掃描,經(jīng)常會因?yàn)樵谑彝夤庹諒?qiáng)烈、屏幕...
    Daeva_Song閱讀 4,077評論 1 1
  • 清晨,懶懶的,不想起來,躺在床上。這是久違的享受了。很久很久,已經(jīng)記不清有多久了,都是早早的就起床,多早呢,反正都...
    華客魯俊閱讀 166評論 0 3

友情鏈接更多精彩內(nèi)容