最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nodejs實(shí)現(xiàn)多房間簡(jiǎn)易聊天室功能

 更新時(shí)間:2017年06月20日 10:20:40   作者:煩囂的人  
本文通過實(shí)例代碼給大家介紹了Nodejs實(shí)現(xiàn)多房間簡(jiǎn)易聊天室功能,需要的朋友參考下吧

1、前端界面代碼

  前端不是重點(diǎn),夠用就行,下面是前端界面,具體代碼可到github下載。

2、服務(wù)器端搭建

  本服務(wù)器需要提供兩個(gè)功能:http服務(wù)和websocket服務(wù),由于node的事件驅(qū)動(dòng)機(jī)制,可將兩種服務(wù)搭建在同一個(gè)端口下。

  1、包描述文件:package.json,這里用到了兩個(gè)依賴項(xiàng),mime:確定靜態(tài)文件mime類型,socket.io:搭建websocket服務(wù),然后使用npm install  安裝依賴

{
 "name": "chat_room",
 "version": "1.0.0",
 "description": "this is a room where you can chat with your friends",
 "main": "index.js",
 "scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
 },
 "author": "sfs",
 "license": "ISC",
 "dependencies": {
  "socket.io":"2.0.3",
  "mime":"1.3.6"
 }
}

  2、http服務(wù)器

  http服務(wù)主要是給web瀏覽器提供靜態(tài)文件,既瀏覽器發(fā)來(lái)一個(gè)請(qǐng)求,服務(wù)器返回一個(gè)響應(yīng)。

const 
  http=require('http'),
  fs=require('fs'),
  path=require('path'),
  mime=require('mime'),
  chatServer=require('./lib/chat_server');

var cache={};//緩存靜態(tài)文件內(nèi)容
//發(fā)送錯(cuò)誤響應(yīng)
function send404(response){
  response.writeHead(404,{'Content-Type':'text/plain'});
  response.write('Error 4.4:文件未找到。');
  response.end();
}
//發(fā)送文件內(nèi)容
function sendFile(response,filePath,fileContents){
  response.writeHead(
    200,
    {"content-Type":mime.lookup(path.basename(filePath))}
  );
  response.end(fileContents);
}
//查找文件
function serveStatic(response,cache,absPath){
  if(cache[absPath]){
    sendFile(response,absPath,cache[absPath]);
  }else{
    fs.exists(absPath,function(exists){
      if(exists){
        fs.readFile(absPath,function(err,data){
          if(err){
            send404(response);
          }else{
            cache[absPath]=data;
            sendFile(response,absPath,data);
          }
        });
      }else{
        send404(response);
      }
    });
  }
}
//入口
var server=http.createServer(function(request,response){
  var filePath=false;
  console.log(`new request for ${request.url}`);
  if(request.url==='/'){
    filePath='public/index.html';
  }else{
    filePath='public'+request.url;
  }

  var absPath='./'+filePath;
  serveStatic(response,cache,absPath);
});
server.listen(3000,function(){
  console.log("the server is listening on prot 3000.");
});
chatServer.listen(server); //websocket服務(wù)也綁定到該端口上

  3、socket服務(wù)

  socket.io提供了開箱既用的虛擬通道,所以不需要任務(wù)手動(dòng)轉(zhuǎn)發(fā)消息到已連接的的用戶,可以使用 socket.broadcast.to(room).emit('message','hello'); room為某個(gè)聊天室id

const 
  socketio=require('socket.io');
var io,
  guestNumber=1, //用戶編號(hào)
  nickNames={},  //socket id對(duì)應(yīng)的nickname
  namesUsed={},  //所有已使用的nickname
  allRooms={},  //聊天室--人數(shù)
  currentRoom={}; //sockid--聊天室
