vue3-websocket即时通讯

1,189 阅读2分钟

一、 websocket

1. websocket背景:

WebSocket是一种在单个TCP连接上进行全双工的网络通信通信协议。实现了客户端和服务器的平等对话,任何一方都可以主动发送数据。并且在第一次建立后,就一直保持连接。

WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

image.png

image.png

2. 开发目的:

不通过轮询的方式,实现即时通讯,例如:聊天窗

3. vue使用websocket

3.1 封装websocket.ts
const BASE_URL = 'localhost';
const WS_PORT = '8080';
const WS_ADDRESS = `ws://${BASE_URL}:${WS_PORT}`;


export const useWebSocket = (handleMessage) => {
    const ws = new WebSocket(WS_ADDRESS);

    const init = () => {
        ws.addEventListener('open', handleOpen, false);
        ws.addEventListener('close', handleClose, false)
        ws.addEventListener('error', handleError, false)
        ws.addEventListener('message', handleMessage, false)
    }

    function handleOpen(e) {
        console.log('WebSocket open', e);
    }
    function handleClose(e) {
        console.log('WebSocket close', e);
    }
    function handleError(e) {
        console.log('WebSocket error', e);
    }

    init();
    return ws;
} 
3.2 index.vue页面引入websocket.js
<template>
    <div class="websocket_container">
        <!-- 聊天内容 -->
        <div class="chart_container">

        </div>
        <!-- 发送聊天内容 -->
        <div class="send_chart">
            <div class="input_box">
                <input type="text" v-model="inputText">
            </div>
            <div class="send_box" :style="{ color: inputText ? '#39f' : '#999' }">
                <button @click="sendMsg">发送</button>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { useWebSocket } from '@/request/websocket/index';


const sendMsg = () => {
    if (!inputText.value) return;

    const _msg = inputText.value;

    if (!_msg.trim().length) return;

    let sendParams = {
        id: new Date().getTime(),
        msg: _msg,
        curentTime: getTime(new Date()),
        username,
    }
    console.log(sendParams)
    //发送信息
    ws.send(JSON.stringify(sendParams));

    inputText.value = "";
}

// 获取时间
function getTime(time) {
    const oDate = new Date(time); //实例一个时间对象;
    const year = oDate.getFullYear(); //获取系统的年;
    const month = oDate.getMonth() + 1; //获取系统月份,由于月份是从0开始计算,所以要加1
    const date = oDate.getDate(); // 获取系统日,
    const h = oDate.getHours(); //获取系统时,
    const m = oDate.getMinutes(); //分
    const s = oDate.getSeconds(); //秒

    return `${year}${month}${date}${h}:${m}`;
}
</script>

<style lang="less" scoped>
@import "@/assets/styles/common.less";

.send_chart {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: #fff;
    padding: 10px 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;

    .input_box {
        flex-grow: 1;
        padding: 6px 10px;
        border: 1px solid #ccc;
        border-radius: 4px;
    }

    .send_box {
        margin-left: 10px;
        color: @COLOR_MAIN_THREE;
        font-size: 16px;

        &:active {
            opacity: .5;
        }
    }
}

input {
    width: 100%;
    outline: none;
    border: none;
}
</style>
3.3 问题:

image.png image.png

5. 效果图

二、 前端国密加密SM-crypto