亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于Nodejs利用socket.io實現(xiàn)多人聊天室

 更新時間:2017年02月22日 09:38:01   作者:Newpidian  
這篇文章講述了websocket無到有,根據(jù)協(xié)議,分析數(shù)據(jù)幀的頭,進行構建websocket。雖然代碼短,但可以很好地體現(xiàn)websocket的原理。對nodejs利用socket 實現(xiàn)多人聊天室功能感興趣的朋友一起看看吧

socket.io簡介

在Html5中存在著這樣的一個新特性,引入了websocket,關于websocket的內(nèi)部實現(xiàn)原理可以看這篇文章,這篇文章講述了websocket無到有,根據(jù)協(xié)議,分析數(shù)據(jù)幀的頭,進行構建websocket。雖然代碼短,但可以很好地體現(xiàn)websocket的原理。

,這個特性提供了瀏覽器端和服務器端的基于TCP連接的雙向通道。但是并不是所有的瀏覽器都支持websocket特性,故為了磨平瀏覽器間的差異,為開發(fā)者提供統(tǒng)一的接口,引入了socket.io模塊。在不支持websoket的瀏覽器中,socket.io可以降級為其他的通信方式,比如有AJAX long polling ,JSONP Polling等。
模塊安裝

新建一個package.json文件,在文件中寫入如下內(nèi)容:

{
 "name": "socketiochatroom",
 "version": "0.0.1",
 "dependencies": {
 "socket.io": "*",
 "express":"*"
 }
}

npm install

執(zhí)行完這句,node將會從npm處下載socket.io和express模塊。

-

服務器端的實現(xiàn)

在文件夾中添加index.js文件,并在文件中寫入如下內(nèi)容:

/**
 * Created by bamboo on 2016/3/31.
 */
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function (req, res) {
 "use strict";
 res.end("<h1>socket server</h1>")
});
/*在線人員*/
var onLineUsers = {};
/* 在線人數(shù)*/
var onLineCounts = 0;
/*io監(jiān)聽到存在鏈接,此時回調(diào)一個socket進行socket監(jiān)聽*/
io.on('connection', function (socket) {
 console.log('a user connected');
 /*監(jiān)聽新用戶加入*/
 socket.on('login', function (user) {
  "use strict";
  //暫存socket.name 為user.userId;在用戶退出時候?qū)玫?
  socket.name = user.userId;
  /*不存在則加入 */
  if (!onLineUsers.hasOwnProperty(user.userId)) {
   //不存在則加入
   onLineUsers[user.userId] = user.userName;
   onLineCounts++;
  }
  /*一個用戶新加入,向所有客戶端監(jiān)聽login的socket的實例發(fā)送響應,響應內(nèi)容為一個對象*/
  io.emit('login', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user});
  console.log(user.userName, "加入了聊天室");//在服務器控制臺中打印么么么用戶加入到了聊天室
 });
 /*監(jiān)聽用戶退出聊天室*/
 socket.on('disconnect', function () {
  "use strict";
  if (onLineUsers.hasOwnProperty(socket.name)) {
   var user = {userId: socket.name, userName: onLineUsers[socket.name]};
   delete onLineUsers[socket.name];
   onLineCounts--;
   /*向所有客戶端廣播該用戶退出群聊*/
   io.emit('logout', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user});
   console.log(user.userName, "退出群聊");
  }
 })
 /*監(jiān)聽到用戶發(fā)送了消息,就使用io廣播信息,信息被所有客戶端接收并顯示。注意,如果客戶端自己發(fā)送的也會接收到這個消息,故在客戶端應當存在這的判斷,是否收到的消息是自己發(fā)送的,故在emit時,應該將用戶的id和信息封裝成一個對象進行廣播*/
 socket.on('message', function (obj) {
  "use strict";
  /*監(jiān)聽到有用戶發(fā)消息,將該消息廣播給所有客戶端*/
  io.emit('message', obj);
  console.log(obj.userName, "說了:", obj.content);
 });
});
/*監(jiān)聽3000*/
http.listen(3000, function () {
 "use strict";
 console.log('listening 3000');
});

