• Node.js基础(四)


    1.JWT基础

    1.对称加密:

    var jwt = require('jsonwebtoken');
        //下面演示对称加密:
        // 加密,第一个参数是载荷,第二个参数是密钥,sign是加密方法
        const tk = jwt.sign({ username: 'admin' }, 'shhhh')
        res.send(tk)
    
        //验证
        const decoded = jwt.verify(tk, 'shhhh')
        console.log(decoded)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.非对称加密

    1.密钥生成:

    openssl

    • 生成私钥:

      genrsa -out rsa_private_key.pem 2048

    • 根据私钥生成公钥:

      rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

    2.根据密钥生成token

        //非对称加密:
        const privateKey = fs.readFileSync(path.join(__dirname, '../keys/rsa_private_key.pem'))
        const tk = jwt.sign({ username: 'admin' }, privateKey, { algorithm: 'RS256' })
        const publicKey = fs.readFileSync(path.join(__dirname, '../keys/rsa_public_key.pem'))
        res.send(tk)
    
        const result = jwt.verify(tk, publicKey)
        console.log(result)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.Socket

    • 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
    • 官网:http://socket.io

    img

    1.基于 Net 模块的 Socket 编程

    Client.js

    const net = require('net')
    
    const client = net.createConnection({ port: 9000 }, () => {
        //connect listener
        console.log('connected to server!')
        client.write('world!\n')
    
    })
    
    client.on('data', (data) => {
        console.log(data.toString())
    
        //表示断开连接
        // client.end()
    })
    client.on('end', () => {
        console.log('disconnected from server...')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Server.js

    //net是一个内置模块
    const net = require('net')
    
    const server = net.createServer((socket) => {
        //socket.write(data,[encoding],[callback])
        socket.write('hello')
        // socket.end('goodbye\n');
        socket.on('data', (chunk) => {
            console.log(chunk.toString())
        })
    
    })
    server.on('error', (err) => {
        //Handle errors here
        throw err
    })
    
    //Grab an arbitrary unused port
    server.listen(9000, () => {
        console.log('opened server on', server.address())
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 广播

    Client.js

    注意:这里不能使用nodemon启动,否则会出现输入一次就会打印一次的情况

    const net = require('net')
    const readline = require('readline')
    var port = 9000
    var host = 'localhost'
    var socket = new net.Socket()
    socket.setEncoding = 'UTF-8'
    
    socket.connect(port, host, () => {
        socket.write('hello.')
    })
    socket.on('data', (data) => {
    
        //这里是获取到了服务端返回的数据并且显示出来
        console.log(data.toString())
    
        say()
    })
    socket.on('error', function (err) {
        console.log(err)
    })
    socket.on('close', function () {
        console.log('connection closed')
    })
    const r1 = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    })
    function say() {
        r1.question('please input:\n', (inpurMsg) => {
            if (inpurMsg !== 'bye') {
                socket.write(inpurMsg + '\n')
            } else {
                socket.destroy()
                r1.close()
            }
        })
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • Server.js
    //net是一个内置模块
    // const net = require('net')
    
    // const server = net.createServer((socket) => {
    //     //socket.write(data,[encoding],[callback])
    //     socket.write('hello')
    //     // socket.end('goodbye\n');
    //     socket.on('data', (chunk) => {
    //         console.log(chunk.toString())
    //     })
    
    // })
    // server.on('error', (err) => {
    //     //Handle errors here
    //     throw err
    // })
    
    // //Grab an arbitrary unused port
    // server.listen(9000, () => {
    //     console.log('opened server on', server.address())
    // })
    
    const net = require('net')
    
    const server = new net.createServer()
    
    //记录用户名
    let clients = {}
    //记录用户序号
    let clientName = 0
    
    server.on('connection', (client) => {
        client.name = ++clientName
        clients[client.name] = client
    
        client.on('data', (msg) => {
            console.log('客户端传来:' + msg);
            broadcast(client, msg)
        })
    
        client.on('error', (e) => {
            console.log('client error' + e);
            client.end()
        })
    
        //表示关闭操作
        client.on('close', (data) => {
            delete clients[client.name]
            console.log(client.name + ' 下线了');
        })
    })
    function broadcast(client, msg) {
        for (var key in clients) {
            clients[key].write(client.name + ' 说:' + msg)
        }
    }
    
    
    
    server.listen(9000, 'localhost')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    2.基于WebSocket(ws)的Socket编程

    • 在浏览器中的控制台输入WebSocket,如果有则说明浏览器支持websocket

    在这里插入图片描述

    • 安装ws(a Node.js WebSocket library):npm i ws

    前端:

    index.html

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>WebSockettitle>
        <script src="./js/WsClient.js" charset="utf-8">script>
    head>
    
    <body>
        <h1>gp 交流区h1>
        <div id="content" name="name" style="overflow-y: scroll; width: 400px; height: 300px; border: solid 1px #000">div>
        <br />
        <div>
            <input type="text" id="msg" style="width: 200px;">
        div>
        <button id="submit">提交button>
        <script>
            document.querySelector('#submit')
                .addEventListener('click', function () {
                    var msg2 = msg.value
                    ws.send(msg2) // 核心代码,将表单里的数据提交给server端
                    msg.value = ''
                }, false)
        script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    WsClient.js

    var ws = new WebSocket('ws://localhost:9527/')
    
    ws.onopen = () => {
        console.log(0)
        ws.send('大家好!')
        ws.send('hello')
        console.log(1)
    }
    
    ws.onmessage = (msg) => {
        console.log(msg)
        console.log(s = msg.data)
        const content = document.getElementById('content')
        content.innerHTML += msg.data + '
    '
    } ws.onerror = (err) => { console.log(err); } ws.onclose = () => { console.log('closed~'); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    后端:

    Server.js

    const WebSocket = require('ws');
    
    const wss = new WebSocket.WebSocketServer({ port: 9527 });
    
    wss.on('connection', function connection(ws) {
    
        ws.on('open', function open() {
            console.log('connected')
        })
    
        //注意最新版本的ws才有isBinary这个参数,而且是必填项
        ws.on('message', function message(data, isBinary) {
            //广播操作
            wss.clients.forEach(function each(client) {
                if (client.readyState === WebSocket.OPEN) {
                    client.send(data, { binary: isBinary });
                }
            });
        });
    
    
    
        ws.on('close', function close() {
            console.log('disconnected')
        })
    });
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    3.基于Socket.io的Socket编程

    • 最低可以兼容ie8,这个也是企业常用的一种方案

    • socket.io官网:https://socket.io/

    • 安装插件:npm i socket.io npm i express

    • 前端:

    index.html

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>socket.iotitle>
        
        <script src="https://cdn.bootcdn.net/ajax/libs/socket.io/4.5.1/socket.io.js">script>
    head>
    
    <body>
        <h1>gp 交流区h1>
        <div id="content" name="name" style="overflow-y: scroll; width: 400px; height: 300px; border: solid 1px #000">div>
        <br />
        <div>
            <input type="text" id="msg" style="width: 200px;">
        div>
        <button id="submit">提交button>
        <script>
            var socket = io.connect('http://localhost:3000');
            const content = document.getElementById('content')
            document.querySelector('#submit')
                .addEventListener('click', function () {
                    var msg2 = msg.value
                    //emit提交/触发,事件名,事件要传递的值
                    socket.emit('receive', msg2) // 核心代码
                    msg.value = ''
                    content.innerHTML += msg2 + '
    '
    }, false) socket.on('message', function (msg) { content.innerHTML += msg + '
    '
    })
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 后端:

    Server.js

    const express = require('express');
    const app = express();
    const http = require('http');
    const server = http.createServer(app);
    const { Server } = require("socket.io");
    const io = new Server(server);
    
    //使用express静态文件管理的中间件
    app.use(express.static('./public'))
    
    app.get('/', (req, res) => {
        // res.sendFile(__dirname + '/public/index.html');
        res.send('hello')
    });
    
    io.on('connection', (socket) => {
        console.log('a user connected');
        socket.on('receive', (data) => {
            console.log(data)
            //开始广播事件
            socket.broadcast.emit('message', data)
        })
    });
    
    server.listen(3000, 'localhost', () => {
        console.log('listening on *:3000');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    golang 并发--goroutine(四)
    WSL-Ubuntu20.04训练环境配置
    2023-简单点-IOU计算
    【计算机视觉】BYOL 讲解
    A-Level经济真题每期一练(20)
    在ubuntu中恢复误删除的文件
    后端请求转发与请求重定对于向前端静态资源的加载影响
    【vue2第十三章】自定义指令 自定义v-loading指令
    【软件测试】如何用python连接Linux服务器
    pycharm连接远程服务器进行调试
  • 原文地址:https://blog.csdn.net/m0_50315078/article/details/126493683