1. 程式人生 > >1024_(即時通訊)使用node.js和socket.io實現多人聊天室

1024_(即時通訊)使用node.js和socket.io實現多人聊天室

使用node.js和socket.io實現多人聊天室

2015年01月24日 03:24:54 遠古大猛獁 閱讀數:2775

轉自:

http://www.cnblogs.com/flyoung2008/archive/2012/07/19/2600132.html

http://blog.fens.me/nodejs-socketio-chat/

 

一、基本功能

1、使用者隨意輸入一個暱稱即可登入
2、登入成功後
1) 對正在登入使用者來說,羅列所有線上使用者列表,羅列最近的歷史聊天記錄
2) 對已登入的使用者來說,通知有新使用者進入房間,更新線上使用者列表
3、退出登入
1)支援直接退出
2) 當有使用者退出,其他所有線上使用者會收到資訊,通知又使用者退出房間,同時更新線上使用者列表
4、聊天
1) 聊天就是廣播,把資訊廣播給所有連線線上的使用者
5、一些出錯處理
1) 暫時簡單處理了系統邏輯錯誤、網路出錯等特殊情況的出錯提示

問題:功能不完善,有bug(退出後,新使用者重新登入,還是原來的使用者) 。抽空完善吧

二、技術介紹

socket.io(官網:http://socket.io/)是一個跨平臺,多種連線方式自動切換,做即時通訊方面的開發很方便,而且能和expressjs提供的傳統請求方式很好的結合,即可以在同一個域名,同一個埠提供兩種連線方式:request/response, websocket(flashsocket,ajax…)。

這篇文章對socket.io的使用做了詳細介紹:http://www.cnblogs.com/dxy1982/archive/2012/01/30/2328020.html

《用node.js和Websocket做個多人聊天室吧》

http://www.html5china.com/HTML5features/WebSocket/20111206_3096.html

三、注意事項

(1)客戶端這樣引用socket.io.js:

<script src="/socket.io/socket.io.js"></script>

可能會載入失敗(我在這裡耗了不少時間)

可以改為:

<script src="http://ip:port/socket.io/socket.io.js"></script>

(對應伺服器的ip地址和埠號,比如說localhost和80埠)

(2)實現廣播的時候,參考官網的寫法,竟然不起作用,如:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.broadcast.emit('user connected');
  socket.broadcast.json.send({ a: 'message' });
});

後來看了這個:http://stackoverflow.com/questions/7352164/update-all-clients-using-socket-io

改為以下才起作用:

io.sockets.emit('users_count', clients);

四、效果圖

五、原始碼下載

  Nodejs多人聊天室

ps:

1、在命令列執行

node main.js

然後在瀏覽器中開啟index.html,如果瀏覽器(ff、Chrome)不支援,請升級到支援WebSocket的版本.

2、推薦node.js的IDE WebStorm

 

=============================================================================================================================

 

前言

網路聊天室在web1.0的時代就出現了,但當時技術支援比較有限,大都是通過瀏覽器外掛BHO,JavaApplet,Flash實現的。如今HTML5技術風起雲湧,通過websocket實現的網路聊天室,被定義為websocket的第一個實驗,就像Hello World一樣的簡單。

今天我也動手完成了這個實驗,感覺真的很爽!

目錄

  1. socket.io介紹
  2. 伺服器端和客戶端通訊設計
  3. 伺服器端實現
  4. 客戶端實現
  5. 完整案例程式碼

1. socket.io介紹

socket.io一個是基於Nodejs架構體系的,支援websocket的協議用於時時通訊的一個軟體包。socket.io 給跨瀏覽器構建實時應用提供了完整的封裝,socket.io完全由javascript實現。

基於Nodejs實現webscoket其他的框架,請參考文章:Nodejs實現websocket的4種方式

2. 伺服器端和客戶端通訊設計

chat

上圖中client1 和 server 描述通訊過程,client2描述對其他的客戶端,通過廣播進行訊息通訊。

  1. client1向server發起連線請求
  2. server接受client的連線
  3. client1輸入登陸使用者名稱
  4. server返回歡迎語
  5. server通過廣播告訴其他線上的使用者,client1已登陸
  6. client1傳送聊天資訊
  7. server返回聊天資訊(可省略)
  8. server通過廣播告訴其他線上的使用者,client1的聊天訊息
  9. client1關閉連線,退出登陸
  10. server通過廣播告訴其他線上的使用者,client1已退出

