通过向导创建一个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. 字符串转化为int数组

    String a = "1,2,3,4,5,6" String str[] = a.split(","); int array[] = new int[str. ...

  2. linux网卡eth1如何修改为eth0

    ifconfig看到的ip不是我想要的ip,而且显示的第一块网卡也是eth1 ,这明显是有问题的, vim /etc/sysconfig/network-script/ifcfg-eth0 看到的ip ...

  3. db2修改表结构,增加列,删除列等

    增加一列:ALTER TABLE tbname ADD COLUMN columnName datatype; 增加多列:ALTER TABLE tbname ADD COLUMN columnNam ...

  4. vm虚拟机出现Disk启动失败

    https://jingyan.baidu.com/article/a501d80c0e45b8ec630f5ed6.html

  5. 本地文件直接访问html,document.cookie总是显示空字符串

    当file:///E:/browser.html访问时,我们设置document.cookie,读取时一直会显示空字符串! 而开一下Apache时:localhost/browser.html或者12 ...

  6. python 类似java的三目运算符

    python中没有其他语言中的三元表达式,不过有类似的实现方法 其他语言中,例如java的三元表达式是这样 int a = 1; String b = ""; b = a > ...

  7. C语言学习感受

    C语言,是我学习的第一种计算机语言,是他作为我编写程序的开始,在学习的时候,先学习了最基础的知识,在语言的理论学习语法上,我逐渐的了解了C语言并且对他有了基础的认识与理解,随着学习内容的不断深入,我逐 ...

  8. C# CheckBox与RadioButton

    通常RadioBox称为单选按钮,CheckBox称为多选按钮,这两个控件都是从ButtonBase类中派生,可以将其视为按钮. 多个checkBox之间的选择是互相独立的,互补影响.多个RadioB ...

  9. canvas绘图,html5 k线图,股票行情图

    canvas绘图,html5 k线图,股票行情图 canvas跟其他标签一样,也可以通过css来定义样式.但这里需要注意的是:canvas的默认宽高为300px * 150px,在css中为canva ...

  10. springboot maven项目,为什么build成功,build path也没错误,project-->clean 也没用,项目上面还是有个红x呢?

    springboot maven项目,为什么build成功,build path也没错误,project-->clean 也没用,项目上面还是有个红x呢? 看错误信息有提示:  Descript ...