跳到正文
本頁目錄

🌏 網絡接口 API

下面這些API為腳本提供了基本的網絡接口。
如果有更復雜的需求,可以使用各自語言平臺的網絡庫來完成任務

目錄

發送一個異步HTTP(s) Get請求

network.httpGet(url[,header],callback)

  • 參數:
  • url : String
    請求的目標地址(包括 Get 請求附帶的參數)
  • header : Object
    (可選參數)請求頭
  • callback : Function
    當請求返回時執行的回調函數,用於回傳HTTP(s)響應結果。
  • 返回值:是否成功發送請求
  • 返回值類型:Boolean

注:參數callback的回調函數原型:function(status,result)

  • status : Integer
    返回的HTTP(s)響應碼,如200代表請求成功
  • result : String
    返回的具體數據

如果請求執行失敗,status值將為 -1

發送一個異步HTTP(s) Post請求

network.httpPost(url[,header],data,type,callback)

  • 參數:
  • url : String
    請求的目標地址
  • header : Object
    (可選參數)請求頭
  • data : String
    發送的數據
  • type : String
    發送的 Post 數據類型,形如 text/plain application/x-www-form-urlencoded 等
  • callback : Function
    當請求返回時執行的回調函數,用於回傳HTTP(s)響應結果。
  • 返回值:是否成功發送請求
  • 返回值類型:Boolean

注:參數callback的回調函數原型:function(status,result)

  • status : Integer
    返回的HTTP(s)響應碼,如200代表請求成功
  • result : String
    返回的具體數據

如果請求執行失敗,status值將為 -1

🔌 WebSocket 客戶端對象 API

在腳本引擎中,使用「WebSocket 對象」來操作某個 WebSocket 客戶端的連接和工作

創建一個新的WebSocket 客戶端對象

[JavaScript] new WSClient()
[Lua] WSClient()

  • 返回值:一個新的 websocket 客戶端對象
  • 返回值類型:WSClient

WebSocket 客戶端對象 - 屬性

每一個WS客戶端對象都包含一些固定的對象屬性。對於某個特定的客戶端對象wsc,有以下這些屬性

屬性含義類型
wsc.status當前的連接狀態Enum

這些對象屬性都是隻讀的,無法被修改

其中,wsc.status 枚舉有如下幾種情況:

wsc.Open - 處於正常連接中
wsc.Closing - 正在斷開連接
wsc.Closed - 未連接

WebSocket 客戶端對象 - 函數

每一個WS客戶端對象都包含一些可以執行的成員函數(成員方法)。對於某個特定的客戶端對象wsc,可以通過以下這些函數對這個客戶端進行一些操作

創建連接

wsc.connect(target)

  • 參數:
  • target : String
    要連接的目標地址,形如ws://hostname[:port][/path/path][?query=value]
  • 返回值:是否成功連接
  • 返回值類型:Boolean

異步創建連接

wsc.connectAsync(target,callback)

  • 參數:
  • target : String
    要連接的目標地址,形如ws://hostname[:port][/path/path][?query=value]
  • callback : Function 當連接成功或者失敗時執行的回調函數。
  • 返回值:是否成功開始嘗試連接
  • 返回值類型:Boolean

注:參數callback的回調函數原型:function(success)

  • success : Boolean
    WebSocket 連接是否成功

發送文本 / 二進制消息

wsc.send(msg)

  • 參數:
  • msg : String / ByteBuffer
    要發送的文本 / 二進制數據
  • 返回值:是否成功發送
  • 返回值類型:Boolean

如果傳入的參數類型是String,會按照文本發送,如果是ByteBuffer將按照二進制數據發送

監聽WebSocket事件

在WS工作的過程中,當收到消息或發生錯誤時,需要對相關信息進行處理。這裡給出了監聽事件的接口

wsc.listen(event,callback)

  • 參數:

  • event : String
    要監聽的事件名(見下方監聽事件列表)

  • callback : Function
    註冊的監聽函數(函數相關參數見下)
    當指定的事件發生時,腳本引擎會調用你給出的監聽函數,並傳入相應的參數

  • 返回值:是否成功監聽事件

  • 返回值類型:Boolean

監聽事件列表

"onTextReceived" - 收到文本消息

  • 監聽函數原型 function(msg)
  • 參數:
  • msg : String
    收到的文本消息

"onBinaryReceived" - 收到二進制消息

  • 監聽函數原型 function(data)
  • 參數:
  • data : ByteBuffer
    收到的二進制消息

"onError" - 發生錯誤

  • 監聽函數原型 function(msg)
  • 參數:
  • msg : String
    錯誤的提示信息

