资源加载中... loading...

__Serve

__Serve函数用于创建Http服务、TCP服务、Websocket服务(基于Http协议)。

返回一个字符串,记录创建的服务的IP地址、端口。例如:127.0.0.1:8088[::]:8089

string

__Serve(serveURI, handler) __Serve(serveURI, handler, …args)

serveURI参数用于配置服务绑定的协议、IP地址、端口等设置,例如:http://0.0.0.0:8088?gzip=true,即:http://:8088?gzip=true

  • TCP协议 serveURI参数设置例如:tcp://127.0.0.1:6666?tls=true;可以添加证书、私钥例如:tls=true&cert_pem=xxxx&cert_key_pem=xxxx
  • Http协议 serveURI参数设置例如:http://127.0.0.1:6666?gzip=true;可以设置压缩设置:gzip=trueserveURI参数用于Https例如:https://127.0.0.1:6666?tls=true&gzip=true;可以加入cert_pemcert_key_pem参数来加载证书。

serveURI true string handler参数用于传入路由处理函数(Http协议)、消息处理函数(TCP协议)、Stream处理函数(Websocket)。 参数handler传入的回调函数可以定义多个参数,第一个参数为ctx对象(上下文对象)。

handler true function 作为参数handler传入的回调函数的参数的实参,参数arg可能有多个,例如:

__Serve("http://:8088", function(ctx, a, b, c) {
    Log(`ctx.host():`, ctx.host(), ", a=", a, ", b=", b, ", c=", c)
}, 1, 2, 3)

调用__Serve()函数时传入的参数1, 2, 3对应传入回调函数的参数a, b, c

arg false string、number、bool、object、array、function、空值等系统支持的所有类型

function main() {
    let httpServer = __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 = __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, "tcp serve on", echoServer)
    
    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)
    }
}
# 不支持
// 不支持
  • 该函数仅支持JavaScript语言策略。
  • 服务线程与全局作用域隔离,因此不支持闭包或引用外部变量、自定义函数等;但是可以调用平台所有的API函数。
  • Websocket服务基于Http协议实现,可以在path中设置一个路由分支,设计Websocket消息订阅/推送的实现代码,可以参考本节范例代码。

参数handler传入的回调处理函数接收一个ctx参数。ctx参数为一个上下文对象,用于获取数据和写入数据,有以下方法:

  • ctx.proto() 应用于Http/TCP协议,调用时返回协议名称。例如:HTTP/1.1tcp
  • 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-Agentctx.header("User-Agent")
  • ctx.method() 应用于Http协议,调用时返回请求方法,例如GETPOST等。
  • 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,单位毫秒。
  • ctx.write(s) 应用于Http/TCP协议,用于写入字符串数据,可以使用JSON.stringify()编码JSON对象为字符串之后写入。对于WebSocket协议,可以使用该方法将编码后的字符串传递给客户端。

{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go}

EventLoop _G