運行服務器端程序

node index.js

輸出

listening 3000

此時在瀏覽器中打開localhost:3000會得到這樣的結果:

這里寫圖片描述

原因是在代碼中只對路由進行了如下設置

app.get('/', function (req, res) {
 "use strict";
 res.end("<h1>socket server</h1>")
});

服務器端主要是提供socketio服務,并沒有設置路由。

客戶端的實現(xiàn)

在客戶端建立如下的目錄和文件,其中json3.min.js可以從網(wǎng)上下載到。

client

- - - client.js
- - - index.html
- - - json3.min.js
- - - style.css

在index.html中

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="format-detection" content="telephone=no"/>
 <meta name="format-detection" content="email=no"/>
 <title>1301群聊</title>
 <link rel="stylesheet" type="text/css" href="./style.css"/>
 <script src="http://realtime.plhwin.com:3000/socket.io/socket.io.js"></script>
 <script src="./json3.min.js"></script>
</head>
<body>
<div id="loginbox">
 <div style="width: 260px;margin: 200px auto;">
  輸入你在群聊中的昵稱
  <br/>
  <br/>
  <input type="text" style="width:180px;" placeholder="請輸入用戶名" id="userName" name="userName"/>
  <input type="button" style="width: 50px;" value="提交" onclick="CHAT.userNameSubmit();"/>
 </div>
</div>
<div id="chatbox" style="display: none;">
 <div style="background: #3d3d3d;height: 28px;width: 100%;font-size: 12px">
  <div style="line-height: 28px;color:#fff;">
   <span style="text-align: left;margin-left: 10px;">1301群聊</span>
   <span style="float: right;margin-right: 10px"><span id="showUserName"></span>|
   <a href="javascript:;" onclick="CHAT.logout()" style="color: #fff;">退出</a></span>
  </div>
 </div>
 <div id="doc">
  <div id="chat">
   <div id="message" class="message">
    <div id="onLineCounts"
      style="background: #EFEFF4; font-size: 12px;margin-top: 10px;margin-left: 10px;color: #666;">
    </div>
   </div>
   <div class="input-box">
    <div class="input">
     <input type="text" maxlength="140" placeholder="輸入聊天內(nèi)容 " id="content" name="content" >
    </div>
    <div class="action">
     <button type="button" id="mjr_send" onclick="CHAT.submit();">提交</button>
    </div>
   </div>
  </div>
 </div>
</div>
<script type="text/javascript" src="./client.js"></script>
</body>
</html>

在client.js中

/**
 * Created by bamboo on 2016/3/31.
 */
 /*即時運行函數(shù)*/
