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

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


1 个回复 | 最后更新于 2021-10-09
2021-10-09   #1

没有仔细看你的代码,

但注意到你删除了大量的代码,又添加了大量的代码,

具体是要解决什么问题呢?


aardio.js 原本就支持 WebSocket 和 Promise,

也可以将对 web.socket.jsonServer 的远程函数调用自动转换为 JavaScript 中的 Promise。


另外标准库有提供 web.rpc.externalServer 

支持单独创建独立的 web.socket.jsonServer 用于支持 aardio.js。



登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前在学aardio+halcon机器视觉.
AARDIO语言QQ群:70517368
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
C大Aardio论坛:Aar爱好者论坛
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
赞助商:才仁机械




Loading...