HP-Socket is a high performance network framework.
aardio is an extremely easy-to-use dynamic language, but it is also a hybrid language that allows for rare and very convenient manipulation of static types, so it can directly call API interface functions of static languages such as C, C++, etc.
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=466;bottom=144)
winform.add(
btnBaidu={cls="button";text="访问 baidu (chunk 传输)";left=11;top=14;right=201;bottom=45;z=1};
btnCnbeta={cls="button";text="访问 cnbeta ";left=263;top=16;right=441;bottom=44;z=2};
static={cls="static";text="网页源码保存在同目录的";left=274;top=110;right=427;bottom=130;transparent=1;z=3}
)
/*}}*/
io.open()
// 1. 导入 ssl http 相关库用于访问 https 网址
// 1.1 导入 ssl http client 监听器
import aaz.libhpsocket.ssl.listener.httpClient;
// 1.2 导入 ssl http client 组件
import aaz.libhpsocket.ssl.component.httpClient;
// 2. 创建监听器
var listener = aaz.libhpsocket.ssl.listener.httpClient();
// 3. 定义事件函数 注:事件函数为线程函数,请按多线程函数规则使用
// 3.1 在工作线程里面导入一些辅助函数。因为 HP-Socket 的唯一职责就是接收和发送字节流,不参与应用程序的协议解析等工作,所以这些工作要自己做
listener.onThreadCreated = function(){
import aaz.libhpsocket.helper.client;
}
// 3.2 准备连接事件
listener.onPrepareConnect = function(component, connId, soListen){
io.print("[onPrepareConnect]", connId, soListen);
}
// 3.3 完成连接事件
listener.onConnect = function(component, connId){
io.print("[onConnect]", connId);
}
// 3.4 握手完成事件
listener.onHandShake = function(component, connId){
io.print("[onHandShake]", connId);
}
// 3.5 开始解析事件
listener.onMessageBegin = function(component, connId){
io.print("[onMessageBegin]", component, connId);
// 使用辅助函数来保存得到的网址内容, 初始化动态指针
aaz.libhpsocket.helper.client.reallocString(component, 1);
}
// 3.6 状态行解析完成 (仅用于 HTTP 客户端)
listener.onStatusLine = function(component, connId, usStatusCode, lpszDesc){
io.print("[onStatusLine]", component, connId, usStatusCode, lpszDesc);
}
// 3.7 请求头事件
listener.onHeader = function(component, connId, pszName, lpszValue){
io.print("[onHeader]", component, connId, pszName, lpszValue);
}
// 3.8 请求头完成事件
listener.onHeadersComplete = function(component, connId){
io.print("[onHeadersComplete]", component, connId);
if(component.getHeader("Transfer-Encoding") == "chunked"){
io.print("分块传输");
}
else {
io.print("一次性传输->content-length", component.contentLength);
}
io.print("------获取全部 header-----------");
var headers = component.getAllHeaders();
for(i=1;#headers;1){
io.print(headers[i].name, headers[i].value);
}
io.print("------获取指定 header (Set-Cookie)-----------");
var headers = component.getHeaders("Set-Cookie");
for(i=1;#headers;1){
io.print(headers[i]);
}
io.print("------获取全部 cookie-----------");
var cookies = component.getAllCookies();
for(i=1;#cookies;1){
io.print(cookies[i].name, cookies[i].value);
}
}
// 3.9 Chunked 报文头事件
listener.onChunkHeader = function(component, connId, iLength){
io.print("[onChunkHeader]", component, connId, iLength);
}
// 3.10 Chunked 报文结束事件
listener.onChunkComplete = function(component, connId){
io.print("[onChunkComplete]", component, connId);
}
// 3.11 BODY 报文事件
listener.onBody = function(component, connId, pData, len){
io.print("[onBody]", component, connId, pData, len);
// 动态指针追加数据
aaz.libhpsocket.helper.client.appendString(component, pData, len);
}
// 3.12 完成解析事件
listener.onMessageComplete = function(component, connId){
io.print("[onMessageComplete]", component, connId);
var html = aaz.libhpsocket.helper.client.getString(component);
string.save("\test.html", html);
}
// 3.13 升级协议
listener.onUpgrade = function(component, connId, enUpgradeType){
io.print("[onUpgrade]", component, connId, enUpgradeType);
}
// 3.14 解析错误
listener.onParseError = function(component, connId, iErrorCode, lpszErrorDesc){
io.print("[onParseError]", component, connId, iErrorCode, lpszErrorDesc);
}
// 3.15 Web Socket 数据包头
listener.onWsMessageHeader = function(component, connId, bFinal, iReserved, iOperationCode, lpszMask, ullBodyLen){
io.print("[onWsMessageHeader]", component, connId, bFinal, iReserved, iOperationCode, lpszMask, ullBodyLen);
}
// 3.14 Web Socket 数据包体
listener.onWsMessageBody = function(component, connId, pData, iLength){
io.print("[onWsMessageBody]", component, connId, pData, iLength);
}
// 3.16 Web Socket 数据包体
listener.onWsMessageComplete = function(component, connId){
io.print("[onWsMessageComplete]", component, connId);
}
// 3.17 连接关闭事件
listener.onClose = function(component, connId){
io.print("[onClose]", component, connId);
// 释放动态指针
aaz.libhpsocket.helper.client.reallocString(component, 0);
}
// 4. 创建组件并绑定监听器,第一个参数是监听器对象
var componentBaidu = aaz.libhpsocket.ssl.component.httpClient(listener);
var componentCnbeta = aaz.libhpsocket.ssl.component.httpClient(listener);
io.print( componentBaidu.workerThreadCount )
// 4.1 初始化 ssl 环境,并设置验证模式,默认不验证,即第一个参数为0
componentBaidu.setupSSLContext(0);
// 4.2 向服务端应用程序发起连接请求,如果连接成功则返回 true 并且会先后接收到 onPrepareConnect、onConnect 和 onHandshake事件
componentBaidu.start("www.baidu.com",443);
componentCnbeta.setupSSLContext(0)
componentCnbeta.start("www.cnbeta.com",443);
// 4.3 向服务器发送数据
winform.btnBaidu.oncommand = function(id,event){
// 自己想办法在触发 onHandShake 事件后才运行
componentBaidu.sendGet(
"/",
{
["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9";
["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36";
["accept-language"] = "zh-CN,zh;q=0.9,ja;q=0.8,zh-TW;q=0.7";
}
)
}
winform.btnCnbeta.oncommand = function(id,event){
// 自己想办法在触发 onHandShake 事件后才运行
componentCnbeta.sendGet(
"/",
{
["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36";
["accept-language"] = "zh-CN,zh;q=0.9,ja;q=0.8,zh-TW;q=0.7";
}
)
}
// 4.4 客户端推出前调用 stop() 方法让组件停止通信,如果调用成功则返回 true 并收到 onClose 事件
winform.onClose = function(hwnd,message,wParam,lParam){
componentBaidu.stop();
componentCnbeta.stop();
}
winform.show();
win.loopMessage();