"onLostConnection" - 連接丟失

  • 監聽函數原型 function(code)
  • 參數:
  • code : Integer
    錯誤碼

關閉連接

wsc.close()

  • 返回值:是否成功關閉連接
  • 返回值類型:Boolean

在處於關閉狀態時,請勿繼續使用此客戶端對象!

強制斷開連接

wsc.shutdown()

  • 返回值:是否成功斷開連接
  • 返回值類型:Boolean

在處於關閉狀態時,請勿繼續使用此客戶端對象!

獲取錯誤碼

wsc.errorCode()

  • 返回值:上一次錯誤產生的錯誤碼
  • 返回值類型:Integer

如果在上述接口使用中遇到了失敗,可以從這裡獲取上一個錯誤碼

📡 Http 服務端對象 API

腳本引擎提供了簡易的Http服務端服務,可以用於Webhook等數據傳輸量較小的Web服務。
如果您想搭建網站,更推薦使用老牌Web服務軟件如Apache, Nginx等。

創建一個新的服務器對象

[JavaScript] new HttpServer()
[Lua] HttpServer()

  • 返回值:新的服務器對象
  • 返回值類型:HttpServer

監聽 Get 請求

svr.onGet(path, callback)

  • 參數:
  • path : String
    請求目錄,以/開頭,可以包含正則表達式。如: /test/(.+)
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在收到符合path的GET請求回調
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 Put 請求

svr.onPut(path, callback)

  • 參數:
  • path : String
    請求目錄,以/開頭,可以包含正則表達式。如: /test/(.+)
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在收到符合path的PUT請求回調
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 Post 請求

svr.onPost(path, callback)

  • 參數:
  • path : String
    請求目錄,以/開頭,可以包含正則表達式。如: /test/(.+)
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在收到符合path的POST請求回調
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 Patch 請求

svr.onPatch(path, callback)

  • 參數:
  • path : String
    請求目錄,以/開頭,可以包含正則表達式。如: /test/(.+)
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在收到符合path的PATCH請求回調
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 Delete 請求

svr.onDelete(path, callback)

  • 參數:
  • path : String
    請求目錄,以/開頭,可以包含正則表達式。如: /test/(.+)
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在收到符合path的DELETE請求回調
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 Options 請求

svr.onOptions(path, callback)

  • 參數:
  • path : String
    請求目錄,以/開頭,可以包含正則表達式。如: /test/(.+)
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在收到符合path的OPTIONS請求回調
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽請求 - 說明

請注意,請求監聽是有優先級的。
如果有多個路徑同時滿足正則表達式,則選擇先定義的路徑。
例如:

JavaScript
svr.onGet('/test/123', (req, res) => {
  res.write('test');
}).onGet('/test/(.+)', (req, res) => {
  res.write('get /test/');
}).onGet('/test/foo', (req, res) => {
  res.write("bar");
});
// 请求 /test/123 时,第一个回调函数将被调用; 而请求 /test/foo 时,第二个回调函数将被调用(尽管第三个回调函数的路径更匹配)

監聽 PreRouting 預路由事件

svr.onPreRouting(callback)

  • 參數:
  • callback : Function<bool(HttpRequest, HttpResponse)>
    回調函數,在收到請求時調用。在回調函數中可以修改響應,如果返回false,則不會繼續路由至對應路徑的回調函數(但仍然會觸發PostRouting事件)。
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 PostRouting 後路由事件

svr.onPostRouting(callback)

  • 參數:
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在對應目錄的回調函數(或PreRouting事件)執行完畢後調用,在回調函數中可以修改響應
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 Error 錯誤事件

svr.onError(callback)

  • 參數:
  • callback : Function<(HttpRequest, HttpResponse)>
    回調函數,在錯誤(狀態碼 >= 400)時調用
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽 Exception 異常事件

svr.onException(callback)

  • 參數:
  • callback : Function<(HttpRequest, HttpResponse, String)>
    回調函數,在handler中有拋出異常時調用,參數3為異常信息
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

監聽端口並開啟服務器

svr.listen(addr, port)
svr.startAt(addr, port)

  • 參數:
  • addr : String
    監聽地址,可以是IP地址或域名
  • port : Integer
    監聽端口
  • 返回值:處理完畢的服務器對象(便於連鎖進行其他操作)
  • 返回值類型:HttpServer

停止服務器

svr.stop()

  • 返回值:無

獲取服務器是否正在運行

svr.isRunning()

  • 返回值:服務器正在運行與否
  • 返回值類型:Boolean

Http 請求對象 API

Http請求對象 - 屬性

