uniGUI试用笔记(一)
通过向导创建一个uniGUI应用服务器,工程中有三个文件:
TUniServerModule = class(TUniGUIServerModule) TUniMainModule = class(TUniGUIMainModule) TMainForm = class(TUniForm)
(1)采用了单例模式,所有客户端共用一个TUniServerModule实例对象,从下面代码可以看出:
function UniServerModule: TUniServerModule;
implementation
{$R *.dfm}
uses
UniGUIVars;
function UniServerModule: TUniServerModule;
begin
Result:=TUniServerModule(UniGUIServerInstance);
end;
initialization
RegisterServerModuleClass(TUniServerModule);
用全局变量UniGUIServerInstance实现了唯一化的TUniServerModule实例对象,可以视同为全局控制对象,将一些需要唯一化的对象构建在TUniGUIServerModule类中,比如可以考虑构建数据库连接池,如果有必要也可以构建对象池。
(2)每个客户端连接后,系统创建了一个TUniMainModule对象,用于支撑和管理每个客户端连接,实现机理由于没有源码还暂时看不出,其实例的获取代码如下:
function UniMainModule: TUniMainModule;
implementation
{$R *.dfm}
uses
UniGUIVars, ServerModule, uniGUIApplication;
function UniMainModule: TUniMainModule;
begin
Result := TUniMainModule(UniApplication.UniMainModule)
end;
通过全局变量UniApplication的属性UniMainModule实现对TUniMainModule实例对象的调用,如何区分不同客户端连接的还不清楚。类的注册代码如下:
initialization
RegisterMainModuleClass(TUniMainModule);
TUniGUIMainModule实例视同每个连接的控制对象,可以将数据库连接和数据集放在该类中,如果数据集非常多,也可以考虑动态创建多个TDataModule,并由TUniGUIMainModule实例进行管理和维护。如果是三层结构,则TSQLConnection也应放在这个Module中。
(3)主窗体是一个TUniForm类,且是一个Application构建的窗体,通过注册实现,如下:
function MainForm: TMainForm;
implementation
{$R *.dfm}
uses
uniGUIVars, MainModule, uniGUIApplication;
function MainForm: TMainForm;
begin
Result := TMainForm(UniMainModule.GetFormInstance(TMainForm));
end;
通过以下代码进行注册
initialization
RegisterAppFormClass(TMainForm);
所有Application构建窗体都是通过上述方式实现,由Application控制其生命周期。也可以自定义Free窗体,自己控制窗体的创建和释放。
总之,可以将TUniServerModule实例对象视作全局控制对象,TUniMainModule对象视作每个连接控制对象,第一个注册的TUniForm类Application窗体为主窗体。
(4)对每个连接线程的访问可以通过UniServerModule.SessionManager.Sessions获取并作进一步处理,如下:
procedure TUniMainModule.UniGUIMainModuleCreate(Sender: TObject);
var
I : Integer;
ASessionList: TList;
ASession : TUniGUISession;
begin
{ 锁定列表 }
ASessionList := UniServerModule.SessionManager.Sessions.SessionList.LockList; try
{ 访问每个线程 }
for I := to ASessionList.Count- do
begin
ASession := TUniGUISession(ASessionList[I]);
if not ASession.IsTerminated then
{ 进行处理,如客户端地址 ASession.UniApplication.RemoteAddress }
end;
finally
{ 释放列表 }
UniServerModule.SessionManager.Sessions.SessionList.UnlockList;
end;
end;
也可以在TUniMainModule实例或TUniForm实例中直接访问当前线程对象,如:
procedure TUniMainModule.UniGUIMainModuleDestroy(Sender: TObject);
var
strClientIP : String;
begin
strClientIP := UniSession.UniApplication.RemoteAddress;
{ 进一步处理 }
end;
uniGUI试用笔记(一)的更多相关文章
- uniGUI试用笔记(十三)调用WebService
今天尝试用uniGUI做Web服务器,调用应用服务器的WebService,遇到些问题记录下来备忘. 1.对WebService的调用同一般App程序,只是注意如果WebService的执行时间较长, ...
- uniGUI试用笔记(十一)
最近研究了一下UniGUI的TuniDBGrid,记录一下免得忘记了. TuniDBGrid的重要属性包括: 1.列—TUniDBGridColumns和TUniDBGridColumn 每个列对象( ...
- uniGUI试用笔记(十)
今天用LoadRunner对uniGUI的Standalone模式的程序进行了一次压力测试,程序采用三层模式,将应用服务器与Web服务器分离,由于条件限制,数据库.应用服务和Web服务都部署在同一条云 ...
- uniGUI试用笔记(九)
uniGUI执行程序部署有3种形式 1.ISAPI模式 部署在IIS或Apache,程序编译为Dll形式,没有试,准备后续专门测试一下. 2.标准执行文件模式 将软件编译成一个独立的Exe文件,包括了 ...
- uniGUI试用笔记(八)
在业务系统中常常使用回车键(Enter)替代Tab键完成焦点跳转,在uniGUI下,可以不用代码,直接使用TUniForm的NavigateKeys进行设置: 其中Next和Prior决定了焦点向下一 ...
- uniGUI试用笔记(七)
uniGUI的文件下载由于TUniSession的存在而变得非常简单,最典型的一个例子就是将列表中的所有数据导出到Excel中.服务器上采用TMS FlexCel控件,先将数据集中的记录导入到Exce ...
- uniGUI试用笔记(六)
uniGUI提供了一个文件上传控件TUniFileUpload,进行数据的导入就变得比较容易.首先将TUniFileUpload控件放置在窗体上,按下导入按钮后,执行TUniFileUpload的文件 ...
- uniGUI试用笔记(五)
uniGUI的主窗体可以采用多页面方式进行管理,参考网上的资料,都是用TUniFrame + TUniPageControl 来实现,尝试了一下,效果还不错,如下图: 用TUniFrame 能够使用继 ...
- uniGUI试用笔记(四)
uniGUI下有专用的登录窗体类:TUniLoginForm,该类属于AppForm,构建代码为: function frmWebLogin: TfrmWebLogin; begin Result : ...
- uniGUI试用笔记(三)
uniGUI下的MessageDlg使用发生了变化,最大的特点是: 1.成为了uniGUIForm的成员函数: 2.变成过程(procedure)了,也就是没有返回值了,使得程序不再具有线程阻塞性. ...
随机推荐
- LA 3890 Most Distant Point from the Sea(半平面交)
Most Distant Point from the Sea [题目链接]Most Distant Point from the Sea [题目类型]半平面交 &题解: 蓝书279 二分答案 ...
- Beta阶段冲刺2.0
1. 提供当天站立式会议照片一张 2. 每个人的工作 (有work item 的ID) 成员 昨天已完成的工作 今天计划完成的工作 工作中遇到的困难 具体贡献 郑晓丽 "我的活动详情&quo ...
- 手动创建mfc工程(留存方便复制)
案例一. #include <afxwin.h> class CMyWnd : public CWnd { //DECLARE_DYNCREATE(CMyWnd) public: CMyW ...
- 4.GDscript(2)关键字,运算符,字面量
(来源godot官方文档) 关键词 下面是该语言支持的关键字列表.由于关键字是保留字(令牌),它们不能用作标识符.操作符(如 in , not , and 或 or )以及下面列出的内置类型的名称也是 ...
- MyEclipse 黑色主题 jsp 页面 js背景色修改
Windows-->Preferences-->Myeclipse-->Files and Editors-->JavaScript-->Editor-->Synt ...
- Spark学习之路 (六)Spark Transformation和Action
Transformation算子 基本的初始化 java static SparkConf conf = null; static JavaSparkContext sc = null; static ...
- .py文件 改成默认用idle打开
A.右键.py文件,edit with idle ==================================B.如果没有这个选项: 选择打开方式,进入python安装路径,选择 Python ...
- Locust 设置响应断言
转:http://www.testclass.net/locust/assert/ 性能测试也需要设置断言么? 某些情况下是需要,比如你在请求一个页面时,就可以通过状态来判断返回的 HTTP 状态码是 ...
- Runtime单例模式类 -- 控制电脑关机
package demo1; import java.io.IOException; public class RunTimeDemo { public static void main(String ...
- docker rmi 导致后面的命令不执行问题 Dockerfile设置时区问题
docker rmi 导致后面的命令不执行问题 把ca=`docker rmi sendemail-service` echo $ca改成docker rmi sendemail-service -f ...