修改aardio.js,连接web.socket.jsonServer

By money at 2021-10-09 • 0人收藏 • 907人看过
/*
源码参考修改自: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
})


登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...