sas 发表于 2022-7-1 22:48

[aardio] hp socket 网络库 extra 的构造方法

本帖最后由 sas 于 2022-7-2 22:25 编辑

hp socket 是国内出名的高性能网络库。
用户数据和网络连接是通过 extra 来绑定的


那么在 aardio 里面怎么构造 extra 呢 ?

最基本的操作包括: 释放指针, 把指针写入结构体, 把结构体写入指针等

import util.metaProperty;
namespace aaz.libhpsocket.app;
class extra{
    ctor(){
      this@ = _metaProperty;
      // 子类的free方法会自动加入此列表
      this.freeList = {};
    };
    free = function(){
      this.data.value = null;
    };
    // 存放原始的传输数据
    struct data = ..aaz.libhpsocket.app.extra.data();
}
namespace extra{
    _metaProperty = ..util.metaProperty(
      _topointer = function(){
            return owner.pointer;
      };
      update = function(){
            if(!owner.pointer){
                error("未绑定指针 ",2)
            }
            // 把结构体的数据写入指针
            ..raw.convert(owner, owner.pointer);
      };
      free = {
            _set = function(v){
                ..table.push(owner.freeList, v)
            }
      }
      value = {
            _get = function(){
                if(!owner.pointer){
                  // 创建动态指针存放结构体
                  owner.pointer = ..raw.realloc(..raw.sizeof(owner), null, owner);
                  // 新建原始的通讯数据
                  owner.data.new()
                  // 写入指针
                  owner.update()
                }
                return owner.pointer;
            }
            _set = function(v){
                if(v === null){
                  if(!owner.pointer){
                        error("请先设置 pointer 再赋值为 null",2)   
                  }
                  // 释放各子类的数据
                  for(i=1;#owner.freeList;1){
                        owner.freeList[ i ]();
                  }
                  // 释放本身的指针
                  owner.pointer = ..raw.realloc(0, owner.pointer);
                  return ;   
                }
                // 把外部指针的数据写入结构体
                ..raw.convert(v, owner);
                owner.pointer = v;
            }
      }
    )   
}

import aaz.libhpsocket.app.extra.data;
二,基础数据的构造: 用来存储 tcphttp websocket 等二进制数据, 支持清空,新建,连接,抽出等操作import util.metaProperty;

namespace aaz.libhpsocket.app.extra;
class data{
    ctor(){
      this@ = _metaProperty;
    };
    pointer pValue;
}
namespace data{
    _metaProperty = ..util.metaProperty(
      value = {
            _get = function(){
                return owner.pValue;
            }
            _set = function(v){
                if(v===null){
                  if(owner.pValue){
                        owner.pValue = ..raw.realloc(0, owner.pValue)
                  }
                  return ;
                }
            }   
      };
      convert = function(struct, offset){
            return ..raw.convert(owner.pValue, struct, offset);
      };
      pointer = {
            _get = function(){
                return owner.pValue;
            }
      };
      length = {
            _get = function(){
                return ..raw.sizeof(owner.pValue);
            }   
      };
      getString = function(){
            if(!owner.pValue){
                error("未绑定指针 ",2)
            }
            return ..raw.tostring(owner.pValue, 1, ..raw.sizeof(owner.pValue))
      };
      toUnread = function(offset, unreadLen){
            if(!owner.pValue){
                error("未绑定指针 ",2)
            }
            
            // 构建剩余的未读取的数据的动态指针
            var unread = ..raw.realloc(unreadLen);
            unread = ..raw.concat(unread, topointer(owner.pValue, offset), unreadLen);
            
            // 释放原来的数据
            owner.value = null;
            
            // 更新未读取数据的指针
            owner.pValue = unread;
      };
      new = function(){
            owner.pValue = ..raw.realloc(1, owner.pValue, "");
      };
      concat = function(pData, len){
            if(!owner.pValue){
                error("未绑定指针 ",2)
            }
            owner.pValue = ..raw.concat(owner.pValue, pData, len);
      };
    )   
}
三,不定长字符串的构造

import util.metaProperty;

namespace aaz.libhpsocket.app.extra;
class str{
    ctor(s){
      this@ = _metaProperty;
      if(s){
            if(type(s) != type.string){
                error("参数@1必须是字符串",2)
            }
            this.value = s;
      }
    }
    pointer pValue;
}
namespace str{
    _metaProperty = ..util.metaProperty(
      value = {
            _get = function(){
                if(owner.pValue){
                  return ..raw.str(owner.pValue);
                }
            }
            
            _set = function(v){
                if(v===null){
                  if(owner.pValue){
                        owner.pValue = ..raw.realloc(0, owner.pValue)
                  }
                  return ;
                }
                owner.pValue = ..raw.realloc(#v, owner.pValue, v);
            }   
      };
    )   
}
四,websocket 客户端的构造: 包含 path 路径, origin 头,认证 key ,还有传输的数据


import aaz.libhpsocket.app.extra;
import aaz.libhpsocket.app.extra.str;

namespace aaz.libhpsocket.app.websocket.client;
class extra{
    ctor(wsPath, wsOrigin){
      this = ..aaz.libhpsocket.app.extra();
    }
    free = function(){
      this.wsKey.value = null;
      this.wsPath.value = null;
      this.wsOrigin.value = null;
    }
    struct wsKey = ..aaz.libhpsocket.app.extra.str();
    struct wsPath = ..aaz.libhpsocket.app.extra.str(wsPath);
    struct wsOrigin = ..aaz.libhpsocket.app.extra.str(wsOrigin);
}
五,bilibili B站直播弹幕客户端的构造:在 websocket client 的基础上增加了 roomId 直播间号, token


import aaz.libhpsocket.app.websocket.client.extra;

namespace aaz.bilibili;
class extra{
    ctor(roomId, token, wsPath, wsOrigin){
      this = ..aaz.libhpsocket.app.websocket.client.extra(wsPath, wsOrigin);
    };
    free = function(){
      this.roomId.value = null;
      this.token.value = null;
    };
    struct roomId = ..aaz.libhpsocket.app.extra.str(roomId);
    struct token = ..aaz.libhpsocket.app.extra.str(token);
}



更具体的应用请看 https://www.52pojie.cn/thread-1656586-1-1.html

sas 发表于 2022-7-2 12:18

本帖最后由 sas 于 2022-7-2 22:30 编辑

占个楼,后续更新使用
页: [1]
查看完整版本: [aardio] hp socket 网络库 extra 的构造方法