//external 服务器
import win.ui;
/*DSG{{*/
var winform = win.form(text="RPC 服务端 - 支持任意本地网页调用 aardio 函数";right=759;bottom=469)
winform.add(
edit={cls="richedit";left=23;top=24;right=730;bottom=446;edge=1;hscroll=1;multiline=1;vscroll=1;z=1}
)
/*}}*/

import web.rpc.externalServer;
var externalServer = web.rpc.externalServer();

//只有下面指定的函数网页才能调用
externalServer.external = {
    test = function(...){
        winform.edit.print("external.test 被调用",...)
    }
	tag = function(strs,...){
		var args = {...}
		for(i=#args;1;-1){
			table.insert(strs,args[i],i+1);
		}
		
		strs = string.join(strs);
		return strs;
	}
}
 
//可选用下面的方法限定只有下面允许的外部域名才能访问 aardio 函数
/*
externalServer.accessControlAllowOrigin = {
    ["https://example.com/"] = true
}
*/

//如果不指定端口号，则默认动态分配空闲的端口号
//如果不指定具体的端口号，则只有 externalServer 提供的网页才能自 aardio.js 自动获取到端口号
winform.edit.print( "启动服务器：",externalServer.start())
winform.edit.print( "请在网页中引入：",externalServer.getUrl("aardio.js"))

externalServer.httpHandler["/test.html"] = function(response,request){
    var html = /**
    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <script src="<?=owner.rpcUrl?>"></script>
        <script>
        /*
        也可以在前端源码中用 npm i aardio 安装 aardio.js ,
        然后再调用 aardio.open( RPC端口号 ) 打开 RPC 服务器，
        这种方式必须事先知道端口号，不能自动分配动态的空闲端口。
        而且在 RPC 连接成功以前，只能使用 aardio.xcall 调用 aardio 函数。
        但直接引用 RPC 服务器提供的 aardio.js 可以自动连接，并在连接成功以前事先建立创建函数。
        如果在创建 web.rpc.externalServer 以后调用标准库中的 nodeJs 创建 Node.js  进程，
        也可以自动获取端口号并在连接成功前创建远程函数。
        */
        aardio.test("这是网页调用 aardio 的参数",1122);
        
		//用 aardio 解析模板字符串
		let $ = aardio.tag;
		$`abc${123}ddd${456}`.then( v=> alert("模板字符串:"+v)  )
        
        </script>
    </head>
    <body><?=owner.rpcUrl?></body></html>
    **/
    response.write( string.loadcode(html,{rpcUrl=externalServer.getUrl("aardio.js")}) );	
}

import process;
process.openUrl(externalServer.getUrl("/test.html"))

winform.show();
win.loopMessage();

/**
global.d.ts 声明 aardio 对象演示：

declare global {

    interface aardioExternal {  
    /* 添加 external 接口导出的 aardio  函数 */
    test: (name: string,value: number) => Promise<string>; 
    }
}
export {};
**/