静态链接 HevSCGIHandler

在原来 HevSCGIServer 的设计中 HevSCGIHandler 接口的实现的整合形式为共享库,HevSCGIServerLibrary 会读取 modules.conf 配置文件,解析出 Handlers 配置,应用于 TaskDispatcher 中。最近由于一个特殊的需求,HevSCGIServerLibrary 和 HevSCGIHandler 都需要静态链接到主程序中,这在原来的设计中上不支持的。

分析发现 HevSCGIHandler 要做的就是定义一个类,主要是要实现了 HevSCGIHandler 接口,模块还实现一个导出函数 hev_scgi_handler_module_get_handler_type 注册与导出 GType。模块被 Library 加载的过程就是通过查找模块的 hev_scgi_handler_module_get_handler_type 函数,调用并得到 GType,然后实例化进增加到 TaskDispatcher。

在此基础上需要对 Library 和 Handler 实现做一些简单的修改就可以支持静态链接 Handler 实现了,首先对于 Library 要做的就是在实例化之前调用 Handler 实现的注册方法向 GType system 注册 GType,然后 Library 根据 modules.conf 中的 TypeName 从 GType system 找到 GType 再进行实例化,最后加入 TaskDispatcher;而对于 Handler 实现来说,就是要简单修改 G_DEFINE_TYPE_DYNAMIC… 为 G_DEFINE_TYPE,在 Makefile 中通过开关宏分离 static 与 shared 的实现。

diff --git a/src/hev-scgi-server.c b/src/hev-scgi-server.c
index ab2d9bb..99f0a40 100644
--- a/src/hev-scgi-server.c
+++ b/src/hev-scgi-server.c
@@ -20,6 +20,9 @@
 #include "hev-scgi-handler-module.h"
 #include "hev-scgi-handler-default.h"
 
+#include <hev-scgi-handler-cgi.h>
+#include <hev-scgi-handler-filebox.h>
+
 enum
 {
        PROP_0,
@@ -148,7 +151,8 @@ static void hev_scgi_server_constructed(GObject * obj)
          g_critical("%s:%d[%s]", __FILE__, __LINE__, __FUNCTION__);
 
        /* Register static handler types at here*/
-
+       HEV_REGISTER_TYPE_SCGI_HANDLER_CGI();
+       HEV_REGISTER_TYPE_SCGI_HANDLER_FILEBOX();
 
        module_dir_path = hev_scgi_config_get_module_dir_path(
                                HEV_SCGI_CONFIG(priv->scgi_config));
# modules.conf
 
[Module0]
Alias=HevSCGIHandlerFilebox
Pattern=^/fb(.*)$
TypeName=HevSCGIHandlerFilebox
 
BaseURI=/fb/
CleanInterval=600
FilePoolPath=/tmp
FileMetaPath=/tmp
FileTempPath=/tmp
 
[Module1]
Alias=HevSCGIHandlerCGI
Pattern=^/cgi((/|\\?)(.*))?$
TypeName=HevSCGIHandlerCGI
 
CGIBinPath=/tmp/test.cgi
WorkDir=/tmp

最后,只要在主程序中将 library 与 handler 实现全部静态链接就可以了。

HevSocks5Service – 简单的 Socks5 服务

HevSocks5Service 是基于 GLib/GObject/GIO 的简单 Socks5 服务实现,参考 RFC1928。初步不支持任何认证且仅支持 CONNECT 命令,采用异步+多线程模式。

在 HevSocks5Service 的 Splice 实现中仍然没有直接使用 GIOStream 的 splice_async 方法,原因和之前在 HevTLSTunnel 中遇到的问题一样,GIO 库中 GTask 的线程池最大并发线程数被硬编码限制为了 10 个,从而使异步方法的并发数限制在一定的值以下。虽然不知道这样设计的目的何在,但这已经影响了对相关的异步方法的调用。

另外,通过对比使用 GIO 和直接使用系统原生 API,感觉基于 GObject 的实现对资源的使用相比较多,库的层层抽象及设计的不合理也使得实现不灵活,或也只能不按套路走。是不是我应该不要再过多的“依赖” GLib 及相关的库了?

Over!