使用 Web Sockets 实现实时通信

有没有想过,WhatsApp、Facebook 或其他类似的社交平台是如何在幕后运作的?

为了更好地理解这个问题,让我们以 WhatsApp 为例,数百万人通过聊天或其他方式相互交流。现在从技术角度出发,我们假设有 10 个用户(假设),假设有人给你发短信。

一旦有人给你发短信,你就会收到通知。但这怎么可能呢,因为从技术上讲,除非你进行了操作(调用 API),否则你不会收到数据。

假设调用 API 是了解谁给您发短信的唯一方法,那么对于一个拥有 10000 个联系人的人来说,这岂不是一种可怕的方法,因为他们需要调用 10000 次 API 来查看是否收到任何信息。这就是 Web Sockets 的用武之地。

使用 Web Sockets 实现实时通信
传统 HTTP 网络交易

与遵循请求-响应模式的传统网络事务不同,Web Sockets 允许客户端和服务器之间进行双向实时通信。这就是为什么 Web Sockets 是需要低延迟和持续更新数据的应用程序(如游戏平台、聊天应用程序和其他类似应用程序)的首选。

使用 Web Sockets 实现实时通信
Web Socket通信

连接通过单个 TCP 连接进行。它提供 wss(用于 https)和 ws(用于 http)协议来创建网络套接字。wss 协议通过加密的 TLS 连接建立 WebSocket,而 ws 协议则使用未加密的连接。网络连接保持开放,可用于向任一方向发送 WebSocket 消息。

让我们来看看 WebSocket 的实际应用。我们将创建一个简单的应用程序,在服务器端使用节点,在客户端使用传统的 HTML 和 JS。

步骤

要创建示例节点应用程序,请创建一个文件夹,其中包含最新(首选)版本的节点应用程序。

npm init

该命令将创建包含基本配置的 package.json 文件,并在根结构中创建 index.js 文件。这就是 package.json 文件的样子。

package.json

{
  "name": "socket",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node --watch index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2",
    "http": "0.0.1-security",
    "socket.io": "^4.7.2"
  }
}

使用 “node – watch index.js “命令,就可以监控文件(index.js)的任何更改并进行相应更新,而无需重启服务器。

index.js

const http = require('http');
const express = require('express');
const socketIO = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIO(server);
const clients = new Set();
io.on('connection', (socket) => {
  
  //add newly connected client to the List
  clients.add(socket);

  // Event listener for messages from clients
  socket.on('message', (message) => {
    // Broadcast the message to all connected clients
    io.emit('message', message);
  });

  socket.on('connectedClients', (c) => {
    io.emit('connectedClients', Array.from(clients).map(client => ({ id: client.id })))
    // io.emit('clients', clients);
  })

  socket.on('clientMessage', (message) => {
    // Broadcast the message to all other connected clients (excluding the sender)
    socket.broadcast.emit('message', `Message from ${socket.id}: ${message}`);
  });

  socket.on('disconnect', () => {
    // Remove the client from the set when it disconnects
    clients.delete(socket);
    io.emit('connectedClients', Array.from(clients).map(client => ({ id: client.id })))
  });

  //To continously send list of active clients
  io.emit('connectedClients', Array.from(clients).map(client => ({ id: client.id })))
});

server.listen(3000, () => {
  console.log('Server listening on port 3000');
});

index.html

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sockets Tutorial</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
</head>

<body>
    <div class="m-3">
        <h1>Welcome to Web Sockets</h1>
        <div style="display: flex;margin-bottom: 20px;">
            <input id="myInput" style="width: 60%" class="form-control" type="text" placeholder="Enter your message to other clients">
            <button class="btn btn-success" onclick="sendMessageToOtherClients()">
            Send Message To Other Clients
            </button>
        </div>
        <p>Below is the list of connected clients</p>
        <ul id="allClients"></ul>

        <div class="alert alert-success" id="message"></div>
    </div>

    <script>
        const socket = io('ws://localhost:3000');
        // Connection opened
        socket.on('connect', () => {
            socket.send('Connected To Sockets');
        });
        // Listen for messages
        socket.on('message', (message) => {
            // console.log('Message from server:', message);
            document.getElementById('message').innerHTML = message;
        });
        socket.on('connectedClients', (clients) => {
            let clientsElem = document.getElementById('allClients');
            clientsElem.innerHTML = ''
            clients.forEach(c => {
                let childElem = document.createElement('li');
                childElem.id = c.id;
                childElem.textContent = c.id
                clientsElem.append(childElem)
            })
            document.getElementById(socket.id).classList.add('owner')
        })
        // Connection closed
        socket.on('disconnect', () => {
            console.log('Server connection closed');
        });

        function sendMessageToOtherClients() {
            let input = document.getElementById('myInput').value;
            if(input.length > 0) {
                socket.emit('clientMessage', input);
                // document.getElementById('myInput').value = ''
            }
        }
    </script>
    <style>
        .owner {
            color: green
        }
    </style>
</body>
</html>

以下是应用程序的屏幕截图:

使用 Web Sockets 实现实时通信
使用 Web Sockets 实现实时通信

上面的截图表示,当我们在两个浏览器窗口中打开应用程序时,这将被视为两个客户端连接到我们的套接字。同样,在实时情况下,客户端可以位于全球任何地方,并可以通过套接字相互通信。

请注意,我们的应用程序中有一部分显示了所有与服务器连接的活动客户端,为了便于理解,当前套接字 ID 已标记为绿色。我们有一个收集用户信息的输入框,一旦你点击按钮,该信息就会广播给所有其他已连接的用户。

就是这样,希望你已经在一些实时操作中学到了套接字的基础知识,利用这些知识创建一个简单的聊天应用程序吧。

作者:Rajiv Varma
来自:https://rajivvarmag.medium.com/

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/im/40705.html

(0)

相关推荐

发表回复

登录后才能评论