我們看一下測試截圖:
chat2

  1. 左邊: aaa 登陸
  2. 右邊: bbb 登陸
  3. 左邊: aaa 收到 bbb登陸歡迎訊息
  4. aaa 和 bbb 實現對話
  5. 右邊: bbb 重新整理瀏覽自動退出
  6. 左邊: aaa 收到 bbb的退出訊息
  7. 右邊: CCC 登陸
  8. 左邊: aaa 收到 CCC 登陸歡迎訊息
  9. aaa 和 CCC 實現對話

3. 伺服器端實現

我們這裡使用socket.io和express3的混合模式,讓HTTP請求和WebSocket請求都使用3000埠。

伺服器端實現,只有一個核心檔案app.js。

 
  1.  
  2. //引入程式包

  3. var express = require('express')

  4. , path = require('path')

  5. , app = express()

  6. , server = require('http').createServer(app)

  7. , io = require('socket.io').listen(server);

  8.  
  9. //設定日誌級別

  10. io.set('log level', 1);

  11.  
  12. //WebSocket連線監聽

  13. io.on('connection', function (socket) {

  14. socket.emit('open');//通知客戶端已連線

  15.  
  16. // 列印握手資訊

  17. // console.log(socket.handshake);

  18.  
  19. // 構造客戶端物件

  20. var client = {

  21. socket:socket,

  22. name:false,

  23. color:getColor()

  24. }

  25.  
  26. // 對message事件的監聽

  27. socket.on('message', function(msg){

  28. var obj = {time:getTime(),color:client.color};

  29.  
  30. // 判斷是不是第一次連線,以第一條訊息作為使用者名稱

  31. if(!client.name){

  32. client.name = msg;

  33. obj['text']=client.name;

  34. obj['author']='System';

  35. obj['type']='welcome';

  36. console.log(client.name + ' login');

  37.  
  38. //返回歡迎語

  39. socket.emit('system',obj);

  40. //廣播新使用者已登陸

  41. socket.broadcast.emit('system',obj);

  42. }else{

  43.  
  44. //如果不是第一次的連線,正常的聊天訊息

  45. obj['text']=msg;

  46. obj['author']=client.name;

  47. obj['type']='message';

  48. console.log(client.name + ' say: ' + msg);

  49.  
  50. // 返回訊息(可以省略)

  51. socket.emit('message',obj);

  52. // 廣播向其他使用者發訊息

  53. socket.broadcast.emit('message',obj);

  54. }

  55. });

  56.  
  57. //監聽出退事件

  58. socket.on('disconnect', function () {

  59. var obj = {

  60. time:getTime(),

  61. color:client.color,

  62. author:'System',

  63. text:client.name,

  64. type:'disconnect'

  65. };

  66.  
  67. // 廣播使用者已退出

  68. socket.broadcast.emit('system',obj);

  69. console.log(client.name + 'Disconnect');

  70. });

  71.  
  72. });

  73.  
  74. //express基本配置

  75. app.configure(function(){

  76. app.set('port', process.env.PORT || 3000);

  77. app.set('views', __dirname + '/views');

  78. app.use(express.favicon());

  79. app.use(express.logger('dev'));

  80. app.use(express.bodyParser());

  81. app.use(express.methodOverride());

  82. app.use(app.router);

  83. app.use(express.static(path.join(__dirname, 'public')));

  84. });

  85.  
  86. app.configure('development', function(){

  87. app.use(express.errorHandler());

  88. });

  89.  
  90. // 指定webscoket的客戶端的html檔案

  91. app.get('/', function(req, res){

  92. res.sendfile('views/chat.html');

  93. });

  94.  
  95. server.listen(app.get('port'), function(){

  96. console.log("Express server listening on port " + app.get('port'));

  97. });

  98.  
  99. var getTime=function(){

  100. var date = new Date();

  101. return date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();

  102. }

  103.  
  104. var getColor=function(){

  105. var colors = ['aliceblue','antiquewhite','aqua','aquamarine','pink','red','green',

  106. 'orange','blue','blueviolet','brown','burlywood','cadetblue'];

  107. return colors[Math.round(Math.random() * 10000 % colors.length)];

  108. }

