electron+socket開發踩坑記

現在正在使用js全棧開發一個基於socket和electron的開源的評分系統,前端使用的是vue技術棧,開發進行了一小部分了,踩了很多坑,現在一一道來

跨域問題:

因爲electron是客戶端,所以跨域問題不可避免,一開始我覺得後臺配一下就可以了,反正我只打算使用http請求開發註冊模塊,其餘的都交給socket來做,後臺配置如下:

app.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  res.header("Access-Control-Allow-Credentials", true);
  res.header("X-Powered-By",' 3.2.1')
  if(req.method=="OPTIONS") res.send(200);/*讓options請求快速返回*/
  else  next();
});
這樣就解決了跨域問題,然而我還是太年輕。。後來才知道這樣雖然可以解決跨域,但是沒法傳session,因爲跨域請求默認不帶cookie。。這就尷尬了,必須要前臺配置如下:
axios.defaults.withCredentials = true
我用的是axios,其他庫或者原生xhr的配置應該都差不多,就是要帶cookie,但是雖然帶過去了,後端卻不認賬。。
res.header("Access-Control-Allow-Origin", "*")
說是這個必須是ip地址,不能默認所有值。。這我哪知道啊,然後就崩潰了,後來就想換token了甚至後來想在electron裏開一個代理。最後神奇的找到了一個配置:
mainWindow = new BrowserWindow({
    webPreferences: {webSecurity: false},
  })
直接改chromium的配置,牛批!!!

socket.io 問題

斷線重連與手動重連衝突,導致多個連接

因爲socket.io會斷線重連,而這時如果我再次手動連接的話,自動重連不會停,如果自動重連也成功的話他會存在兩個相同的連接。看代碼:

window.$socket = this.$io.connect(`${api.basePath}`, {
          reconnection: true,
          reconnectionDelay: 200,
          reconnectionAttempts: 5,
          reconnectionDelayMax: 3000
        })
這就是連接的代碼,我手動連接還是賦值給window.$socket,講道理不管哪個連接成功,或是手動和自動重連都成功了,他也只應該存在一個socket連接,但是。。。神奇的是他會存在兩個連接,我如果打印$socket,他會打印出兩個對象出來,這絕對是違反常理的,至今還沒弄懂到底是什麼原因,但是問題是解決了,因爲我找到了一個方法,在每次手動重連時使用 window.$socket.destory()銷燬掉就可以了,(但是控制檯還是會打印出兩個相同的$socket)這樣emit就不會觸發兩次了


vue中的組件生命週期導致重複監聽socket事件

我在vue的created生命週期中初始化所有的這個組價的socket事件,就是很多個socket.on,然後我的socket是綁定在window上的,所以全局存在,代碼樣例如下:

created () {
    window.$socket.on('open', () => {
        console.log('open事件')
    })
}

但是這裏會有一個問題,當我再次進入這個組件的時候,他會再次監聽一遍socket事件,這會導致事件被多次觸發,打印出socket,我發現了socket.off可以解決問題,所以我們在組件銷燬的時候,將組件所有的事件off掉就可以了

destroyed () {
      this.OffSocket()
    },

但是這樣又會存在問題,當銷燬組件的時候,如果還需要監聽事件怎麼辦?所以我們可以在created中判斷一下是否已經註冊過了,這部分就不提供代碼了

electron中數據問題

用戶使用時的數據

首先是用戶數據,我使用了lowdb保存用戶名和密碼(之前是存在localstorage中),但是這裏會有一個問題,數據庫文件放在什麼地方~,如果直接放在源代碼裏的話,開發環境沒問題,但是打包後,會報權限錯誤,改成777也沒法解決

還好electron提供了用戶目錄,我們可以獲取到路徑

remote.app.getPath('userData')

所以代碼如下:

const adapter = new FileSync(path.join(remote.app.getPath('userData'), './MarkingSystem.json'), {
  serialize: (data) => getEncAse192(JSON.stringify(data), 'xinzai'),
  deserialize: (data) => JSON.parse(getDecAse192(data, 'xinzai'))
})
const MarkingSystem = low(adapter)
MarkingSystem.defaults({User: {username: '', password: ''}}).write()

打包時需要的數據

在打包時我需要打包一個Excel文件,但是我不知道該放在哪裏,我一開始想在打包時將文件拷貝到用戶目錄,但是我發現這樣做的話文件其實並沒有打包,只是在我本機上,並且在build.js中無法獲取到用戶目錄。。。所以我只能猜文件打包後的位置了,代碼如下:

if (process.env.NODE_ENV === 'development') {
  ExcelBuf = fs.readFileSync(path.join(__dirname, '../../static/markExcel.xlsx'))
} else {
  ExcelBuf = fs.readFileSync(path.join(__dirname, './static/markExcel.xlsx'))
}
我吧Excel文件放在static目錄下,因爲放在static中,webpack不會打包,然後我覺得打包後的js文件應該和static目錄在同級目錄下,所以我區分環境進行讀取,成功!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章