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

相关文章
相关标签/搜索