教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

web前端開(kāi)發(fā)培訓(xùn)之如何實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)隨機(jī)匹配聊天

更新時(shí)間:2016年10月13日10時(shí)44分 來(lái)源:傳智播客前端與移動(dòng)開(kāi)發(fā)學(xué)院 瀏覽次數(shù):

真心佩服那些可以經(jīng)常發(fā)布筆記的人,其實(shí)我也想經(jīng)常發(fā)來(lái)的,奈何技術(shù)不夠加上懶,要向大神們多多學(xué)習(xí)了,前段時(shí)間有用bomb平臺(tái)自帶的socket寫(xiě)一個(gè)聊天室,其實(shí)基本就是改了改它的demo,這次想實(shí)現(xiàn)一個(gè)隨機(jī)私聊,所以自己基于node 和 socket.io 來(lái)搭服務(wù),當(dāng)然,第一次用node做東西玩,雖然做的不好,但是也蠻分享下哈。
    下面是demo地址,可以自己開(kāi)兩個(gè)網(wǎng)頁(yè)和自己聊天看效果哦~

    基于node和socket的隨機(jī)匹配聊天
    先說(shuō)說(shuō)用到的東西, node 用來(lái)做后臺(tái)服務(wù),express 用來(lái)托管靜態(tài)資源,然后socket.io 用來(lái)傳送聊天數(shù)據(jù)。接下來(lái)說(shuō)說(shuō)思路,其實(shí)用socket.io來(lái)傳數(shù)據(jù)是很簡(jiǎn)單的一件事情,我們只需要再前端頁(yè)面引入 socket.io.js  然后再node端也require('socket.io'),把它在后端跑起來(lái),那么前端就可以通過(guò)如下代碼來(lái)發(fā)送或者接收信息。//前端
  1. socket = io.connect('ws://'+'服務(wù)器ip');
  2. socket.emit('msg',{msg:'前端要發(fā)送的信息'});//要發(fā)送的信息(以對(duì)象的形式發(fā)送)
  3. socket.on('msg2',function(data){
  4.     ...
  5.     //這里的data是后端傳過(guò)來(lái)的信息
  6. })
  7. //后端
  8. socket.on('msg',function(data){
  9.     var data = data; //這里的data就是前端傳過(guò)來(lái)的數(shù)據(jù),即{msg:'前端要發(fā)送的信息'}
  10.     console.log(data.msg) // 打印出 “前端要發(fā)送的信息”
  11. })
  12. //同理,后端要傳信息給前端也是一樣
  13. socket.emit('msg2',{msg:'后端要發(fā)送的信息'})

    我們來(lái)看后端怎么把socket跑起來(lái)
  1. var express = require('express');
  2. var app = express();
  3. var http = require('http').Server(app);
  4. var io = require('socket.io')(http);
  5. io.on('connection', function(socket){ //當(dāng)前端執(zhí)行 socket = io.connect('ws://'+host); 的時(shí)候,此處的io會(huì)監(jiān)聽(tīng)到connection事件
  6.         socket.on('msg',function(data){
  7.                 io.emit('onlineCount',freeList)
  8.                 //如果直接用io.emit來(lái)發(fā)送數(shù)據(jù)的話,這代表廣播的形式,就是當(dāng)前所有打開(kāi)服務(wù)的前端頁(yè)面都會(huì)收到這條消息。
  9.         
  10.             socket.emit('welcome',{msg:'歡迎...'})//這里將給當(dāng)前連接的頁(yè)面發(fā)送一個(gè)歡迎的對(duì)象數(shù)據(jù)
  11.         })
  12.         socket.on('disconnect',function(){
  13.                 //當(dāng)前端頁(yè)面關(guān)閉,或者失去連接時(shí),后端會(huì)接收到disconnect事件
  14.             
  15.         })
  16. })
  17. http.listen(4000, function(){
  18.         console.log('listening on *:4000');
  19. });

    當(dāng)然不僅如此,因?yàn)閣ebsocket協(xié)議,是在瀏覽器和服務(wù)器之間建立了一個(gè)長(zhǎng)鏈接來(lái)相互傳輸數(shù)據(jù),對(duì)服務(wù)器而言,如果打開(kāi)了好幾個(gè)頁(yè)面,那么就有好幾個(gè)socket實(shí)例,每個(gè)建立連接的前端頁(yè)面都會(huì)有一個(gè)socket實(shí)例,這樣就為接下來(lái)的點(diǎn)對(duì)點(diǎn)私聊提供了思路。當(dāng)然,我們也可以通過(guò)直接廣播來(lái)傳送信息,不過(guò)這適用于聊天室情景。
    那如何實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)呢,之前說(shuō)了,每個(gè)建立連接的頁(yè)面都會(huì)產(chǎn)生一個(gè)socket實(shí)例,那么我們只需要后端在接收消息的同時(shí),判斷該socket實(shí)例是和哪個(gè)個(gè)實(shí)例在聊天,只把消息發(fā)送給另一個(gè)匹配的socket實(shí)例就好了。簡(jiǎn)單來(lái)說(shuō)就像寫(xiě)信一樣,我把消息發(fā)送給后端,然后告訴后端,這個(gè)消息是給xxx的,然后后端找到xxx對(duì)應(yīng)的socket實(shí)例,將消息發(fā)給他就好了。

  1. //前端
  2. window.id = new Date().getTime()+""+Math.floor(Math.random()*899+100);
  3. //每次登錄,獲取一個(gè)唯一的用戶id
  4. socket = io.connect('ws://'+host);
  5. socket.emit('newUser',{ user_name : name, user_id : id})
  6. //建立連接后,將我的用戶名和id都傳給后端
  7. //后端
  8. socket.on('newUser',function(data){
  9.                 var nickname = data.user_name,
  10.                         user_id = data.user_id;
  11.                 userServer[user_id] = socket;
  12.                 //后端接收后,將該用戶socket保存在一個(gè)對(duì)象里,key值為id,value就是這個(gè)用戶的socket
  13.    
  14. })
    通過(guò)上面的代碼,后端得到了一個(gè)userServer的對(duì)象,里面是每個(gè)連接socket和其id的對(duì)應(yīng)值,這樣,就可以通過(guò)每次發(fā)送信息時(shí),附帶要接收對(duì)象的id來(lái)達(dá)到點(diǎn)對(duì)點(diǎn)的數(shù)據(jù)傳輸。
    接下來(lái)就是數(shù)據(jù)處理咯,如何取到對(duì)方的id啊等等,鑒于我表達(dá)能力有限,加上懶,就不啰嗦啦~~ 代碼我都托管在github歡迎自己下下來(lái)看咯~



本文版權(quán)歸傳智播客web前端開(kāi)發(fā)培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處,謝謝!
作者:傳智播客web前端開(kāi)發(fā)培訓(xùn)學(xué)院
首發(fā):http://xamj520.com/web/
0 分享到:
和我們?cè)诰€交談!