输入/搜索内容
内置函数
Global
Log
Market
Trade
Account
Futures
Exchange
IO
Network
HttpQuery
HttpQuery_Go
Dial
Mail
Mail_Go
Storage
Threads
TA
Talib
OS
结构体
内置变量与常量
通用约定
交易所

用于原始的Socket访问,支持tcp、tls(也可写作ssl)协议,以及WebSocket的ws、wss协议。支持连接数据库,支持的数据库有:sqlite3、mysql、postgres、clickhouse。

Dial(address)
Dial(address, timeout)
Dial(address, options)

示例

  • Dial函数调用例子。

    javascript
    function main(){ // Dial支持tcp://、tls://协议以及ws://、wss://协议,tcp://、tls://可加一个参数指定超时的秒数 var client = Dial("tls://www.baidu.com:443") if (client) { // write可再跟一个数字参数指定超时,write返回成功发送的字节数 client.write("GET / HTTP/1.1\nConnection: Closed\n\n") while (true) { // read可再跟一个数字参数指定超时,单位:毫秒。返回null指出错或者超时或者socket已经关闭 var buf = client.read() if (!buf) { break } Log(buf) } client.close() } }
    python
    def main(): client = Dial("tls://www.baidu.com:443") if client: client.write("GET / HTTP/1.1\nConnection: Closed\n\n") while True: buf = client.read() if not buf: break Log(buf) client.close()
    rust
    fn main() { // Dial支持tcp://、tls://协议以及ws://、wss://协议,tcp://、tls://可使用Dial::new(addr, timeout)指定超时的秒数 let mut client = Dial("tls://www.baidu.com:443"); if client.Valid() { // write的第二个数字参数指定超时,write返回成功发送的字节数 client.write("GET / HTTP/1.1\nConnection: Closed\n\n", 0); loop { // read的数字参数指定超时,单位:毫秒。返回空字符串指出错或者超时或者socket已经关闭 let buf = client.read(0); if buf == "" { break; } Log!(buf); } client.close(); } }
  • 访问币安(binance)的WebSocket行情接口。

    javascript
    function main() { LogStatus("Connecting...") // 访问币安的WebSocket接口 var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr") if (!client) { Log("Connection failed, exiting") return } while (true) { // read只返回调用read之后获取的数据 var buf = client.read() if (!buf) { break } var table = { type: 'table', title: '行情图表', cols: ['币种', '最高', '最低', '买一', '卖一', '最后成交价', '成交量', '更新时间'], rows: [] } var obj = JSON.parse(buf) Object.values(obj).forEach(function(ticker) { table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)]) }) LogStatus('`' + JSON.stringify(table) + '`') } client.close() }
    python
    import json def main(): LogStatus("Connecting...") client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr") if not client: Log("Connection failed, exiting") return while True: buf = client.read() if not buf: break table = { "type" : "table", "title" : "行情图表", "cols" : ["币种", "最高", "最低", "买一", "卖一", "最后成交价", "成交量", "更新时间"], "rows" : [] } obj = json.loads(buf) for i in range(len(obj)): table["rows"].append([obj[i]["s"], obj[i]["h"], obj[i]["l"], obj[i]["b"], obj[i]["a"], obj[i]["c"], obj[i]["q"], _D(int(obj[i]["E"]) / 1000)]) LogStatus('`' + json.dumps(table) + '`') client.close()
    rust
    fn main() { LogStatus!("Connecting..."); // 访问币安的WebSocket接口 let mut client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr"); if !client.Valid() { Log!("Connection failed, exiting"); return; } loop { // read只返回调用read之后获取的数据 let buf = client.read(0); if buf == "" { break; } let obj = JSONParse(&buf).unwrap(); // Rust SDK 没有 JSON 序列化功能,使用字符串拼接构造状态栏表格的 JSON 文本 let mut rows = String::new(); if let Some(arr) = obj.as_array() { for ticker in arr { if !rows.is_empty() { rows += ","; } rows += &format!(r#"["{}","{}","{}","{}","{}","{}","{}","{}"]"#, ticker["s"].as_str().unwrap_or(""), ticker["h"].as_str().unwrap_or(""), ticker["l"].as_str().unwrap_or(""), ticker["b"].as_str().unwrap_or(""), ticker["a"].as_str().unwrap_or(""), ticker["c"].as_str().unwrap_or(""), ticker["q"].as_str().unwrap_or(""), _D(ticker["E"].as_i64().unwrap_or(0))); } } let table = format!(r#"{{"type":"table","title":"行情图表","cols":["币种","最高","最低","买一","卖一","最后成交价","成交量","更新时间"],"rows":[{}]}}"#, rows); LogStatus!(format!("`{}`", table)); } client.close(); }
  • 连接sqlite3数据库,用连接对象的exec()方法执行SQL语句(见Dial-return)。

    javascript
    var client = null function main() { // client = Dial("sqlite3://:memory:") // 使用内存数据库 client = Dial("sqlite3://test1.db") // 打开/连接实盘目录下的数据库文件 // 查询数据库中的表 var ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'") Log(ret) } function onexit() { Log("Executing client.close()") client.close() }
    python
    client = None def main(): global client # client = Dial("sqlite3://:memory:") # 使用内存数据库 client = Dial("sqlite3://test1.db") # 打开/连接实盘目录下的数据库文件 # 查询数据库中的表 ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'") Log(ret) def onexit(): Log("Executing client.close()") client.close()
    rust
    fn main() { // let mut client = Dial("sqlite3://:memory:"); // 使用内存数据库 let mut client = Dial("sqlite3://test1.db"); // 打开/连接实盘目录下的数据库文件 // Rust 的连接对象不支持 fd() 方法 // 查询数据库中的表 let ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'"); Log!(format!("{:?}", ret)); Log!("Executing client.close()"); client.close(); }

返回值

类型描述

object

连接对象,有read()、write()、close()等方法(数据库连接另有exec()),见Dial-return。连接失败(例如超时)时返回空值并记录错误(Rust返回Valid()为false的连接对象)。

参数

名称类型必填描述

address

string

是

请求地址。

timeout

number

否

建立连接的超时时间。ws、wss协议单位为毫秒(小于100时按秒计算),tcp、tls协议单位为秒;设置为0时使用默认超时。JavaScript、Python中不传该参数时为30,即30秒。Rust中Dial(address)使用默认超时,指定超时使用Dial::new(address, timeout),timeout的单位与上述相同。

options

object

否

配置选项,例如headers(WebSocket请求头)、timeout(单位与timeout参数相同,未设置时使用默认超时)。

参考

备注

address参数的详细说明,在正常的地址:wss://ws.okx.com:8443/ws/v5/public后,以|符号分隔。如果参数字符串中有|字符,则以||作为分隔符号。之后的部分是一些功能参数设置,各个参数之间用&字符连接。

例如ss5代理和压缩参数一起设置时可以写作:
Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")

Dial函数的address参数支持的功能参数说明
WebSocket协议数据压缩相关的参数:compress=参数值compress为压缩方式,可选gzip、gzip_raw(也可写作flate)、zlib(也可写作deflate)。gzip_raw为不带gzip头的原始deflate数据,接收的数据不是标准gzip格式时可以使用。设置不支持的值会报错。
WebSocket协议数据压缩相关的参数:mode=参数值mode为压缩模式,只支持recv(接收压缩数据,本地解压缩),不设置时默认为recv。设置了compress时,mode设置为send或dual会报错。
WebSocket协议启用compression设置:enableCompression=true该参数可以设置但不生效,不进行WebSocket的permessage-deflate压缩协商。
WebSocket协议设置底层自动重连相关的参数:reconnect=参数值reconnect为是否设置重连,reconnect=true为启用重连。不设置该参数时默认不重连。
WebSocket协议设置底层自动重连相关的参数:interval=参数值interval为重试时间间隔,单位毫秒,interval=10000为重试间隔10秒,不设置默认1秒,即interval=1000。
WebSocket协议设置底层自动重连相关的参数:payload=参数值payload为WebSocket重连时需要发送的订阅消息,例如:payload=okok。
socks5代理的相关参数:proxy=参数值proxy为ss5代理设置,参数值格式:socks5://name:[email protected]:1080,name为ss5服务端用户名,pwd为ss5服务端登录密码,1080为ss5服务的端口。
WebSocket接收缓冲区上限:qsize=参数值qsize为接收缓冲区最多保存的消息条数,不设置时默认4096。
WebSocket接收缓冲区上限:qbytes=参数值qbytes为接收缓冲区最多保存的字节数,不设置时默认16777216(16MB)。

Dial()函数仅支持实盘。

使用Dial函数连接数据库时,连接字符串的写法如下:

支持的数据库连接字符串(Connection String)
sqlite3sqlite3://test1.db
mysqlmysql://username:yourpassword@tcp(localhost:3306)/yourdatabase?charset=utf8mb4&parseTime=true
postgrespostgres://user=username password=yourpassword host=localhost port=5432 dbname=yourdatabase sslmode=disable
clickhouseclickhouse://tcp://localhost:9000?username=username&password=yourpassword&database=yourdatabase

各数据库连接字符串的说明:

  • sqlite3:sqlite3://前缀表示使用的是sqlite3数据库。相对路径的数据库文件位于实盘目录(logs/storage/<实盘ID>/)下;sqlite3://:memory:为内存数据库,不创建文件,连接关闭后数据即丢弃;也支持sqlite3://file:test.db?cache=shared&mode=memory这样的URI写法。
  • mysql:mysql://之后的写法与Go语言MySQL驱动(go-sql-driver/mysql)的DSN相同。charset、collation、timeout、readTimeout、writeTimeout、tls(true、false、skip-verify、preferred)等参数生效,也可以用ssl-mode设置TLS;parseTime、loc只校验取值,不生效;不支持自定义TLS配置名;其它无法识别的参数作为会话变量,连接后执行SET 参数名 = 参数值。也可写作URL形式:mysql://username:yourpassword@localhost:3306/yourdatabase。
  • postgres:libpq键值对写法,各项以空格分隔。sslmode按libpq的语义:disable不使用TLS,require等使用TLS但不校验证书,只有verify-ca、verify-full校验证书;不支持sslrootcert、sslcert、sslkey、passfile、service等需要读取文件的参数;其它无法识别的参数作为运行时参数设置。也可写作URL形式:postgres://username:yourpassword@localhost:5432/yourdatabase?sslmode=disable。
  • clickhouse:clickhouse://之后的写法与Go语言ClickHouse驱动(clickhouse-go)的DSN相同:tcp://使用原生TCP协议(端口9000;端口9440或者参数secure=true时使用TLS,skip_verify=true时不校验证书),也可写作http://、https://使用HTTP接口;其它无法识别的参数作为ClickHouse设置(settings)。也可写作URL形式:clickhouse://username:yourpassword@localhost:9000/yourdatabase,默认使用原生TCP协议,使用clickhouse+http://、clickhouse+https://前缀或者端口8123、8443时使用HTTP接口。

address中|之后的参数以&连接、以=赋值,所以payload的内容含有=、&等字符(例如base64编码的签名、JSON)时会干扰解析。这种情况不要写进payload,而是连接成功后用write()发送订阅消息。