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 := 0 to ASessionList.Count-1 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;
时间: 2024-10-10 17:23:00

uniGUI试用笔记(一)的相关文章

uniGUI试用笔记(三)

uniGUI下的MessageDlg使用发生了变化,最大的特点是: 1.成为了uniGUIForm的成员函数: 2.变成过程(procedure)了,也就是没有返回值了,使得程序不再具有线程阻塞性. 3.增加了一个传入回调函数的参数:callBack : TuniDialogCallbackAnonProc,该类型定义在uniGUIDialogs单元中: TuniDialogCallbackAnonProc = procedure (Sender : TComponent; Res : Inte

uniGUI试用笔记(四)

uniGUI下有专用的登录窗体类:TUniLoginForm,该类属于AppForm,构建代码为: function frmWebLogin: TfrmWebLogin; begin Result := TfrmWebLogin(dmWebMain.GetFormInstance(TfrmWebLogin)); end; 系统中如果存在登录窗体,则首先显示该窗体,当登录窗体返回不同ModuleResult值时,代表不同含义: ModalResult := mrOk; //表示登录成功,显示主窗体

uniGUI试用笔记(五)

uniGUI的主窗体可以采用多页面方式进行管理,参考网上的资料,都是用TUniFrame + TUniPageControl 来实现,尝试了一下,效果还不错,如下图: 用TUniFrame 能够使用继承模式,我采用了以下的类关系: TfmeWebEmbedBase : 所有嵌入Frame的基类,实现了与主窗体的交互和控制,包括窗体的关闭等 TfmeWebDBListBase:   与数据集列表操作相关的基类,实现了数据集的开启.数据导出与打印等 TfmeWebDBListEditBase:与数据

uniGUI试用笔记(七)

uniGUI的文件下载由于TUniSession的存在而变得非常简单,最典型的一个例子就是将列表中的所有数据导出到Excel中.服务器上采用TMS FlexCel控件,先将数据集中的记录导入到Excel文件中,然后再将Excel文件内容输出到内存流中,最后通过TUniSession发送到客户端.代码如下: procedure TfmeWebDBListBase.ExportData; var i, rowindex, colindex: Integer; ms : TMemoryStream;

uniGUI试用笔记(六)

uniGUI提供了一个文件上传控件TUniFileUpload,进行数据的导入就变得比较容易.首先将TUniFileUpload控件放置在窗体上,按下导入按钮后,执行TUniFileUpload的文件上传功能: procedure TfmeWebDBListEditBase.btnImportClick(Sender: TObject); begin inherited; { 执行文件上传 } fuMain.Execute; { 启动Mask,显示文件上传过程 } fuMain.ScreenMa

uniGUI试用笔记(十)

今天用LoadRunner对uniGUI的Standalone模式的程序进行了一次压力测试,程序采用三层模式,将应用服务器与Web服务器分离,由于条件限制,数据库.应用服务和Web服务都部署在同一条云服务器上,客户端使用IE浏览器,如下图: , 云服务器配置:CPU 4核 内存8G 硬盘500G 带宽10Mbps 客户端为笔记本电脑,i7 8核,内存16G,硬盘1T,客户端带宽20Mbps 先用LoadRunner纪录一组操作,包括操作员登录.打开结算单列表,大约900条纪录分页显示,点击第一条

uniGUI试用笔记(二)

前几天做的demo今天启动后,浏览器打开页面后死活不显示窗体,找了半天原因才发现是360浏览器启动了兼容模式,改成极速模式后就正常了.有点晕.... 今天简单测试了TUniGUIServerModule的几个属性 Title   应用程序名称,显示在页面标签上的 LoadingMessage  载入ExtJS库时显示的信息 UnavailableErrMsg   服务器不可用时显示的信息 MainFormDisplayMode  主窗体的显示模式,可选项包括: mfWindow 窗体模式,有窗体

uniGUI试用笔记(九)uniGUI执行程序部署有3种形式

uniGUI执行程序部署有3种形式 1.ISAPI模式 部署在IIS或Apache,程序编译为Dll形式,没有试,准备后续专门测试一下. 2.标准执行文件模式 将软件编译成一个独立的Exe文件,包括了WEB服务和业务内容,是uniGUI部署方式中最简单的一种.该方式最大特点是可以进行代码跟踪,同一般exe程序调试一样,在Debug模式下程序调试非常方便.运行exe后就可以直接打开页面进行测试,通过任务栏上的图标可以打开服务监控页面,监控服务程序的运行情况,如下图: 3.Windows服务模式 将

uniGUI试用笔记(十一)

最近研究了一下UniGUI的TuniDBGrid,记录一下免得忘记了. TuniDBGrid的重要属性包括: 1.列—TUniDBGridColumns和TUniDBGridColumn 每个列对象(TUniDBGridColumn)的重要属性包括: CheckBoxField : TUniCheckBoxField 列作为CheckBox操作的相关属性 属性 类型 说明 AutoPost Boolean 当用户点选CheckBox后,改变前端显示并根据该属性决定: True—立即自动提交到数据