Vue3 自己動手寫 websocket 底層

才剛學完 vue2 的 websocket 底層,馬上又要來寫 vue3 版本了。

沒辦法,想幫客戶用比較新的技術,以免他大佬幾年都懶得翻新網站,到時候維護時苦的還是我~QQ

原本 vue2 的概念是建立一個 vue 實例,然後可以在獨立出來的api.js檔案中去存取 vuex;但現在 vue3 有了useStore這個方法,我們就可以單純寫 js 就好囉!

 

新增一隻檔案 utils/api.js

首先我們需要知道後端 websocket 的網址~

這種寫死的東西呢,最好是找一個檔案去放,以免之後要改還要去翻程式碼,很麻煩的。

const wsUrl = process.env.VUE_APP_API_URL; 

 

建立 websocket 連線

這邊我們要做三件事:連線(onopen)、監聽訊息(onmessage)、監聽錯誤(onerror)

var socket = null;

export const connectSocket = () => {  
  socket = new WebSocket(wsUrl); // 這邊就是剛剛上面的process.env.VUE_APP_API_URL

  socket.onopen = function() { //連線(onopen)
    console.log("websocket connected!!");
  };
  socket.onmessage = function(msg) { //監聽訊息(onmessage)
    console.log("onmessage", msg);
  };
  socket.onerror = function(err) { //監聽錯誤(onerror)
    console.log("error", err);
  };
};

等等要在App.vue中使用,所以這邊就直接export了。

監聽訊息(onmessage):因為現在只是接收訊息後console出來,我們希望的是可以在 vue 實例中可以存取訊息,所以我打算把它放在 vuex 中,這樣就不用在每個頁面去接收訊息。

 

加入vuex

我在這邊幫 websocket 獨立了一個 vuex module 出來,所以先新增一隻檔案store/ws.js

基本上就是一個放訊息state寫訊息mutaion

export const state = {
  wsRes: {},
};
export const actions = {};

export const mutations = {
  setWsRes(state, payload) {
    state.wsRes = payload;
  },
};
export const getters = {};

export default {
  state,
  actions,
  mutations,
  getters,
  namespaced: true,
};

然後要記得在store/index.js引用

import { createStore } from "vuex";
import ws from "./ws";

export default createStore({
  state: {},
  mutations: {},
  actions: {},
  modules: { ws },
});

創建好之後就可以在個地方呼叫useStore()使用:

import { useStore } from "vuex";

export const connectSocket = () => {
  const store = useStore();
 //...
  socket.onmessage = function(msg) {
    store.commit("ws/setWsRes", JSON.parse(msg ?? {}));
  };
  //...
};

 

傳送訊息

我們除了接收訊息,還要有傳送訊息的功能:

要在個頁面使用,所以一樣要export出來。

export const sendSocketMessage = msg => {
  if (1 === socket.readyState) socket.send(JSON.stringify(msg));
};

 

到目前為止,完整的utils/api.js

import { useStore } from "vuex";
const wsUrl = process.env.VUE_APP_API_URL;
var socket = null;

export const connectSocket = () => {
  socket = new WebSocket(wsUrl);
  const store = useStore();
  socket.onopen = function() {
    console.log("websocket connected!!");
  };
  socket.onmessage = function(msg) {
    store.commit("ws/setWsRes", JSON.parse(msg ?? {}));
  };
  socket.onerror = function(err) {
    console.log("error", err);
  };
};

export const sendSocketMessage = msg => {
  if (1 === socket.readyState) socket.send(JSON.stringify(msg));
};

 

在頁面中引用

重頭戲來了!

我們有三件事情要做:

  1. 進入網站時與 websocket 連線。
  2. 按下按鈕送出訊息給後端。
  3. 頁面中取用 websocket 送出的訊息。

 

1. 進入網站時與 websocket 連線。

App.vue中的setup()連線。

因為 vue3 沒有created這種東西(但是有mounted),所以直接寫在setup()就好了。

import { connectSocket } from "./utils/api";

//...

setup() {
  connectSocket();
  return {};
}

 

2. 按下按鈕送出訊息給後端。

<button @click="onSubmit">
  Login
</button>

//...

import { sendSocketMessage } from "@G/utils/api";
import { useStore } from "vuex";

//...

setup() {
  const store = useStore();
  const onSubmit = () => {
    sendSocketMessage({
      msg: "some message to websocket server",
    });
  };
  return { onSubmit };
},

 

3. 頁面中取用 websocket 送出的訊息。

因為我們已經在底層那隻utils/api.js把接收到的訊息直接存到 vuex,所以這邊直接取用 vuex 就好。

import { computed } from "vue";
import { useStore } from "vuex";

//...

setup() {
  const store = useStore();
  const wsRes = computed(() => store.state.ws.wsRes);
  return { wsRes };
},

學習程式原來可以這麼簡單:六角學院線上課程

初學者如何成為vue前端工程師:查看課程內容

---------------------------

| 軟體開發 | 網站建置 | 網頁系統 | 資料庫網站 |

| 客製化網站 (報名系統、投票系統、掛號系統...) |

| 前後端技術合作 |

歡迎與我們聯繫:jessica@penueling.com

加入Line立即聊聊:@539mjyid

3+
0 回復

發表評論

Want to join the discussion?
Feel free to contribute!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。