4. 客戶端實現

這裡我們需要定義幾個檔案:chat.html, chat.js, jquery.min.js, main.css

1). views/chat.html

 
  1.  
  2. <!DOCTYPE html>

  3. <html>

  4. <head>

  5. <meta charset="utf-8">

  6. <title>Socket.io - Simple chat</title>

  7. <link rel="stylesheet" type="text/css" href="css/main.css">

  8. <script src="javascripts/jquery.min.js"></script>

  9. <script src="/socket.io/socket.io.js"></script>

  10. <script src="javascripts/chat.js"></script>

  11. </head>

  12. <body>

  13. <h1>Socket.io - Simple chat room</h1>

  14. <div>

  15. <span id="status">Connecting...</span>

  16. <input type="text" id="input"/>

  17. </div>

  18. <div id="content"></div>

  19. </body>

  20. </html>

2). public/javascript/chat.js

 
  1.  
  2. $(function () {

  3. var content = $('#content');

  4. var status = $('#status');

  5. var input = $('#input');

  6. var myName = false;

  7.  
  8. //建立websocket連線

  9. socket = io.connect('http://localhost:3000');

  10. //收到server的連線確認

  11. socket.on('open',function(){

  12. status.text('Choose a name:');

  13. });

  14.  
  15. //監聽system事件,判斷welcome或者disconnect,列印系統訊息資訊

  16. socket.on('system',function(json){

  17. var p = '';

  18. if (json.type === 'welcome'){

  19. if(myName==json.text) status.text(myName + ': ').css('color', json.color);

  20. p = '<p style="background:'+json.color+'">system @ '+ json.time+ ' : Welcome ' + json.text +'</p>';

  21. }else if(json.type == 'disconnect'){

  22. p = '<p style="background:'+json.color+'">system @ '+ json.time+ ' : Bye ' + json.text +'</p>';

  23. }

  24. content.prepend(p);

  25. });

  26.  
  27. //監聽message事件,列印訊息資訊

  28. socket.on('message',function(json){

  29. var p = '<p><span style="color:'+json.color+';">' + json.author+'</span> @ '+ json.time+ ' : '+json.text+'</p>';

  30. content.prepend(p);

  31. });

  32.  
  33. //通過“回車”提交聊天資訊

  34. input.keydown(function(e) {

  35. if (e.keyCode === 13) {

  36. var msg = $(this).val();

  37. if (!msg) return;

  38. socket.send(msg);

  39. $(this).val('');

  40. if (myName === false) {

  41. myName = msg;

  42. }

  43. }

  44. });

  45. });

3). public/javascript/jquery.min.js
從jquery官方下載: http://jquery.com/

4). public/css/main.css

 
  1.  
  2. * {padding:0px; margin:0px;}

  3. body{font-family:tahoma; font-size:12px;margin:10px;}

  4. p {line-height:18px;padding:2px;}

  5. div {width:500px;}

  6. #content {

  7. padding:5px;

  8. background:#ddd;

  9. border-radius:5px;

  10. border:1px solid #CCC;

  11. margin-top:10px;

  12. }

  13. #input {

  14. border-radius:2px;

  15. border:1px solid #ccc;

  16. margin-top:10px;

  17. padding:5px;

  18. width:380px;

  19. }

  20. #status {

  21. width:100px;

  22. display:block;

  23. float:left;

  24. margin-top:15px;

  25. }

5. 完整案例程式碼

專案已經上傳到github: https://github.com/bsspirit/chat-websocket

下載,安裝,啟動伺服器

 
  1.  
  2. git clone https://github.com/bsspirit/chat-websocket.git

  3. npm install

  4. node app.js

開啟瀏覽器
可以多開啟幾個視窗,模擬不同使用者有的對話。

http://localhost:3000

做完實驗,感覺棒極了。技術創新的革命!!