module.exports.listen=function(server){
  io=socketio.listen(server);
  io.serveClient('log level',1);
  io.sockets.on('connection',function(socket){
    guestNumber=assignGuestName(socket,guestNumber,nickNames);
    joinRoom(socket,'Lobby');
    handleMessageBroadcasting(socket,nickNames);
    handleNameChangeAttempts(socket,nickNames,namesUsed);
    handleRoomJoining(socket);
    socket.on('rooms',function(){
      socket.emit('rooms',JSON.stringify(allRooms));
    });
    handleClientDisconnection(socket,nickNames,namesUsed);
  });
};
//新socket連入,自動(dòng)分配一個(gè)昵稱
function assignGuestName(socket,guesetNumber,nickNames){
  var name='Guest'+guestNumber;
  nickNames[socket.id]=name;
  socket.emit('nameResult',{
    success:true,
    name:name
  });
  namesUsed[name]=1;
  return guestNumber+1;
}
//加入某個(gè)聊天室
function joinRoom(socket,room){
  socket.join(room);
  var num=allRooms[room];
  if(num===undefined){
    allRooms[room]=1;
  }else{
    allRooms[room]=num+1;
  }
  currentRoom[socket.id]=room;
  socket.emit('joinResult',{room:room});
  socket.broadcast.to(room).emit('message',{
    text:nickNames[socket.id]+' has join '+room+'.'
  });
  var usersinRoom=io.sockets.adapter.rooms[room];
  if(usersinRoom.length>1){
    var usersInRoomSummary='Users currently in '+room+' : ';
    for(var index in usersinRoom.sockets){
      if(index!=socket.id){
        usersInRoomSummary+=nickNames[index]+',';
      }
    }
    socket.emit('message',{text:usersInRoomSummary}); 
  }
}
//修改昵稱
function handleNameChangeAttempts(socket,nickNames,namesUsed){
  socket.on('nameAttempt',function(name){
    if(name.indexOf('Guest')==0){
      socket.emit('nameResult',{
        success:false,
        message:'Names cannot begin with "Guest".'
      });
    }else{
      if(namesUsed[name]==undefined){
        var previousName=nickNames[socket.id];
        delete namesUsed[previousName];
        namesUsed[name]=1;
        nickNames[socket.id]=name;
        socket.emit('nameResult',{
          success:true,
          name:name
        });
        socket.broadcast.to(currentRoom[socket.id]).emit('message',{
          text:previousName+' is now known as '+name+'.'
        });
      }else{
        socket.emit('nameResult',{
          success:false,
          message:'That name is already in use.' 
        });
      }
    }
  });                                    
}
//將某個(gè)用戶的消息廣播到同聊天室下的其他用戶
function handleMessageBroadcasting(socket){
  socket.on('message',function(message){
    console.log('message:---'+JSON.stringify(message));
    socket.broadcast.to(message.room).emit('message',{
      text:nickNames[socket.id]+ ': '+message.text
    });
  });
}
//加入/創(chuàng)建某個(gè)聊天室
function handleRoomJoining(socket){
  socket.on('join',function(room){
    var temp=currentRoom[socket.id];
    delete currentRoom[socket.id];
    socket.leave(temp);
    var num=--allRooms[temp];
    if(num==0)
      delete allRooms[temp];
    joinRoom(socket,room.newRoom);
  });
}
//socket斷線處理
function handleClientDisconnection(socket){
  socket.on('disconnect',function(){
    console.log("xxxx disconnect");
    allRooms[currentRoom[socket.id]]--;
    delete namesUsed[nickNames[socket.id]];
    delete nickNames[socket.id];
    delete currentRoom[socket.id];
  })
}

3、客戶端實(shí)現(xiàn)socket.io

  1、chat.js處理發(fā)送消息,變更房間,聊天命令。

var Chat=function(socket){
  this.socket=socket;//綁定socket
}
//發(fā)送消息
Chat.prototype.sendMessage=function(room,text){
  var message={
    room:room,
    text:text
  };
  this.socket.emit('message',message);
};
//變更房間
Chat.prototype.changeRoom=function(room){
  this.socket.emit('join',{
    newRoom:room
  });
};
//處理聊天命令
Chat.prototype.processCommand=function(command){
  var words=command.split(' ');
  var command=words[0].substring(1,words[0].length).toLowerCase();
  var message=false;
  switch(command){
    case 'join':
      words.shift();
      var room=words.join(' ');
      this.changeRoom(room);
      break;
    case 'nick':
      words.shift();
      var name=words.join(' ');
      this.socket.emit('nameAttempt',name);
      break;
    default:
      message='Unrecognized command.';
      break;
  }
  return message;
};

  2、chat_ui.js 處理用戶輸入,根據(jù)輸入調(diào)用chat.js的不同方法發(fā)送消息給服務(wù)器

function divEscapedContentElement(message){
  return $('<div></div>').text(message);
}
function divSystemContentElement(message){
  return $('<div></div>').html('<i>'+message+'</i>');
}
function processUserInput(chatApp,socket){
  var message=$('#send-message').val();
  var systemMessage;
  if(message.charAt(0)=='/'){
    systemMessage=chatApp.processCommand(message);
    if(systemMessage){
      $('#messages').append(divSystemContentElement(systemMessage));
    }
  }else{
    chatApp.sendMessage($('#room').text(),message);
    $('#messages').append(divSystemContentElement(message));
    $('#messages').scrollTop($('#messages').prop('scrollHeight'));
  }
  $('#send-message').val('');
}

  3、init.js客戶端程序初始化   創(chuàng)建一個(gè)websocket連接,綁定事件。

