threading.Serve
在策略进程内创建Http服务、TCP服务、Websocket服务(基于Http协议),返回Server对象。
Serve(serveURI, handler)
Serve(serveURI, handler, ...args)示例
启动一个HTTP服务,按请求路径返回不同的数据。
javascript
function main() {
let httpServer = threading.Serve("http://:8088?gzip=true", function (ctx) {
Log("http connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
let path = ctx.path()
if (path == "/") {
ctx.write(JSON.stringify({
path: ctx.path(),
method: ctx.method(),
headers: ctx.headers(),
cookie: ctx.header("Cookie"),
remote: ctx.remoteAddr(),
query: ctx.rawQuery()
}))
} else if (path == "/tickers") {
let ret = exchange.GetTickers()
if (!ret) {
ctx.setStatus(500)
ctx.write(GetLastError())
} else {
ctx.write(JSON.stringify(ret))
}
} else if (path == "/wss") {
if (ctx.upgrade("websocket")) { // upgrade to websocket
while (true) {
let r = ctx.read(10)
if (r == "") {
break
} else if (r) {
if (r == "ticker") {
ctx.write(JSON.stringify(exchange.GetTicker()))
} else {
ctx.write("not support")
}
}
}
Log("websocket closed", ctx.remoteAddr())
}
} else {
ctx.setStatus(404)
}
})
let echoServer = threading.Serve("tcp://:8089", function (ctx) {
Log("tcp connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
while (true) {
let d = ctx.read()
if (!d) {
break
}
ctx.write(d)
}
Log("connect closed")
})
Log("http serve on", httpServer.addr(), "tcp serve on", echoServer.addr())
for (var i = 0; i < 5; i++) {
if (i == 2) {
// test Http
var retHttp = HttpQuery("http://127.0.0.1:8088?num=123&limit=100", {"debug": true})
Log("retHttp:", retHttp)
} else if (i == 3) {
// test TCP
var tcpConn = Dial("tcp://127.0.0.1:8089")
tcpConn.write("Hello TCP Server")
var retTCP = tcpConn.read()
Log("retTCP:", retTCP)
} else if (i == 4) {
// test Websocket
var wsConn = Dial("ws://127.0.0.1:8088/wss|compress=gzip")
wsConn.write("ticker")
var retWS = wsConn.read(1000)
Log("retWS:", retWS)
// no depth
wsConn.write("depth")
retWS = wsConn.read(1000)
Log("retWS:", retWS)
}
Sleep(1000)
}
httpServer.close()
echoServer.close()
}
python
# 不支持返回值
| 类型 | 描述 |
| 返回 |
参数
| 名称 | 类型 | 必填 | 描述 |
serveURI | string | 是 | 服务的协议、绑定地址、端口和可选设置,例如 |
handler | function | 是 | 路由处理函数(Http协议)、消息处理函数(TCP协议)、Stream处理函数(Websocket)。每个TCP连接、每个Http请求都在独立的线程中调用一次该函数。 |
arg | string / number / bool / object / array / function / any | 否 | 作为参数
调用 |
参考
备注
- 该函数仅支持JavaScript语言策略。
- 处理函数与
Thread创建的线程一样运行在隔离环境中,不能引用外部变量、闭包或自定义函数,需要的数据通过...args传入;可以调用平台所有的API函数。ThreadDict、ThreadLock等对象也可以作为参数传入,与其它线程共享数据。 - Http服务每个连接只处理一个请求,处理函数中
ctx.write()写入的内容在函数返回后一次性发送。 - 每个服务同时执行的处理函数最多64个,超出时Http请求返回
503,TCP连接直接断开。 - 策略停止时服务自动关闭;需要提前关闭时调用返回对象的
close()或stop()。 Websocket服务基于Http协议实现,可以在path中设置一个路由分支,设计Websocket消息订阅/推送的实现代码,可以参考本节范例代码。- 旧的全局函数
__Serve()仍然可以使用,参数相同,返回值是监听地址字符串,相当于threading.Serve(...).addr();新代码请使用threading.Serve()。
参数handler传入的回调处理函数接收一个ctx参数。ctx参数为一个上下文对象,用于获取数据和写入数据,有以下方法:
- ctx.proto()
应用于Http/TCP协议,调用时返回协议名称。例如:HTTP/1.1、tcp。 - ctx.host()
应用于Http协议,调用时返回主机信息:IP地址、端口。 - ctx.path()
应用于Http协议,调用时返回请求路径。 - ctx.query(key)
应用于Http协议,调用时返回请求中query查询中key对应的值。例如发送的请求为:http://127.0.0.1:8088?num=123,参数handler传入的回调处理函数中ctx.query("num")调用时返回"123"。 - ctx.rawQuery()
应用于Http协议,调用时返回请求中的原始查询(Http请求的query)。 - ctx.headers()
应用于Http协议,调用时返回请求中的请求头信息。 - ctx.header(key)
应用于Http协议,调用时返回指定的请求头中的某个key对应的值。例如获取当前请求的headers中的User-Agent:ctx.header("User-Agent")。 - ctx.method()
应用于Http协议,调用时返回请求方法,例如GET、POST等。 - ctx.body()
应用于Http协议的POST请求,调用时返回请求的正文。 - ctx.setHeader(key, value)
应用于Http协议,设置应答报文的请求头信息。 - ctx.setStatus(code)
应用于Http协议,设置Http报文状态码,通常在路由分支最后设置Http状态码,默认为200。 - ctx.remoteAddr()
应用于Http/TCP协议,调用时返回请求中的远程客户端地址、端口。 - ctx.localAddr()
应用于Http/TCP协议,调用时返回服务本地地址、端口。 - ctx.upgrade("websocket")
应用于基于Http协议的Websocket协议实现,切换ctx上下文对象为Websocket协议;切换成功返回布尔值(真),失败返回布尔值(假)。 - ctx.read(timeout_ms)
应用于基于Http协议的Websocket协议实现/TCP协议,读取Websocket连接的数据,TCP连接的数据,普通Http协议中不支持使用该read方法;可以指定超时时间参数timeout_ms,单位毫秒。超时返回null,对方关闭连接返回空字符串""。 - ctx.write(s)
应用于Http/TCP协议,用于写入字符串数据,可以使用JSON.stringify()编码JSON对象为字符串之后写入。对于WebSocket协议,可以使用该方法将编码后的字符串传递给客户端。
serveURI格式
配置服务的协议、绑定地址、端口以及可选的设置,例如:http://0.0.0.0:8088?gzip=true,可以省略IP写成http://:8088?gzip=true(监听所有网卡);端口写0时随机分配空闲端口,实际地址用返回对象的addr()获取。
- TCP协议
serveURI参数设置例如:tcp://127.0.0.1:6666。 - Http协议
serveURI参数设置例如:http://127.0.0.1:6666。Websocket服务也使用Http协议,在处理函数中调用ctx.upgrade("websocket")切换。
可以在?后面加入以下设置:
gzip=true:启用gzip压缩。tls=true:启用TLS加密(Https、wss、TLS加密的TCP),必须同时用cert_pem和cert_key_pem传入PEM格式的证书和私钥(内容需要URL编码),例如:http://:8443?tls=true&cert_pem=xxxx&cert_key_pem=xxxx。协议前缀只支持tcp://和http://,Https服务写成http://加tls=true。