Node.js和Socket.IO搭建Web Chat application

WebSocket與Socket.IO

WebSocket是一種協議,有了它就能夠在TCP協議的基礎上在瀏覽器和服務器之間創建起了一種全雙工的通道,它徹底兼容HTTP協議,有了它使得Web應用程序能夠在瀏覽器和服務器之間進行實時的交互,如今主流瀏覽器都支持這種協議。html


Socket.IO是JavaScript library,是Node.js的module,它能夠創建起一個基於事件的實時的雙向交流方式,極大的簡化了WebSocket的處理過程。在這個Chat application中將會用到它。node

開始Chat application

搭建這個應用幾乎只須要Node.js和Socket.IO最初級的知識,由於只搭建一個基本的程序。jquery

web 框架

最初的構想是一個簡單的HTML頁面,由一個表單和消息列表組成,要使用Node.js和express框架,首先確保Node.js已經安裝好了。web


首先建立項目目錄chat-example文件夾,而後在裏邊建立package.json文件來描述項目信息以及依賴。express

{
  "name": "socket-chat-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {}
}

而後到命令行cd到項目目錄安裝express,npm install --save express
--save參數能夠把自動把express添加到package.json的dependencies中。
express安裝好後建立一個index.js,來配置應用。npm

//index.js
var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('<h1>Hello world</h1>');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

上邊代碼能夠這樣翻譯一下:json

  1. Express初始化了一個函數句柄能夠應用於HTTP server於第2行瀏覽器

  2. 定義一個路由來訪問網站首頁服務器

  3. 開啓http服務監聽3000端口app

在命令行中node index.js獲得以下結果:
圖片描述
到瀏覽器中訪問http://localhost:3000結果以下:
圖片描述

以前咱們使用res.send('<h1>Hello world</h1>');來傳遞html字符串,若是文檔內容多了這樣作就有點low了,換種方式新建一個index.html文件,訪問它就能夠了。

首先來重構以前的路由:

app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});

而後建立index.html

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

重啓服務,到瀏覽器查看是這個樣子:
圖片描述

把Socket.IO引入

Socket.IO由2部分組成:

  • 服務端Node.JS HTTP Server: socket.io

  • 瀏覽器端的js庫:socket.io-client

接下來npm install --save socket.io添加模塊
而後編輯index.js中的內容以下:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

注意經過把http(the HTTP server)對象傳遞給socket.io初始化了一個socket.io的實例,而後監聽connection事件,而且在控制檯中打印出來

在index.html的</body>以前增長以下幾行:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

這就是用來加載socket.io-client的,暴露出一個全局的io,而後connect
注意我調用io()的時候並無指定任何的URL,由於它默認就是去當前跑的頁面去和server鏈接
重啓服務,多開幾個頁面,在控制檯中能夠看到以下結果:
圖片描述

每一個socket還有一個特殊的disconnect事件:

io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

發射事件

Socket.IO的主要想法就是你可以發射和接收任何你喜歡的事件,任何對象都會被編碼成Json,也支持二進制數據


那接下來就作咱們發送信息的時候server接收到chat message事件,index.html中的script部分改寫以下:

<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
  });
</script>

在index.js中咱們打印出chat message事件

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
  });
});

在瀏覽器端發射,控制檯觀察以下:
圖片描述

廣播消息Broadcasting

接下來的目標是從server發送消息給其他的在線用戶,爲了能把消息傳遞給everyone,Socket.IO給咱們提供了io.emit

io.emit('some event', { for: 'everyone' });

若是你想發消息給everyone,除去一個特定的socket,那就快用broadcast 標誌吧

io.on('connection', function(socket){
  socket.broadcast.emit('hi');
});

像下面這樣就能把消息發給全部人,包括消息的發送者

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

下面到客戶端捕獲chat message事件,把消息內容插到消息列表中:

<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text(msg));
    });
  });
</script>

到瀏覽器多開幾個選項卡就能夠瘋狂的發射和接收消息了,很是實時,短短20幾行代碼就能實現這樣的效果,真是使人髮指啊!

總結

哈哈,其實這個例子是socket.io官網的小栗子,喜歡學英語的朋友能夠去玩一下,那裏的video演示很直觀,你能夠戳這裏socket.io-Chat

相關文章
相關標籤/搜索