修改aardio.js,连接web.socket.jsonServer
By
money
at 2021-10-09 • 0人收藏 • 1060人看过
/*
源码参考修改自:aardio.js
websocket转promise部分参考自网络
*/
(function(name, definition) {
var hasDefine = typeof define === "function",
hasExports = typeof module !== "undefined" && module.exports;
if (hasDefine) {
define(definition);
} else if (hasExports) {
module.exports = definition();
} else {
this[name] = definition();
}
})("aardio",
function() {
class promiseSocket {
constructor(url) {
this.url = url; // close来源判断及后续操作
this.closeConfig = {
resolve: null,
closing: false
} // promise池
this.promisePool = {};
this.open()
}
open() {
return new Promise((resolve, reject) =>{
if (typeof this._websocket === 'undefined') {
this._websocket = new WebSocket(this.url);
this._websocket.onopen = (e) =>{
this.onopen && this.onopen(e);
resolve({
e,
ws: this
});
};
this._websocket.onerror = (e) =>{
reject(e);
this.onerror && this.onerror(e)
}
}
this._websocket.onclose = (e) =>{ // 非主动close
if (!this.closeConfig.closing) {
console.log('reconnect'); // 对应的重连 操作
//setTimeout(this._websocket.open, 1000)
} // 若手动close,恢复初始状态
this.closeConfig.closing = false;
this.onclose && this.onclose(e)
}
this._websocket.onmessage = (e) =>{
var json = JSON.parse(e.data);
const key = json.id;
if (key) {
const req = this.promisePool[key];
if (req) {
req.resolve(json);
delete this.promisePool[key];
} else {
this.onmessage && this.onmessage(e)
}
} else {
this.onmessage && this.onmessage(e)
}
};
});
}
close() {
this.closeConfig.closing = true;
this._websocket.close();
} // token包含在content中
send(content) {
return new Promise((resolve, reject) =>{
if (this._websocket.readyState == 1) {
if (content.id) {
this.promisePool[content.id] = {
content,
resolve,
reject
};
}
this._websocket.send(JSON.stringify(content));
} else {
reject("websocket未连接!")
}
});
}
}
let aardio = {};
let hasWindow = typeof window !== "undefined";
aardio.browser = hasWindow;
if (typeof navigator === "object" && typeof navigator.userAgent === "string" && navigator.userAgent.indexOf("Electron") >= 0) {
aardio.electron = true;
}
aardio.fullUrl = function(path) {
if (path.indexOf(":") > 0) return path;
if (window.location.protocol === "file:") {
return`$ { (window.location.href).replace(/[^\\\/]*$/, "")
}
$ {
path
}`
}
return`$ {
window.location.protocol
} //${window.location.host}/${path}`
}
aardio.getCurrentWindow = function() {};
aardio.getMainWindow = function() {};
let ws;
let createWebSocket;
createWebSocket = (url) =>new promiseSocket(url);
aardio.isConnected = () =>!!aardio.rpcClientId;
let xcall;
let rpcNotifications = new Object();
let urlQuery = function(variable) {
let query = window.location.search.slice(1);
let vars = query.split("&");
for (let i = 0; i < vars.length; i++) {
let pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return false;
};
function off(method, notify) {
if (rpcNotifications[method]) {
if (notify) {
var fns = rpcNotifications[method];
if (fns) {
fns = fns.filter(l =>l != notify);
if (fns.length) {
rpcNotifications[method] = fns;
} else {
delete rpcNotifications[method];
}
}
} else {
delete rpcNotifications[method];
}
}
return aardio;
}
function on(method, notify) {
if (rpcNotifications[method]) {
rpcNotifications[method].push(notify);
} else {
rpcNotifications[method] = [notify];
}
return {
off: () =>{
off(method, notify)
}
}
}
on("doScript", js =>{
if (!aardio.browser) global.eval("(()=>{" + js + "})()");
else window.eval("(()=>{" + js + "})()");
});
function emit(method, ...rest) {
let result;
if (rpcNotifications[method]) {
rpcNotifications[method].forEach(notify =>{
result = notify.apply(aardio, rest);
});
}
return result;
}
function aasdlParse(obj, ex, pk) {
for (var k in obj) {
let method = k;
if (typeof pk == "string") method = pk + "." + k;
else {
if (ex[k]) {
continue;
}
}
if (typeof obj[k] == "object") {
ex[k] = {};
aasdlParse(obj[k], ex[k], method);
continue;
}
ex[k] = function() {
return xcall.apply(ex, [method, ...arguments]);
};
}
}
function initRpcClient() {
let onUrlReady = () =>{
aardio.isReady = true;
emit("ready", aardio.getCurrentWindow());
off("ready");
//xcall("$onUrlReady", document.location.href);
}
if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) {
window.setTimeout(onUrlReady);
} else {
document.addEventListener("DOMContentLoaded",
function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
onUrlReady();
});
}
}
let rpcAasdl;
if (aardio.browser && window) {
rpcAasdl = '{{{$rpcAasdl}}}';
if (rpcAasdl === "{{{$rpc" + "Aasdl}}}") {
rpcAasdl = urlQuery("rpcAasdl");
if (typeof rpcAasdl == "string") {
rpcAasdl = decodeURIComponent(rpcAasdl);
sessionStorage.setItem("rpcAasdl", rpcAasdl);
} else {
rpcAasdl = sessionStorage.getItem("rpcAasdl");
}
}
if (rpcAasdl) {
rpcAasdl = JSON.parse(rpcAasdl)
}
}
if (rpcAasdl) {
aasdlParse(rpcAasdl, aardio);
rpcAasdl = true;
}
on("rpcClientId", id =>{
aardio.rpcClientId = id;
emit("rpcReady");
off("rpcReady");
if (rpcAasdl) {
initRpcClient();
} else {
xcall("?").then((aasdl, error) =>{
aasdlParse(JSON.parse(aasdl), aardio);
initRpcClient();
}).
catch(e =>{
console.error(e);
});
}
});
const rpcReady = callback =>{
if (aardio.rpcClientId) {
callback();
} else {
on("rpcReady", callback);
}
};
xcall = function(method, ...args) {
var reqData = {
method: method,
id: method,
jsonrpc: "2.0",
params: args
};
return new Promise((resolve, reject) =>{
rpcReady(() =>{
ws.send(reqData).then(json =>{
if (json.error) {
console.error("调用aardio函数时遇到错误,请求数据:", reqData);
reject(json.error);
} else resolve(json.result);
}).
catch(e =>reject(e));
});
});
};
aardio.xcall = xcall;
aardio.on = on;
aardio.off = off;
aardio.ready = callback =>{
if (aardio.isReady) {
callback(aardio.getCurrentWindow());
} else {
on("ready", callback);
}
};
aardio.rpc = true;
aardio.open = function(rpcServerHost, rpcServerPort) {
return new Promise((resolve, reject) =>{
if (aardio.rpcClientId) {
return resolve(true);
}
if (window) {
if (!rpcServerPort) {
rpcServerPort = "{{{$rpcServerPort}}}";
if (rpcServerPort === "{{{$rpcServer" + "Port}}}") {
rpcServerPort = urlQuery("rpcServerPort");
if (typeof rpcServerPort == "string") {
sessionStorage.setItem("rpcServerPort", rpcServerPort);
} else {
rpcServerPort = sessionStorage.getItem("rpcServerPort");
}
}
}
}
if (rpcServerPort) {
ws = createWebSocket("ws://" + rpcServerHost + ":" + rpcServerPort + "/rpc/ws");
} else {
return reject("The port number is missing.");
}
ws.onopen = function(e) {
aardio.ready(() =>resolve(true))
};
ws.onclose = function(e) {
delete aardio.rpcClientId;
emit("close");
};
ws.onerror = function(e) {
delete aardio.rpcClientId;
console.error(e);
reject("WebSocket Error");
};
ws.onmessage = function(e) {
var rep = JSON.parse(e.data);
if (typeof rep.method == "string") {
var notify = rpcNotifications[rep.method];
if (notify) {
var result = emit(rep.method, ...rep.params);
if (rep.id) {
var clientRep = {
id: rep.id,
jsonrpc: "2.0",
result: result
};
ws.send(clientRep);
}
}
}
};
});
}
//aardio.open();
return aardio;
});使用方式:
aardio.open("127.0.0.1", 8876).then((e)=>{
//TODO
})登录后方可回帖