1. 安装js插件

js.dlljs.so文件放到kangle的bin目录下,在kangle的ext目录创建js.dso.xml文件

windows

<!--#start 1 -->
<config>
<dso_extend name='js' filename='bin/js.dll'/>
</config>

linux

<!--#start 1 -->
<config>
<dso_extend name='js' filename='bin/js.so'/>
</config>

重起kangle,即可加载js扩展。可以进入3311点左边扩展,再点dso,可以查看是否加载成功。

2. 配置js插件

1. 配置文件使用

在kangle的ext目录,新创建一个配置文件,文件名任意.

<config>
    <request>
        <table name='BEGIN'>
            <chain  action='continue' >
                <mark_js  module='文件名' config='json配置'></mark_js>
            </chain>
        </table>
    </request>
</config>

文件名指定你要加载的js文件名,可以是绝对路径,也可以是相对路径(从kangle安装目录算),config用于js模块的配置,json格式,如有特殊符号,请用html encode。
例如:

<config>
	<request >
		<table name='BEGIN'>
			<chain  action='continue' >
				<mark_js  module='jsdso/test/main.js' config='{&#34;name&#34;:&#34;test&#34;}'></mark_js>
			</chain>
		</table>
	</request>
</config>

此处config配置为{"name":"test"}
创建或修改配置文件后,请运行kangle -r,使kangle重新加载配置文件。

2. web控制台操作

用浏览器打开3311,进入请求控制,点插入,在可用的标记模块里面选择js,输入模块文件名和config配置,即可。

3. js插件入口函数

入口函数由5个,分别是init,check,open,job,shutdown,分别表示不同的意义,并且由globalThis指定。例如:

globalThis.init = function() {
    console.log("init now");
}

4. r全局对象

系统提供全局的r对象,可以在任何地方调用。例如:

console.log(r.getUrl());

r.getMethod()

返回请求方法

r.getUrl()

返回请求url

r.getUri()

返回请求uri

r.getHost()

返回主机头

r.getPath()

返回path

r.getParam()

返回请求参数

r.getRemoteAddress()

返回请求ip地址

r.getHeader(headerName)

返回请求的http头

r.rewrite(url)

重写请求url.

r.setTimeout(func,msec)

定时任务,延时msec毫秒后执行func函数

r.accept()

接受请求,不可在check中调用。

r.accept(queue)

接受请求,但使请求进入queue 指定队列。
queuestring类型。命名规则如下:
name_maxWorker_maxQueue,如
test_10_0表示使用test的队列,该队列最大并发为10个,不限制排队数.

r.error(code,msg)

拒绝请求,回应状态码为code,信息为msg
例如: r.error(403,"拒绝访问")
当code为0时,表示直接断开连接,并不回应任何信息

r.job(param)

开启后台任务,进入job入口函数,param参数,在job入口函数中可以通过r.getParam()获取

r.open(func,argv1,...)

此函数仅在check过程有效,表示接下来的open入口使用func,而不再是globalThis.open指定。argv1func的参数

r.responseStatus(code)

回应状态码

r.responseHeader(headerName,headerValue)

回应http头,例如:
r.responseHeader("Content-Type","text/html; charset=utf-8");

r.setCallback(callbackObj)

设置回调object,此object要可实现如下函数供kangle回调。

r.responseBody()

回应完http头准备回应body部分,kangle会通过r.setCallback(callbackObj)设置的callbackObj读取。

r.response(body)

callbackObjread函数中,可以调用这个函数发送http的body部分。

check中不可用

r.responseFlush()

由于r.response()只是把body写入buffer中,并没有真正发送到对方,故可以调用r.responseFlush()实现真正发送内容。

check中不可用

r.finish()

发送http body结束。check中不可用

r.finish(body)

发送http body并且结束.

注意调用此函数,将会替换r.response(body)存入buffer部分的信息。
一般用于check入口函数中

r.usOpen(callbackObj,[queue])

打开上游,并且设置callbackObj供上游回调。queue可选。
callbackObj可实现如下函数:

r.usRead()

在收到上游调用responseBody后,可以根据情况,调用r.usRead()通知上游发送body.

r.usClose()

关闭上游。

r.usRedirect(target,callbackObj,[queue])

重定向上游到target,设置callbackObj 供上游回调,queue可选。

r.redirect(target,[queue])

重定向到target,queue可选。

5. share模块

share模块,是一个内置的数据共享库。目前提供一个双向链表和map
使用时在js代码最前面使用import引入.如下:

import * as share from "share"

1. 模块全局方法

share.createMap(name)

创建一个name的map table

share.createList(name)

创建一个name的list table

share.open(name)

打开一个name数据集,返回一个table的对象。

share.newElement()

创建一个元素element

2. table类

所有类型table都有以下接口:

table.count()

返回元素个数

其中map table提供以下接口

table.get(key)

返回key的元素element,key为string

table.set(key,element|string)

设置一个key的元素

table.remove(key)

删除key元素,并返回。如果不存在key,则返回JS_UNDEFINED

list table提供以下接口

table.getHead()

获取开始的element元素

table.getEnd()

获取结尾的元素

table.popHead()

弹出开头的元素

table.popEnd()

弹出结尾的元素

table.pushHead(element)

把元素插入开头

table.pushEnd(element)

把元素插入结尾

3. element操作

每个element有两个数据,一个是字符串,一个是64位的数字型,其中数字可以进行数学运算。两个值互相独立操作,不会相互影响。

element.getString()

获取元素字符串

element.setString(str)

设置元素字符串

element.getInt()

获取元素数字值

element.setInt(int)

设置元素数字值

element.add(int)

元素数字增加或减少,原子操作

element.cas(cmp,value)

元素进行cas原子操作,cmp比较值,如果元素数字是cmp,则设置为value,并且返回true,否则返回false

6. socket模块

本模块,提供高性能全异步tcp socket操作,目前仅支持作为client发起连接请求,并不支持server端的listen/accept等操作。
使用方法:在js文件开头引入即可:

import * as socket from "socket";

1. 全局函数

socket.create()

创建socket,返回socket类

2. socket类

1. socket.connect(host,port)

连接host,port,返回Promise对象。

2. socket.write(data)

发送数据,data可以为string,也可以是ArrayBuffer,返回Promise对象。

3. socket.read()

接收数据,返回Promise,成功后resolve参数为ArrayBuffer

4. socket.close()

关闭socket,没有返回。

5. socket.shutdown()

对socket执行shutdown操作,无返回。