前言

从此篇文章开始,作者可能以后会多发一些技术性的文章(主要是关于前端的),此刻我才明白自己多渺小😮‍💨,感觉发一些启发性的文章,并不能真正的启发大家,甚至不屑,看来所有的都得靠大家自己了(可能一个人的成长,真的只能靠某件事情去教了🤔),废话不多说,直接进入正题,大家拿好凳子准备发车

1692238966425040.jpg

注意:请不要连node是什么都不知道,不然这篇文章不适合你哦

原理

利用的是websocket协议(感兴趣的自行探索):在单个TCP连接上进行全双工通信的协议,总之就是服务端与客户端可以互相发送消息,实现通讯功能

项目初始化

1. 安装两个包即可(其实一个也行)

{
  "devDependencies": {
    "@types/node": "^22.5.5"
  },
  "dependencies": {
    "socket.io": "^4.7.5"
  }
}

@types/node: 主要是提供node代码提示

socket.io:今天的主角,通信全靠它了

2. 服务端代码

分为两个文件:

server.js: 服务端入口文件

const http = require('http')
const socket = require('./socket')

const port = 3000 // 端口号
const server = http.createServer((req, res)=>{
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    res.end('欢迎来到聊天室')
})

socket(server)

server.listen(port, ()=>{
    console.log('通讯服务启动成功', `http://localhost:${port}/`)
})

socket.js: 实现聊天服务的一个函数

const { Server } = require('socket.io');

function socket(server) {
    const io = new Server(server, {
        cors: true // 允许跨域
    });
    io.on('connection', (socket) => {
        console.log('a user connected');
    });
}

module.exports = socket

3.客户端代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>聊天室</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.5/socket.io.js"></script>
  </head>
  <body>
    <script>
      const socket = io("ws://localhost:3000");

      // 监听事件
      socket.on("connect", () => {
        console.log("连接成功");
      });
    </script>
  </body>
</html>

简单的接收和发送消息

1.客户端(socket.emit)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>聊天室</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.5/socket.io.js"></script>
</head>

<body>
    <input type="text">
    <button onclick="send()">发送</button>
    <script>
        const socket = io("ws://localhost:3000");
        const input = document.querySelector('input')

        function send() {
            socket.emit('chat', input.value)
            input.value = ''
        }
        // 监听事件
        socket.on("connect", () => {
            console.log("连接成功");
        });
    </script>
</body>

</html>

2.服务端(socket.on)

const { Server } = require('socket.io');

function socket(server) {
    const io = new Server(server, {
        cors: true // 允许跨域
    });
    io.on('connection', (socket) => {
        console.log('a user connected');
        socket.on('chat', (msg)=>{
            console.log(msg)
        })
    });
}

module.exports = socket

实现基本聊天功能

这里为了简便,就省去了用户登录的功能,而是利用了crypto这个模块生成用户id,用以区分消息来自哪里,只要大家能理解里面的思路,加一个登录验证,对你们来说就像呼吸一样简单,嘿嘿😍

1.服务端(广播全体在线用户, io.emit)

const { Server } = require('socket.io');
const crypto = require('crypto');

function socket(server) {
    const io = new Server(server, {
        cors: true // 允许跨域
    });
    io.on('connection', (socket) => {
        const userId = crypto.randomBytes(16).toString('hex') // 随机生成用户id
        socket.user = userId
        socket.on('chat', (msg)=>{
            io.emit('chat', msg + '-用户:' + socket.user)
        })

        console.log('a user connected');
    });
}

module.exports = socket

2.客户端(监听服务器广播的消息,socket.on)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>聊天室</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.5/socket.io.js"></script>
</head>

<body>
    <input type="text">
    <button onclick="send()">发送</button>
    <ul id="messageList"></ul>
    <script>
        const socket = io("ws://localhost:3000");
        const input = document.querySelector('input')
        const messageList = document.querySelector('#messageList')

        function send() {
            socket.emit('chat', input.value)
            input.value = ''
        }
        // 监听事件
        socket.on("connect", () => {
            console.log("连接成功");
        });

        // 接收消息,并展示在页面中
        socket.on('chat', (msg)=>{
            const msgItem = document.createElement('li')
            msgItem.innerText = msg
            messageList.appendChild(msgItem)
        })
    </script>
</body>

</html>

结果如下:

image.png

总结

到这里,你如果全懂了,恭喜你🎉🎉,你已经步入帝君境界,一人便可抵挡千军万马,黄沙百战穿金甲,不破楼兰终不还,嘿嘿,加油修炼吧!!

1692238965354979.jpg

等等,别高兴太早了

一款即时通讯应用要想真正的做起来,上面的这些只能说皮毛都不算

为什么(还有哪些要实现的):

1. 登录验证
2. 数据的存储
3. 用户的互动性(加好友,删除好友,单聊,群聊,拉群功能)
4. 如何保证消息的可靠性、完整性,顺序性
5. 离线消息的存储,并在用户上线的时候进行发送
6. 支持桌面推送、声音提醒
7. 性能优化(服务器负载均衡,使用 Redis 等缓存常用数据)
等等....

我都感觉我写不完了,反正实现一款成熟的聊天应用,不是我一篇文章就能讲清楚的(也不是两篇哈😂),感觉前方还有千军万马等着呢!!