(function () {
 "use strict";
 var d = document,
  w = window,
  dd = d.documentElement,
  db = d.body,
  dc = d.compatMode === "CSS1Compat",
  dx = dc ? dd : db,
  ec = encodeURIComponent,
  p = parseInt;
 w.CHAT = {
  msgObj: d.getElementById("message"),
  screenHeight: w.innerHeight ? w.innerHeight : dx.innerHeight,
  userName: null,
  userId: null,
  socket: null,
  /*滾動條始終在最底部*/
  scrollToBottom: function () {
   w.scrollTo(0, this.msgObj.clientHeight);
  },
  /*此處僅為簡單的刷新頁面,當然可以做復雜點*/
  logout: function () {
   // this.socket.disconnect();
   w.top.location.reload();
  },
  submit: function () {
   var content = d.getElementById('content').value;
   if (content != '') {
    var obj = {
     userId: this.userId,
     userName: this.userName,
     content: content
    };
    //如在服務器端代碼所說,此對象就行想要發(fā)送的信息和發(fā)送人組合成為對象一起發(fā)送。
    this.socket.emit('message', obj);
    d.getElementById('content').value = '';
   }
   return false;
  },
  /**客戶端根據(jù)時間和隨機數(shù)生成ID,聊天用戶名稱可以重復*/
  genUid: function () {
   return new Date().getTime() + "" + Math.floor(Math.random() * 889 + 100);
  },
  /*更新系統(tǒng)信息
  主要是在客戶端顯示當前在線人數(shù),在線人列表等,當有新用戶加入或者舊用戶退出群聊的時候做出頁面提示。*/
  updateSysMsg: function (o, action) {
   var onLineUsers = o.onLineUsers;
   var onLineCounts = o.onLineCounts;
   var user = o.user;
   //更新在線人數(shù)
   var userHtml = '';
   var separator = '';
   for (var key in onLineUsers) {
    if (onLineUsers.hasOwnProperty(key)) {
     userHtml += separator + onLineUsers[key];
     separator = '、';
    }
   }
   //插入在線人數(shù)和在線列表
   d.getElementById('onLineCounts').innerHTML = '當前共有' + onLineCounts + "在線列表: " + userHtml;
   //添加系統(tǒng)消息
   var html = '';
   html += '<div class="msg_system">';
   html += user.userName;
   html += (action === "login") ? "加入了群聊" : "退出了群聊";
   html += '</div>';
   var section = d.createElement('section');
   section.className = 'system J-mjrlinkWrap J-cutMsg';
   section.innerHTML = html;
   this.msgObj.appendChild(section);
   this.scrollToBottom();
  },
  /*用戶提交用戶名后,將loginbox設置為不顯示,將chatbox設置為顯示*/
  userNameSubmit: function () {
   var userName = d.getElementById('userName').value;
   if (userName != '') {
    d.getElementById('userName').value = '';
    d.getElementById('loginbox').style.display = 'none';
    d.getElementById('chatbox').style.display = 'block';
    this.init(userName);//調(diào)用init方法
   }
   return false;
  },
  //用戶初始化
  init: function (userName) {
   //隨機數(shù)生成uid
   this.userId = this.genUid();
   this.userName = userName;
   d.getElementById('showUserName').innerHTML = this.userName;//[newpidian]|[退出]
   this.scrollToBottom();
   //連接socketIO服務器,newpidian的IP地址
   this.socket = io.connect('192.168.3.155:3000');
   //向服務器發(fā)送某用戶已經(jīng)登錄了
   this.socket.emit('login', {userId: this.userId, userName: this.userName});
   //監(jiān)聽來自服務器的login,即在客戶端socket.emit('login ')發(fā)送后,客戶端就會收到來自服務器的
   // io.emit('login', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user});
   /*監(jiān)聽到有用戶login了,更新信息*/
   this.socket.on('login', function (o) {
    //更新系統(tǒng)信息
    CHAT.updateSysMsg(o, 'login');
   });
   /*監(jiān)聽到有用戶logout了,更新信息*/
   this.socket.on('logout', function (o) {
    CHAT.updateSysMsg(o, 'logout');
   });
   //var obj = {
   // userId: this.userId,
   // userName: this.userName,
   // content: content
   //};
   /*監(jiān)聽到有用戶發(fā)送消息了*/
   this.socket.on("message", function (obj) {
    //判斷消息是不是自己發(fā)送的
    var isMe = (obj.userId === CHAT.userId);
    var contentDiv = '<div>' + obj.content + '</div>';
    var userNameDiv = '<span>' + obj.userName + '</span>';
    var section = d.createElement('section');
    if (isMe) {
     section.className = 'user';
     section.innerHTML = contentDiv + userNameDiv;
    } else {
     section.className = 'service';
     section.innerHTML = userNameDiv + contentDiv;
    }
    CHAT.msgObj.appendChild(section);
    CHAT.scrollToBottom();
   });
  }
 }
 /*控制鍵鍵碼值(keyCode)
  按鍵 鍵碼 按鍵 鍵碼 按鍵 鍵碼 按鍵 鍵碼
  BackSpace 8 Esc 27 Right Arrow 39 -_ 189
  Tab 9 Spacebar 32 Dw Arrow 40 .> 190
  Clear 12 Page Up 33 Insert 45 /? 191
  Enter 13 Page Down 34 Delete 46 `~ 192
  Shift 16 End 35 Num Lock 144 [{ 219
  Control 17 Home 36 ;: 186 \| 220
  Alt 18 Left Arrow 37 =+ 187 ]} 221
  Cape Lock 20 Up Arrow 38 ,< 188 '" 222
  * */
 //通過“回車鍵”提交用戶名
 d.getElementById('userName').onkeydown = function (e) {
  console.log(e);
  e = e || event;
  if (e.keyCode === 13) {
   CHAT.userNameSubmit();
  }
 };
 //通過“回車鍵”提交聊天內(nèi)容
 d.getElementById('content').onkeydown = function (e) {
  e = e || event;
  if (e.keyCode === 13) {
   CHAT.submit();
  }
 };
})();

