🌏 網絡接口 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/plainapplication/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
監聽請求 - 說明
請注意,請求監聽是有優先級的。
如果有多個路徑同時滿足正則表達式,則選擇先定義的路徑。
例如:
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 | 請求源端口 | Integer | 11451 |
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 | 響應狀態碼 | Integer | 200 |
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 樣例
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);