socket.io入門,簡易聊天室

介紹

一般咱們web使用的是http協議,可是 HTTP 協議有一個缺陷:通訊只能由客戶端發起。html

因此咱們須要一個能夠由服務端主動發出的協議,即WebSocket。node

WebSocket是HTML5新增的一種通訊協議,其特色是服務端能夠主動向客戶端推送信息,客戶端也能夠主動向服務端發送信息,是真正的雙向平等對話,屬於服務器推送技術的一種。jquery

Socket.IO 是一個基於 Node.js 的實時應用程序框架,在即時通信、通知與消息推送,實時分析等場景中有較爲普遍的應用。web

socket.io 包含兩個部分:express

  • 服務器端(server):運行在 Node.js 服務器上
  • 客戶端(client):運行在瀏覽器中

開啓服務

固然,socket.IO構架在一個nodejs服務上,這裏開啓一個express服務。npm

建立文件夾socketIODemo,而後安裝瀏覽器

npm init -y
npm install express --save

以後在socketIODemo中建立文件index.js:服務器

const express = require('express')
    const app = express()
    
    app.use(express.static(__dirname + '/public'));
    
    app.listen(3000, () => console.log('Example app listening on port 3000!'))

建立靜態資源public/index.html :app

<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            html,
            body {
                height: 100%;
                overflow: hidden;
            }
            .chat {
                float: left;
                padding: 1em 1em 0 2em;
                height: 100%;
                width: 500px;
                border-right: 1px solid #DA4;
                overflow-y: scroll;
            }
            .inputpart {
                float: left;
                margin-left: 10px;
            }
            #userName {
                font-size: 20px;
                color: rgb(3, 57, 109);
            }
        </style>
    </head>
    <body>
        <div class="chat">
            <ul id="messages">
                //聊天信息
            </ul>
        </div>
        <div class="inputpart">
            <div id="userName">
                //用來展現用戶id
            </div>
            <form action="">
                <input autocomplete="off" id="inpB" /><button id="say">Send</button>
            </form>
        </div>
    </body>
    </html>

此時開啓服務: node index, 訪問localhost:3000。框架

服務開啓!

使用socket.IO

安裝:

npm install socket.io --save

而後在index.js中註冊socket.io,並改成http監聽:

let http = require('http').Server(app)
    const io = require('socket.io')(http) 
    app.use(express.static(__dirname + '/public'));
    
    http.listen(3000, () => console.log('Example app listening on port 3000!'))

此時服務已改成WebSocket服務。

數據傳輸

服務端運行後會在根目錄動態生成socket.io的客戶端js文件,客戶端能夠經過固定路徑/socket.io/socket.io.js添加引用。
在HTML中引用js文件,並調用:

<script src="/socket.io/socket.io.js"></script>
        <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
        <script>
            $(function () {
                var userName = '';
                while ($('#userName').text().trim() === '') {
                    //設置用戶名
                    let promptName = prompt("請設置你的暱稱", "")
                    userName = promptName ? promptName + ':' : '未命名:';
                    $('#userName').text(userName);
                }
                let socket = io();
                socket.on('connect', function () {
                    socket.emit('join', userName)
                })
                // 監聽系統消息
                socket.on('sys', function (sysMsg) {
                    var message = '<div class="sysMsg">' + sysMsg + '</div>';
                    $('#messages').append(message);
                });
            })
        </script>

這段代碼中,socket.on('connect', function () { })爲默認監聽事件,socket.io 提供了默認事件(如:connect, message, disconnect)。也能夠自定義。socket.emit('action');表示發送了一個action命令,命令是字符串的。

後臺index.js文件中:

io.on('connection', function (socket) {
        console.log('a user connected')
        let userID = ''
        socket.on('join', function (userName) {
            userID = userName;
            io.emit('sys', userID + '已加入房間');
            console.log(userID + '加入了');
        });
    })

connection事件在客戶端成功鏈接到服務端時觸發,有了這個事件,咱們能夠隨時掌握用戶鏈接到服務端的信息。
當客戶端成功創建鏈接時,在connection事件的回調函數中,咱們仍是能夠爲socket註冊一些經常使用的事件,如:disconnect事件socket.on('disconnect',function(){...});,它在客戶端鏈接斷開是觸發,這時候我就知道用戶已經離開了。

重啓服務,打開多個窗口,查看聊天框內容:

下面添加聊天功能。

在HTML文件中添加事件監聽click:

$('#say').click((e) => {
          e.preventDefault()
          socket.send($("#inpB")[0].value)
          $("#inpB")[0].value = ''
      })
      socket.on('msg', function (userName, userColor, msg) {
          var message = ' <div class="message">' +
              `<span class="user" style="font-size:1.5em; color: #${userColor}">` +                  userName + '</span>' +
              '  <span class="msg">' + msg + '</span>' +
              '</div>';
          $('#messages').append(message);
          // 滾動條保持最下方
          $('#messages').scrollTop($('#messages')[0].scrollHeight);
      });

這段代碼中,首先監聽事件並將input中內容send回去;socket.on爲自定義事件msg 用來接收後臺發送來的其餘人的發言。

socket.emit和socket.send的區別在stackoverflow中有一個解釋大意是說emit能夠自定義事件,而send不能夠,且只能以message接收。

後臺index.js:

io.on('connection', function (socket) {
        console.log('a user connected')
        let userID = '', userColor =parseInt(Math.random() * 16777216).toString(16)
    
        socket.on('join', function (userName) {
            userID = userName;
            io.emit('sys', userID + '已加入房間');
            console.log(userID + '加入了');
        });
        socket.on('message', function (msg){
            io.emit('msg', userID, userColor, msg)
        })
    })

爲新的成員隨機匹配顏色,並將message監聽到的信息經過自定義爲msg的事件emit出去。

此時,一個簡易聊天室已經完成。

讀者能夠自行添加退出功能,或者設置多個房間。。。

參考:https://www.jianshu.com/p/40d8bc17529f

相關文章
相關標籤/搜索