通过向导创建一个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试用笔记(一)的更多相关文章

  1. uniGUI试用笔记(十三)调用WebService

    今天尝试用uniGUI做Web服务器,调用应用服务器的WebService,遇到些问题记录下来备忘. 1.对WebService的调用同一般App程序,只是注意如果WebService的执行时间较长, ...

  2. uniGUI试用笔记(十一)

    最近研究了一下UniGUI的TuniDBGrid,记录一下免得忘记了. TuniDBGrid的重要属性包括: 1.列—TUniDBGridColumns和TUniDBGridColumn 每个列对象( ...

  3. uniGUI试用笔记(十)

    今天用LoadRunner对uniGUI的Standalone模式的程序进行了一次压力测试,程序采用三层模式,将应用服务器与Web服务器分离,由于条件限制,数据库.应用服务和Web服务都部署在同一条云 ...

  4. uniGUI试用笔记(九)

    uniGUI执行程序部署有3种形式 1.ISAPI模式 部署在IIS或Apache,程序编译为Dll形式,没有试,准备后续专门测试一下. 2.标准执行文件模式 将软件编译成一个独立的Exe文件,包括了 ...

  5. uniGUI试用笔记(八)

    在业务系统中常常使用回车键(Enter)替代Tab键完成焦点跳转,在uniGUI下,可以不用代码,直接使用TUniForm的NavigateKeys进行设置: 其中Next和Prior决定了焦点向下一 ...

  6. uniGUI试用笔记(七)

    uniGUI的文件下载由于TUniSession的存在而变得非常简单,最典型的一个例子就是将列表中的所有数据导出到Excel中.服务器上采用TMS FlexCel控件,先将数据集中的记录导入到Exce ...

  7. uniGUI试用笔记(六)

    uniGUI提供了一个文件上传控件TUniFileUpload,进行数据的导入就变得比较容易.首先将TUniFileUpload控件放置在窗体上,按下导入按钮后,执行TUniFileUpload的文件 ...

  8. uniGUI试用笔记(五)

    uniGUI的主窗体可以采用多页面方式进行管理,参考网上的资料,都是用TUniFrame + TUniPageControl 来实现,尝试了一下,效果还不错,如下图: 用TUniFrame 能够使用继 ...

  9. uniGUI试用笔记(四)

    uniGUI下有专用的登录窗体类:TUniLoginForm,该类属于AppForm,构建代码为: function frmWebLogin: TfrmWebLogin; begin Result : ...

  10. uniGUI试用笔记(三)

    uniGUI下的MessageDlg使用发生了变化,最大的特点是: 1.成为了uniGUIForm的成员函数: 2.变成过程(procedure)了,也就是没有返回值了,使得程序不再具有线程阻塞性. ...

随机推荐

  1. LA 3890 Most Distant Point from the Sea(半平面交)

    Most Distant Point from the Sea [题目链接]Most Distant Point from the Sea [题目类型]半平面交 &题解: 蓝书279 二分答案 ...

  2. Beta阶段冲刺2.0

    1. 提供当天站立式会议照片一张 2. 每个人的工作 (有work item 的ID) 成员 昨天已完成的工作 今天计划完成的工作 工作中遇到的困难 具体贡献 郑晓丽 "我的活动详情&quo ...

  3. 手动创建mfc工程(留存方便复制)

    案例一. #include <afxwin.h> class CMyWnd : public CWnd { //DECLARE_DYNCREATE(CMyWnd) public: CMyW ...

  4. 4.GDscript(2)关键字,运算符,字面量

    (来源godot官方文档) 关键词 下面是该语言支持的关键字列表.由于关键字是保留字(令牌),它们不能用作标识符.操作符(如 in , not , and 或 or )以及下面列出的内置类型的名称也是 ...

  5. MyEclipse 黑色主题 jsp 页面 js背景色修改

    Windows-->Preferences-->Myeclipse-->Files and Editors-->JavaScript-->Editor-->Synt ...

  6. Spark学习之路 (六)Spark Transformation和Action

    Transformation算子 基本的初始化 java static SparkConf conf = null; static JavaSparkContext sc = null; static ...

  7. .py文件 改成默认用idle打开

    A.右键.py文件,edit with idle ==================================B.如果没有这个选项: 选择打开方式,进入python安装路径,选择 Python ...

  8. Locust 设置响应断言

    转:http://www.testclass.net/locust/assert/ 性能测试也需要设置断言么? 某些情况下是需要,比如你在请求一个页面时,就可以通过状态来判断返回的 HTTP 状态码是 ...

  9. Runtime单例模式类 -- 控制电脑关机

    package demo1; import java.io.IOException; public class RunTimeDemo { public static void main(String ...

  10. docker rmi 导致后面的命令不执行问题 Dockerfile设置时区问题

    docker rmi 导致后面的命令不执行问题 把ca=`docker rmi sendemail-service` echo $ca改成docker rmi sendemail-service -f ...