import genID from 'wsemi/src/genID.mjs'
import genPm from 'wsemi/src/genPm.mjs'
import Evem from 'wsemi/src/evem.mjs'
import isfun from 'wsemi/src/isfun.mjs'
//import b642u8arr from 'wsemi/src/b642u8arr.mjs'
import b642str from 'wsemi/src/b642str.mjs'
//codeB64, 此處需提供worker執行程式碼, 因有特殊符號編譯困難, 故需先轉base64再使用
let codeB64 = '{codeB64}'
//code
//let code = b642u8arr(codeB64)
let code = b642str(codeB64)
function genWebWorker(code) {
//URL
let URL = window.URL || window.webkitURL
//blob
let blob
try {
//BlobBuilder for IE11, 依然有安全性問題
let BlobBuilder = window.BlobBuilder ||
window.WebKitBlobBuilder ||
window.MozBlobBuilder ||
window.MSBlobBuilder
blob = new BlobBuilder()
blob.append(code)
blob = blob.getBlob()
return new Worker(URL.createObjectURL(blob))
}
catch (e) {
//console.log('can not use BlobBuilder', e)
}
try {
//blob for Chrome 8+, Firefox 6+, Safari 6.0+, Opera 15+
blob = new Blob([code])
return new Worker(URL.createObjectURL(blob))
}
catch (e) {
//console.log('can not use Blob', e)
}
try {
//data:application/javascript for Opera 10.60 - 12
return new Worker('data:application/javascript,' + encodeURIComponent(code))
}
catch (e) {
//console.log('can not use application/javascript', e)
}
return null
}
/**
* 於瀏覽器(Browser)通過Web Worker建立WebSocket使用者端物件
*
* @class
* @param {Object} opt 輸入設定參數物件
* @param {String} [opt.url='ws://localhost:8080'] 輸入WebSocket伺服器ws網址,預設為'ws://localhost:8080'
* @param {String} [opt.token='*'] 輸入使用者認證用token,預設為'*'
* @param {Integer} [opt.strSplitLength=1000000] 輸入傳輸封包長度整數,預設為1000000
* @returns {Object} 回傳通訊物件,可監聽事件open、openOnce、close、error、reconn、broadcast、deliver,可使用函數execute、broadcast、deliver
* @example
*
* <script src="dist/w-converws-client-webworker.umd.js"></script>
*
* let opt = {
* url: 'ws://localhost:8080',
* token: '*',
* }
*
* //new
* let WConverwsClient = window['w-converws-client-webworker']
* let wo = new WConverwsClient(opt)
*
* wo.on('open', function() {
* console.log('client web: open')
* })
* wo.on('openOnce', function() {
* console.log('client web: openOnce')
*
* //execute
* wo.execute('add', { p1: 1, p2: 2 },
* function (prog) {
* console.log('client web: execute prog=', prog)
* })
* .then(function(r) {
* console.log('client web: execute: add=', r)
* })
*
* //broadcast
* wo.broadcast('client web broadcast hi', function (prog) {
* console.log('client web: broadcast prog=', prog)
* })
*
* //deliver
* wo.deliver('client deliver hi', function (prog) {
* console.log('client web: deliver prog=', prog)
* })
*
* })
* wo.on('close', function() {
* console.log('client web: close')
* })
* wo.on('error', function(err) {
* console.log('client web: error=', err)
* })
* wo.on('reconn', function() {
* console.log('client web: reconn')
* })
* wo.on('broadcast', function(data) {
* console.log('client web: broadcast=', data)
* })
* // wo.on('deliver', function(data) { //伺服器目前無法針對client直接deliver
* // console.log('client web: deliver=', data)
* // })
*
*/
function WConverwsClientWebworker(opt) {
//ee
let ee = new Evem()
//wk
// let blob = new Blob([code], { type: 'text/javascript' })
// let url = URL.createObjectURL(blob)
// let wk = new Worker(url)
// let wk = new Worker('./wkapi/wscs_webworker.mjs')
let wk = genWebWorker(code)
//check, IE11安全性問題
if (wk === null) {
return null
}
function init(opt) {
//_id
let _id = genID()
//msg
let msg = {
_id,
type: 'init',
input: opt,
}
//postMessage
wk.postMessage(msg)
}
init(opt)
function terminate() {
wk.terminate()
wk = undefined
}
function execute(func, input, callback) {
//pm
let pm = genPm()
//_id
let _id = genID()
//msg
let msg = {
_id,
type: 'execute',
func,
input,
}
//postMessage
wk.postMessage(msg)
//等待結果回傳
ee.on(_id, function (data) {
//prog
if (data.prog) {
if (isfun(callback)) {
//callback
callback(data.prog)
}
}
//output
else {
//resolve
pm.resolve(data.output)
//removeAllListeners
ee.removeAllListeners(_id)
}
})
return pm
}
function core(type, input, callback) {
//pm
let pm = genPm()
//_id
let _id = genID()
//msg
let msg = {
_id,
type,
input,
}
//postMessage
wk.postMessage(msg)
//等待結果回傳
ee.on(_id, function (data) {
//callback
if (isfun(callback)) {
callback(data.prog)
}
//finish
if (data.prog === 100) {
//resolve
pm.resolve()
//removeAllListeners
ee.removeAllListeners(_id)
}
})
return pm
}
function broadcast(input, callback) {
return core('broadcast', input, callback)
}
function deliver(input, callback) {
return core('deliver', input, callback)
}
wk.onmessage = function (e) {
//data
let data = e.data
//_id
let _id = data._id
if (_id !== 'system') {
//emit
ee.emit(_id, data)
}
else {
//emit
ee.emit(data.func, data.data)
}
}
//save
ee.execute = execute
ee.broadcast = broadcast
ee.deliver = deliver
ee.terminate = terminate
return ee
}
export default WConverwsClientWebworker