if(window.WebSocket){
  console.log('This browser supports WebSocket');
}else{
  console.log('This browser does not supports WebSocket');
}
var socket=io.connect();
$(document).ready(function(){
  var chatApp=new Chat(socket);
  socket.on('nameResult',function(result){
    var message;
    if(result.success){
      message='You are known as '+result.name+'.';
    }else{
      message=result.message;
    }
    console.log("nameResult:---"+message);
    $('#messages').append(divSystemContentElement(message));
    $('#nickName').text(result.name);
  });
  socket.on('joinResult',function(result){
    console.log('joinResult:---'+result);
    $('#room').text(result.room);
    $('#messages').append(divSystemContentElement('Room changed.'));
  });
  socket.on('message',function(message){
    console.log('message:---'+message);
    var newElement=$('<div></div>').text(message.text);
    $('#messages').append(newElement);
    $('#messages').scrollTop($('#messages').prop('scrollHeight'));
  });
  socket.on('rooms',function(rooms){
    console.log('rooms:---'+rooms);
    rooms=JSON.parse(rooms);
    $('#room-list').empty();
    for(var room in rooms){
      $('#room-list').append(divEscapedContentElement(room+':'+rooms[room]));
    }
    $('#room-list div').click(function(){
      chatApp.processCommand('/join '+$(this).text().split(':')[0]);
      $('#send-message').focus();
    });
  });
  setInterval(function(){
    socket.emit('rooms');
  },1000);
  $('#send-message').focus();
  $('#send-button').click(function(){
    processUserInput(chatApp,socket);
  });
});

完整代碼,可到https://github.com/FleyX/ChatRoom 下載。

以上所述是小編給大家介紹的Nodejs實(shí)現(xiàn)多房間簡(jiǎn)易聊天室功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Nodejs全局安裝和本地安裝的不同之處

    Nodejs全局安裝和本地安裝的不同之處

    這篇文章主要介紹了Nodejs全局安裝和本地安裝的不同之處的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Windows上node.js的多版本管理工具用法實(shí)例分析

    Windows上node.js的多版本管理工具用法實(shí)例分析

    這篇文章主要介紹了Windows上node.js的多版本管理工具用法,結(jié)合實(shí)例形式分析了Windows平臺(tái)上node.js多版本管理工具nvm-windows的相關(guān)使用技巧,需要的朋友可以參考下
    2019-11-11
  • 什么是Node.js?Node.js詳細(xì)介紹

    什么是Node.js?Node.js詳細(xì)介紹

    這篇文章主要介紹了什么是Node.js,Node.js能做什么,Node.js的優(yōu)缺點(diǎn),Node.js的例子等,需要的朋友可以參考下
    2014-06-06
  • nodejs中各種加密算法的實(shí)現(xiàn)詳解

    nodejs中各種加密算法的實(shí)現(xiàn)詳解

    這篇文章主要給大家介紹了關(guān)于nodejs中各種加密算法的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用nodejs具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Dapr+NestJs編寫Pub及Sub裝飾器實(shí)戰(zhàn)示例

    Dapr+NestJs編寫Pub及Sub裝飾器實(shí)戰(zhàn)示例

    這篇文章主要為大家介紹了Dapr+NestJs編寫Pub及Sub裝飾器的實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • node.js中的buffer.Buffer.byteLength方法使用說(shuō)明

    node.js中的buffer.Buffer.byteLength方法使用說(shuō)明

    這篇文章主要介紹了node.js中的buffer.Buffer.byteLength方法使用說(shuō)明,本文介紹了buffer.Buffer.byteLength的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • 我的Node.js學(xué)習(xí)之路(二)NPM模塊管理

    我的Node.js學(xué)習(xí)之路(二)NPM模塊管理

    npm 是 Node.js 的模塊依賴管理工具。作為開發(fā)者使用的工具,主要解決開發(fā) Node.js 時(shí)會(huì)遇到的問題。如同 RubyGems 對(duì)于 Ruby 開發(fā)者和 Maven 對(duì)于 Java 開發(fā)者的重要性,npm 對(duì)與 Node.js 的開發(fā)者和社區(qū)的重要性不言而喻。
    2014-07-07
  • node進(jìn)程管理工具PM2用法詳解

    node進(jìn)程管理工具PM2用法詳解

    本文詳細(xì)講解了node進(jìn)程管理工具PM2的用法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • node+socket實(shí)現(xiàn)簡(jiǎn)易聊天室功能

    node+socket實(shí)現(xiàn)簡(jiǎn)易聊天室功能

    這篇文章主要為大家詳細(xì)介紹了node+socket實(shí)現(xiàn)簡(jiǎn)易聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Koa日志中間件封裝開發(fā)詳解

    Koa日志中間件封裝開發(fā)詳解

    這篇文章主要介紹了Koa日志中間件封裝開發(fā)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評(píng)論

雷波县| 金溪县| 前郭尔| 北票市| 鹿泉市| 永嘉县| 依安县| 广灵县| 浪卡子县| 镇赉县| 彭州市| 香河县| 新宾| 理塘县| 景德镇市| 清水河县| 鄢陵县| 长顺县| 华亭县| 瓮安县| 寻甸| 福贡县| 吉水县| 修武县| 灵石县| 嘉善县| 隆尧县| 罗甸县| 漳州市| 郎溪县| 拜城县| 太仆寺旗| 仲巴县| 嘉荫县| 清镇市| 平遥县| 博罗县| 娱乐| 安义县| 平南县| 台中市|