屬性含義類型例
req.method請求方法String'GET'
req.path請求路徑String'/233'
req.query請求查詢參數Object{a: 'b', c: ['d', 'e']}
req.params請求查詢參數(同上)Object{a: 'b', c: ['d', 'e']}
req.headers請求頭Object{a: ['b'], c: ['d', 'e']}
req.body請求內容String'awa'
req.remoteAddr請求源地址String'114.51.41.91'
req.remotePort請求源端口Integer11451
req.version請求版本String'HTTP/1.1'
req.matches請求路徑正則匹配結果Array['/test11', '11']

這些對象屬性都是隻讀的,無法被修改,並且只能在請求回調函數中使用(理論上覆制到外部也可以,但不推薦)。

注意: 1. req.matches[0] 為原始文本,其後面的元素才是匹配結果 2. req.headers["Name"] 為數組而不是字符串

擴展例子: 1. ?k=v1&k=v2&k1=v1 => {k: ['v1', 'v2'], k1: 'v1'} 2. /test/(.+)/(.+) => /test/ll/233 => ['/test/ll/233', 'll', '233']

獲取指定請求頭的值

req.getHeader(name)

  • 參數:
  • name : String
    請求頭名稱
  • 返回值:請求頭的值數組(如果沒有該請求頭,則返回[]空數組)
  • 返回值類型:Array<String>

Http 響應對象 API

Http響應對象 - 屬性

屬性含義類型例
res.status響應狀態碼Integer200
res.headers響應頭Object{a: ['b'], c: ['d', 'e']}
res.body響應內容String'awa'
res.version響應版本String'HTTP/1.1'
res.reason錯誤原因String'OK'

這些屬性可以修改且應當被修改,但只有在回調函數中修改才有效

獲取指定響應頭的值

res.getHeader(name)

  • 參數:
  • name : String
    響應頭名稱
  • 返回值:響應頭的值數組(如果沒有該響應頭,則返回[]空數組)
  • 返回值類型:Array<String>

設置指定響應頭的值

res.setHeader(name, value)

  • 參數:
  • name : String
    響應頭名稱
  • value : 任意类型
    響應頭值
  • 返回值:處理完畢的響應對象
  • 返回值類型:HttpResponse

寫入響應內容

res.write(content1, content2, ...)

  • 參數:
  • content : 任意类型
    響應內容
  • 返回值:處理完畢的響應對象
  • 返回值類型:HttpResponse
  • 注:本函數在目前相當於res.body += content1 + content2 + ...

Http API 樣例

JavaScript
let server = new HttpServer();
server.onGet("/hello(.+)", (req, resp) => {
    logger.info("http_server_test: run: onGet: Received a request from ", req.remoteAddr, 
                ':', req.remotePort, " for ", req.path);
    resp.write("<html><body>")
        .write("<h1>It works!</h1>")
        .write("<br/>")
        .write("<p>Request Headers: ", JSON.stringify(req.headers, null, 4), "</p>")
        .write("<p>Request Body: ", req.body, "</p>")
        .write("<p>Your Address: ", req.remoteAddr, ':', req.remotePort, "</p>")
        .write("<p>HTTP Version: ", req.version, "</p>")
        .write("<p>Method: ", req.method, "</p>")
        .write("<p>Path: ", req.path, "</p>")
        .write("<p>Parsed Query: ", JSON.stringify(req.query, null, 4), "</p>")
        .write("<p>Path Regex Matches: ", JSON.stringify(req.matches), "</p>")
        .write("</body></html>")
    resp.status = 200;
    resp.reason = "OK";
    resp.setHeader("Content-Type", "text/html");
}).onGet("/404", (req, resp) => {
    resp.status = 404;
    resp.reason = "Not Found";
    resp.write("Not Found");
}).onGet("/test-redirect", (req, resp) => {
    // https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections
    resp.status = 301;
    resp.reason = "Moved Permanently";
    resp.setHeader("Location", "https://github.com");
}).onGet("/(.+)", (req, resp) => {
    resp.write("Hello World! ", req.matches);
}).onPreRouting((req, resp) => {
    logger.info("http_server_test: run: onPreRouting: resp.body.length: ", resp.body.length);
    if (req.path == "/test-prerouting") {
        resp.body = "Hello World!";
        resp.status = 200;
        resp.reason = "OK";
        return false;
    }
}).onPostRouting((req, resp) => {
    logger.info("http_server_test: run: onPostRouting: resp.body.length: ", resp.body.length);
}).onError((req, resp) => {
    resp.write("\nonError called");
}).listen(this.listen_address, this.listen_port);
logger.info("http_server_test: run: Server listening on " + this.listen_address + ":" + this.listen_port);