Type/to search
Built-in Functions
Global
Log
Market
Trade
Account
Futures
Exchange
IO
Network
Storage
Threads
exchange.Go
EventLoop
ctx.subscribe
ctx.poll
ctx.order
ctx.cancel
ctx.orderAsync
ctx.cancelAsync
Subscription
threading
threading.Thread
threading.getThread
threading.mainThread
threading.currentThread
threading.Lock
threading.Condition
threading.Event
threading.Dict
threading.Serve
threading.pending
Thread
ThreadLock
ThreadEvent
ThreadCondition
ThreadDict
Server
TA
Talib
OS
Structures
Built-in Variables and Constants
Conventions
Exchanges

Starts an HTTP, TCP or WebSocket (over HTTP) service inside the strategy process and returns a Server object.

Serve(serveURI, handler)
Serve(serveURI, handler, ...args)

Examples

  • Start an HTTP service and request it from the main thread.

    javascript
    function main() { var server = threading.Serve("http://127.0.0.1:8088", function (ctx) { ctx.write("hello " + ctx.path()) }) Log("serve on", server.addr()) // Output: serve on 127.0.0.1:8088 Log(HttpQuery("http://127.0.0.1:8088/ping")) // Output: hello /ping server.close() }
  • Start an HTTP service (with WebSocket) and a TCP echo service in one process, then test each.

    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() }

Returns

TypeDescription

Server object

A Server object. addr() returns the actual listening address and port, for example 127.0.0.1:8088 or 0.0.0.0:8089; close() and stop() shut the service down.

Arguments

NameTypeRequiredDescription

serveURI

string

Yes

Protocol, bind address, port and options of the service, for example http://0.0.0.0:8088?gzip=true or tcp://127.0.0.1:6666; see the remarks.

handler

function

Yes

Route handler (HTTP), message handler (TCP) or stream handler (WebSocket). It is called once per TCP connection or HTTP request, each in its own thread.
The callback may declare several parameters; the first one is the ctx context object.

arg

string / number / bool / object / array / function / any

No

Extra arguments passed to the handler callback; there can be several, and they become the callback parameters after ctx in order.

See Also

Remarks

  • JavaScript strategies only.
  • Like threads created by Thread, the handler runs in an isolated environment: it cannot reference outer variables, closures or user-defined functions, so pass what it needs through ...args; every platform API is available. Objects such as ThreadDict and ThreadLock can be passed as arguments to share data with other threads.
  • An HTTP service handles one request per connection; what the handler writes with ctx.write() is sent in one piece after the handler returns.
  • At most 64 handlers run at the same time per service; beyond that HTTP requests get 503 and TCP connections are dropped.
  • Services close automatically when the strategy stops; call close() or stop() on the returned object to close one earlier.
  • WebSocket services are built on HTTP: route one path to the WebSocket handler to implement subscription/push, as in the example in this section.
  • The old global function __Serve() still works with the same arguments but returns only the listening address string, i.e. threading.Serve(...).addr(); use threading.Serve() in new code.

The callback passed as handler receives a ctx parameter, a context object for reading request data and writing responses, with the following methods:

  • ctx.proto()
    HTTP/TCP. Returns the protocol name, for example HTTP/1.1 or tcp.
  • ctx.host()
    HTTP. Returns the host information: IP address and port.
  • ctx.path()
    HTTP. Returns the request path.
  • ctx.query(key)
    HTTP. Returns the value of key in the request's query string. For the request http://127.0.0.1:8088?num=123, ctx.query("num") returns "123".
  • ctx.rawQuery()
    HTTP. Returns the raw query string of the request.
  • ctx.headers()
    HTTP. Returns the request headers.
  • ctx.header(key)
    HTTP. Returns the value of one request header, for example ctx.header("User-Agent").
  • ctx.method()
    HTTP. Returns the request method, such as GET or POST.
  • ctx.body()
    HTTP POST. Returns the request body.
  • ctx.setHeader(key, value)
    HTTP. Sets a response header.
  • ctx.setStatus(code)
    HTTP. Sets the response status code, usually at the end of a route branch; the default is 200.
  • ctx.remoteAddr()
    HTTP/TCP. Returns the address and port of the remote client.
  • ctx.localAddr()
    HTTP/TCP. Returns the local address and port of the service.
  • ctx.upgrade("websocket")
    WebSocket over HTTP. Switches ctx to the WebSocket protocol; returns true on success and false on failure.
  • ctx.read(timeout_ms)
    WebSocket and TCP (not plain HTTP). Reads data from the connection; timeout_ms is an optional timeout in milliseconds. Returns null on timeout and an empty string "" when the peer closed the connection.
  • ctx.write(s)
    HTTP/TCP. Writes string data; encode objects with JSON.stringify() first. On a WebSocket connection it sends the string to the client.

Writing serveURI:

  • Only the tcp:// (TCP service) and http:// (HTTP service) prefixes are accepted. WebSocket services use http:// too: call ctx.upgrade("websocket") in the handler to switch.
  • The IP can be omitted, as in http://:8088 (listen on all interfaces); port 0 picks a free port, and addr() on the returned object gives the actual address.
  • Options after ?: gzip=true (gzip compression) and tls=true (TLS: HTTPS, wss, or TLS over TCP). With TLS the PEM certificate and private key must be given as well, URL-encoded, in cert_pem and cert_key_pem, for example http://:8443?tls=true&cert_pem=xxxx&cert_key_pem=xxxx; an HTTPS service is http:// with tls=true.

Using arg: the arguments 1, 2, 3 passed to Serve() below become the callback parameters a, b, c.

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