vue3中使用websocket

效果图
在这里插入图片描述
实现
src/util/socket.ts

let websock: any = null;
let global_callback: any = null;
const serverPort = "8080"; // webSocket连接端口
const wsuri = "ws://" + window.location.hostname + ":" + serverPort + "/wsdemo";
function createWebSocket(callback: any) {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  if (websock == null || typeof websock !== WebSocket) {
    initWebSocket(callback);
  }
}
function initWebSocket(callback: any) {
  global_callback = callback;
  // 初始化websocket
  websock = new WebSocket(wsuri);
  websock.onmessage = function (e: any) {
    websocketonmessage(e);
  };
  websock.onclose = function (e: any) {
    websocketclose(e);
  };
  websock.onopen = function () {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    websocketOpen();
  };
  // 连接发生错误的回调方法
  websock.onerror = function () {
    console.log("WebSocket连接发生错误");
    //createWebSocket();啊,发现这样写会创建多个连接,加延时也不行
  };
}
// 实际调用的方法
function sendSock(agentData: any) {
  if (websock.readyState === websock.OPEN) {
    // 若是ws开启状态
    websocketsend(agentData);
  } else if (websock.readyState === websock.CONNECTING) {
    // 若是 正在开启状态,则等待1s后重新调用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  } else {
    // 若未开启 ,则等待1s后重新调用
    setTimeout(function () {
      sendSock(agentData);
    }, 1000);
  }
}
function closeSock() {
  websock.close();
}
// 数据接收
function websocketonmessage(msg: any) {
  // console.log("收到数据:"+JSON.parse(e.data));
  // console.log("收到数据:"+msg);
  // global_callback(JSON.parse(msg.data));
  // 收到信息为Blob类型时
  let result: any = null;
  // debugger
  if (msg.data instanceof Blob) {
    const reader = new FileReader();
    reader.readAsText(msg.data, "UTF-8");
    reader.onload = (e: any) => {
      console.log(e);
      if (typeof reader.result === "string") {
        result = JSON.parse(reader.result);
      }
      //console.log("websocket收到", result);
      global_callback(result);
    };
  } else {
    result = JSON.parse(msg.data);
    //console.log("websocket收到", result);
    global_callback(result);
  }
}
// 数据发送
function websocketsend(agentData: any) {
  console.log("发送数据:" + agentData);
  websock.send(agentData);
}
// 关闭
function websocketclose(e: any) {
  console.log("connection closed (" + e.code + ")");
}
function websocketOpen(e: any) {
  console.log(e);
  console.log("连接打开");
}
export { sendSock, createWebSocket, closeSock };

src/store/webSocket.ts

import { defineStore } from "pinia";

export const webSocketStore = defineStore("webSocket", {
  state: () => ({
    //推送消息
    data: [],
  }),
  getters: {},

  actions: {
    addMsg(val: any) {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      this.data.push(val);
    },
  },
});

这里面放到了登录成功后在连接websocket
src/viwes/login.vue

<script setup lang="ts">
import { colorStore } from "@/store/color";
import { webSocketStore } from "@/store/webSocket";
import { createWebSocket } from "@/util/socket";
import { useRouter } from "vue-router";
import md5 from "js-md5"; //
import { ref } from "vue";
import loginApi from "@/api/loginApi";
import { ElNotification } from "element-plus";
const color = colorStore();
const webSocket = webSocketStore();
const routers = useRouter();
const username = ref("009999");
const password = ref("0");
const mes = ref();
const global_callback = (msg: any) => {
  console.log("websocket的回调函数收到服务器信息:" + JSON.stringify(msg));
  // console.log("收到服务器信息:" + msg);
  mes.value = JSON.parse(JSON.stringify(msg));
  webSocket.addMsg(mes);
  ElNotification({
    title: "您有一条新的消息y",
    message: mes.value.key,
    position: "bottom-right",
  });
};
const login = () => {
  let params = {
    staffCode: username.value,
    password: md5(password.value.toString()),
  };
  loginApi.login(params).then((res: any) => {
    if (res) {
      sessionStorage.setItem("organizationCode", res.hospitalCode);
      sessionStorage.setItem("token", res.token);
      sessionStorage.setItem("staffCode", res.staffCode);
      sessionStorage.setItem("staffName", res.name);
      sessionStorage.setItem("islogin", "true");
      sessionStorage.setItem("roleList", JSON.stringify(res.roles));
      sessionStorage.setItem("currectRole", JSON.stringify(res.roles[0]));
      loginApi.queryMenuByRoleCode(res.roles[0].roleCode).then((res: any) => {
        if (res) {
          sessionStorage.setItem("menu", JSON.stringify(res));
          routers.push("/");
        }
      });
      createWebSocket(global_callback);
    }
  });
};
</script>

