Dial
用于原始的Socket访问,支持tcp、tls(也可写作ssl)协议,以及WebSocket的ws、wss协议。支持连接数据库,支持的数据库有:sqlite3、mysql、postgres、clickhouse。
Dial(address)
Dial(address, timeout)
Dial(address, options)示例
-
Dial函数调用例子。
javascriptfunction 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() } }pythondef 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()rustfn 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行情接口。
javascriptfunction 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() }pythonimport 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()rustfn 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)。javascriptvar 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() }pythonclient = 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()rustfn 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 | 连接对象,有 |
参数
| 名称 | 类型 | 必填 | 描述 |
address | string | 是 | 请求地址。 |
timeout | number | 否 | 建立连接的超时时间。 |
options | object | 否 | 配置选项,例如 |
参考
备注
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) |
|---|---|
| sqlite3 | sqlite3://test1.db |
| mysql | mysql://username:yourpassword@tcp(localhost:3306)/yourdatabase?charset=utf8mb4&parseTime=true |
| postgres | postgres://user=username password=yourpassword host=localhost port=5432 dbname=yourdatabase sslmode=disable |
| clickhouse | clickhouse://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()发送订阅消息。