websoket是干么的如何基于websoket实现一个简单的消息通信。

websoket是干么的

  1. websoket简单来说就是允许服务端主动向客户端推送数据的一种技术。他可以使客户端和服务端之间交换数据变得简单,浏览器和服务器只需要完成一次握手(握手指的是:创建websoket需要向浏览器发送请求,之后服务器进行回应,这个过程称为握手),两者之间就可以创建持久的连接,进行双向数据传输。

  1. websoket是一种在单个TCP连接上进行的全双工通信的协议。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;

  1. 保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等

很多网站为了实现推送技术,一般用的技术都是轮询(轮询简单来说:使用定时器每隔一段时间向后端发送一次请求俗称:程控输出入)由浏览器对服务器发出 HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的 头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

基于websoket实现一个简单的消息通信

使用到的技术有vite node ws

先初始化两个项目一个web端的,一个服务端

npm init -y

npm i vite -D

更改启动命令

{
  "name": "web",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "vite"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "vite": "^4.0.4"
  }
}

创建 index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>欢迎来到聊天室</h1>
    <ul id="ul">
    </ul>
    <input id="input" type="text">
    <button id="btn">点击发送</button>
</body>
<script>
    // 1 安装vite npm i vite -D
    /** 前端
     * open 建立连接
     * close 关闭连接
     * error 错误信息
     * message 接受后端返回的信息
     * */

    ; ((Window, WebSocket, Storage) => {
        console.log(localStorage.getItem('name'))
        let ws = new WebSocket('ws:localhost:8000')

        function bindTab() {
            btn.addEventListener('click', btnHandle)
            ws.addEventListener('message', messageHandle)
            ws.addEventListener('close', closeHandle)
            ws.addEventListener('error', errorHandle)
            ws.addEventListener('open', openHandle)
        }
        const closeHandle = () => {
            console.log('close');
        }
        const errorHandle = () => {
            console.log('error');
        }
        const openHandle = () => {
            console.log('open');
        }
        const messageHandle = (res) => {
            ul.appendChild(render(res.data))
        }
        const btnHandle = () => {
            console.log(input.value)
            if (!Storage.getItem('name')) {
                console.log(Storage.getItem('name'))
                window.location.href = 'http://127.0.0.1:5173/login.html'
            }
            let obj = JSON.stringify({
                text: input.value,
                time: new Date().toLocaleString(),
                name: localStorage.getItem('name')
            })
            console.log(2, ws)
            // 向后端发送数据将参数转换为字符串传入。
            ws.send(obj)
        }
        const render = (value) =>  {
            let msg = JSON.parse(value)
            let li = document.createElement('li')
            li.innerHTML = `
                   <li>内容:${msg.text}--姓名:${msg.name}--时间:${msg.time}</li>
               `
            return li
        }


        bindTab()

    })(Window, WebSocket, localStorage)

</script>

</html>

创建login.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>欢迎来到聊天室</h1>
    <p>请输入你的名字:<input id="input" type="text"> <button id="btn">注册</button></p>

</body>
<script>
    btn.addEventListener('click', function () {
        localStorage.setItem('name', JSON.stringify(input.value))
        window.location.href = 'http://127.0.0.1:5173/'
    })

</script>

</html>

node服务端

npm init -y

npm i ws -D

没有nodemon 安装 npm i nodemon

{
  "name": "node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "nodemon": "^2.0.20",
    "ws": "^8.12.0"
  }
}

创建index.js

const Ws = require('ws')
// 监听在8000端口
const wss = new Ws.Server({
    port: 8000,
})

/** 后端
   * open 建立连接
   * close 关闭连接
   * error 错误信息
   * message 接受后端返回的信息
   * connection 后端表示已经连接上了
   * */

//   ws 插件   nodejs-websocket 插件
wss.on('open', () => {
    console.log('open')
})
wss.on('connection', function (ws) {
    console.log('连接成功', ws)
    ws.on('message', getMessage)
})

wss.on('message', (res) => {
    console.log('message', res);
})
wss.on('error', () => {
    console.log('error' );

})
wss.on('close', () => {
    console.log('close' );
})


function getMessage(msg) {
    //<Buffer 7b 22 69 64 22 3a 31 2c 22 6e 61 6d 65 22 3a 22 e5 bc a0 e4 b8 89 22
    // 必须将msg进行toString 否则会形成Buffer
    console.log('ws', msg.toString())
    // toJSON不是转成原数据json,而是把json buffer数据转化成json格式。
    console.log(msg.toJSON());
    // clients 向客户端推送数据
    wss.clients.forEach(c => {
        c.send(msg.toString())
    })
}

启动命令都是 npm run dev

猜你喜欢

转载自blog.csdn.net/qq_54753561/article/details/128798949
今日推荐