<template>
  <div class="con" :style="{ '--color': color.color }">
    <div id="box" class="login-container">
      <div class="left-container">
        <div class="title">
          <span>
            <img src="../../assets/hip.png" style="height: 15px" />{{
              $t("base.title")
            }}</span
          >
        </div>
        <div class="input-container">
          <input
            type="text"
            name="username"
            placeholder="用户名"
            v-model="username"
          />
          <input
            type="password"
            name="password"
            placeholder="密码"
            v-model="password"
          />
        </div>
        <div class="message-container">
          <span>Copyright © 2022 | {{ $t("login.GoodWill") }}</span>
        </div>
      </div>
      <div class="right-container">
        <div class="regist-container">
          <span class="regist">{{ $t("login.WelcomeLogin") }}</span>
        </div>
        <div class="action-container" @click="login">
          <span>{{ $t("login.submit") }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.con {
  height: calc(100vh - 230px);
  padding-top: 10%;
  background-image: linear-gradient(
    to bottom right,
    rgb(114, 135, 254),
    var(--color)
  );
}
.login-container {
  width: 600px;
  height: 315px;
  margin: 0 auto;
  border-radius: 15px;
  box-shadow: 0 10px 50px 0px rbg(59, 45, 159);
  background-color: rgb(95, 76, 194);
}
#box {
  // outline: 4px solid #fff;
  position: relative;
  overflow: hidden;
  z-index: 1;
}
#box::before {
  content: "";
  position: absolute;
  background: lightgray;
  width: 500px;
  height: 400px;
  z-index: -2;
  left: 50%;
  top: 50%;
  transform-origin: 0 0;
  animation: rotate 5s infinite linear;
}
#box::after {
  content: "";
  position: absolute;
  background: rgb(95, 76, 194);
  width: calc(600px - 4px);
  height: calc(315px - 4px);
  left: 2px;
  top: 2px;
  border-radius: 15px;
  z-index: -1;
}
@keyframes rotate {
  to {
    transform: rotate(1turn);
  }
}
.left-container {
  display: inline-block;
  width: 330px;
  // height: 315px;
  height: 191px;
  margin-top: 2px;
  border-top-left-radius: 15px;
  border-bottom-left-radius: 15px;
  padding: 60px;
  background-image: linear-gradient(
    to bottom right,
    rgb(118, 76, 163),
    rgb(92, 103, 211)
  );
}
.left-container::before {
  content: "";
  width: 200px;
  height: 200px;
  left: 50%;
  top: 50%;
  z-index: -1;
  background-image: linear-gradient(
    to bottom right,
    rgb(118, 76, 163),
    rgb(92, 103, 211)
  );
}
.title {
  color: #fff;
  font-size: 18px;
  font-weight: 200;
}
.title span {
  border-bottom: 3px solid rgb(237, 221, 22);
}
.input-container {
  padding: 20px 0;
}
input {
  border: 0;
  background: none;
  outline: none;
  color: #fff;
  margin: 20px 0;
  display: block;
  width: 100%;
  padding: 5px 0;
  transition: 0.2s;
  border-bottom: 1px solid rgb(199, 191, 219);
}
input:hover {
  border-bottom-color: #fff;
}
::-webkit-input-placeholder {
  color: rgb(199, 191, 219);
}
.message-container {
  font-size: 14px;
  transition: 0.2s;
  color: rgb(199, 191, 219);
  cursor: pointer;
}
.message-container:hover {
  color: #fff;
}
.right-container {
  width: 145px;
  display: inline-block;
  height: calc(100% - 120px);
  vertical-align: top;
  padding: 60px 0;
}
.regist-container {
  text-align: center;
  color: #fff;
  font-size: 18px;
  font-weight: 200;
}
.regist-container span {
  border-bottom: 3px solid rgb(237, 221, 22);
}
.action-container {
  font-size: 10px;
  color: #fff;
  text-align: center;
  position: relative;
  top: 200px;
}
.action-container span {
  border: 1px solid rgb(237, 221, 22);
  padding: 10px;
  display: inline;
  line-height: 20px;
  border-radius: 20px;
  position: absolute;
  bottom: 10px;
  left: calc(72px - 20px);
  transition: 0.2s;
  cursor: pointer;
}
.action-container span:hover {
  background-color: rgb(237, 221, 22);
  color: rgb(95, 76, 194);
}
</style>

附赠后台建议websocket服务供测试使用
链接:https://pan.baidu.com/s/1RzbWiooLwCIuDTnEfN_x0Q?pwd=p58w
提取码:p58w

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值