通过向导创建一个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. jQuery绑定事件方法及区别(bind,click,on,live,one)

    第一种方式: ? 1 2 3 4 5 $(document).ready(function(){  $("#clickme").click(function(){  alert(& ...

  2. java中JDBC连接Oracle数据库

    package com.xxxx.lunwen.test;import java.sql.*;public class DBUtil { static { try { // 加载Oracle驱动程序 ...

  3. ABC3

    Sql Server http://www.cnblogs.com/sunxi/p/4600152.html http://blog.csdn.net/dmz1981/article/details/ ...

  4. [3]传奇3服务器源码分析一 DBServer

    留存 服务端下载地址: 点击这里

  5. c++引用和指针的彻底理解

     ★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名.  ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指 ...

  6. Java多线程-----线程安全及解决机制

    1.什么是线程安全问题? 从某个线程开始访问到访问结束的整个过程,如果有一个访问对象被其他线程修改,那么对于当前线程而言就发生了线程安全问题: 如果在整个访问过程中,无一对象被其他线程修改,就是线程安 ...

  7. Eureka (数学组合 + 斜率)

    由于斜率的储存精度不够,所以使用最简分数表示记录. 合并同一个位置上的点,然后统计个数,利用公式先求出至少包含2个点的数量. 然后再是求某位之上的点与某一斜率的个数,那就是每边至少一个点的个数相乘. ...

  8. uva 11354 Bond

    题意: 邦德在逃命!他在一个有N个城市,由M条边连接的道路网中.一条路的危险度被定义为这条路上危险度最大的边的危险度. 现在给出若干个询问,s,t,问从s到t的最小的危险度是多少. 思路: 首先可以证 ...

  9. Hive常用语句

    文章目录 1 显示分区 2 添加分区 3 删除分区 4 修改分区 5 添加列 6 修改列 7 修改表属性 8 表的重命名 显示分区 show partitions iteblog; 添加分区 ALTE ...

  10. Linux基础命令---IP路由操作

    ip ip指令可以显示或操作路由.网路设备,设置路由策略和通道. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora.   1.语法     ...