style.css

秘密

運行結果

服務器端已經(jīng)運行,現(xiàn)將客戶端也運行起來得到下圖:

這里寫圖片描述

添加了new和pidian兩個用戶,并發(fā)送信息和進行退出,得到下面的結果:

這里寫圖片描述

以上所述是小編給大家介紹的基于Nodejs利用socket.io實現(xiàn)多人聊天室,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

  • 輕松創(chuàng)建nodejs服務器(4):路由

    輕松創(chuàng)建nodejs服務器(4):路由

    這篇文章主要介紹了輕松創(chuàng)建nodejs服務器(4):路由,服務器需要根據(jù)不同的URL或請求來執(zhí)行不一樣的操作,我們可以通過路由來實現(xiàn)這個步驟,需要的朋友可以參考下
    2014-12-12
  • nvm的下載,安裝與使用方法圖文詳解

    nvm的下載,安裝與使用方法圖文詳解

    這篇文章主要介紹了nvm的下載,安裝與使用方法,詳細介紹了nvm的功能、下載與安裝方法,常見命令以及相關問題解決方法,需要的朋友可以參考下
    2023-04-04
  • Nodejs實現(xiàn)多文件夾文件同步

    Nodejs實現(xiàn)多文件夾文件同步

    這篇文章主要為大家介紹了Nodejs實現(xiàn)多文件夾文件同步,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • node實現(xiàn)socket鏈接與GPRS進行通信的方法

    node實現(xiàn)socket鏈接與GPRS進行通信的方法

    這篇文章主要介紹了node實現(xiàn)socket鏈接與GPRS進行通信的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • NodeJS開發(fā)人員常見五個錯誤理解

    NodeJS開發(fā)人員常見五個錯誤理解

    這篇文章主要介紹了NodeJS開發(fā)人員常見五個錯誤理解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • 詳解Node項目部署到云服務器上

    詳解Node項目部署到云服務器上

    本篇文章主要介紹了詳解Node項目部署到云服務器上,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • nodejs個人博客開發(fā)第五步 分配數(shù)據(jù)

    nodejs個人博客開發(fā)第五步 分配數(shù)據(jù)

    這篇文章主要為大家詳細介紹了nodejs個人博客開發(fā)的分配數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • NodeJs模擬登陸正方教務

    NodeJs模擬登陸正方教務

    網(wǎng)上已經(jīng)有很多關于模擬登陸正方教務的作品了,基于 PHP,Python,Java,.Net 加上NodeJs,這幾門語言都可以實現(xiàn)模擬登陸,模擬登陸的技術點不是特別難,這里記錄一下利用Node碰到的一些坑,以及一些解決思路。
    2017-04-04
  • 詳解node服務器中打開html文件的兩種方法

    詳解node服務器中打開html文件的兩種方法

    本篇文章主要介紹了詳解node服務器中打開html文件的兩種方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • node.js中的events.EventEmitter.listenerCount方法使用說明

    node.js中的events.EventEmitter.listenerCount方法使用說明

    這篇文章主要介紹了node.js中的events.EventEmitter.listenerCount方法使用說明,本文介紹了events.EventEmitter.listenerCount的方法說明、語法、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12

最新評論