7 июня 2012 г.

Подключение к серверу приложений. Параметры подключения

В каких случаях нам понадобится самостоятельно подключаться к серверу приложений?

Во-первых, если вы пишете свое приложение для работы с Лоцман.

Во-вторых, если вы пишете плагин и необходимо работать с WorkFlow из клиентов версии меньше 11, или когда необходимо выполнить какие-либо действия от имени пользователя, отличного от того, который запустил клиент.

Для подключения к серверу приложений необходимы следующие данные:
  1. Тип соединения: DCOM, сокет-соединение или веб-соединение. Работа с сервером приложений будет осуществляться с помощью классов TDCOMConnection, TSocketConnetion или TWebConnection соответственно.
  2. Имя сервера, порт для сокет-соединения, имя, пароль пользователя и имя прокси-сервера для веб-соединения.
  3. Имя базы данных.
  4. Способ аутентификации в базе данных: аутентификация средствами Windows или аутентификация средствами SQL-сервера.
  5. Имя и пароль пользователя для аутентификации средствами SQL-сервера.
В данной статье мы рассмотрим, где и как хранит параметры подключения клиентский модуль Лоцман. В представленной реализации подключения к серверу приложений будут использоваться те же самые параметры подключения.


Параметры подключения к серверу приложений хранятся в реестре, ими можно достаточно просто управлять администраторам предприятия, например, с помощью групповых политик.

Сервер приложений



Список серверов приложений хранится в реестре, в ветке HKCU\Software\ASCON\Loodsman, в одном из значений: SP, ClientSP или WorkFlowSP. Если установлена галочке «Использовать общий список серверов», то в значении с именем SP. Если галочка не установлена, то в значении ClientSP для выбранного «Клиент» в списке «Приложение», или в значении WorkFlowSP для выбранного «WorkFlow».
Параметры подключения к разным серверам хранятся в виде строки с разделителем ; (точка с запятой).


В строке подключения к серверу может находиться либо просто имя сервера (при этом тип соединения будет DCOM), либо набор имя=значение, разделенный символом |. Имена значений следующие:

Имя параметраОписание
DisplayNameНазвание подключения
ConnectionTypeТип соединения:
0 — DCOM
1 — сокет-соединения
2 — веб-соединение
HostIP-адрес для сокет-соединения, URL для веб-соединения
PortПорт сокет-сервера, по умолчанию 4804
ProxyПрокси-сервер для веб-соединения
UserИмя пользователя для веб-соединения
PasswordПароль для веб-соединения

Например, строка подключения к сокет-серверу выглядит примерно так:
DisplayName=192.168.0.1:4801|ConnectionType=1|Host=192.168.0.1|Port=4801

При установке соединения необходимо подключаться к серверам из списка по-порядку до тех пор, пока не удастся установить соединение.

Чтение списка серверов приложений в виде кода:

procedure GetAppServerList(const AWorkflow: Boolean;
    const AList: TStrings);
var
    R: TRegistry;
begin
    AList.Clear();
    AList.LineBreak := ';';
    R := TRegistry.Create();
    try
        if R.OpenKeyReadOnly('Software\ASCON\Loodsman') then
        begin
            if AWorkflow and R.ValueExists('WorkFlowSP') then
                AList.Text := R.ReadString('WorkFlowSP')
            else if (not AWorkflow)
                and R.ValueExists('ClientSP') then
                AList.Text := R.ReadString('ClientSP')
            else
                AList.Text := R.ReadString('SP');
        end;
    finally
        R.Free();
    end;
end;

Разбор строки с параметрами подключения:

procedure GetAppServerParams(const AConnectionString: String;
    var AConnection: TAppServerConnection;
    var AHost: String; var APort: Integer;
    var AProxy, AUserName, APassword: String);
var
    LParams: TStringList;
    i: Integer;
    LName: String;
    LValue: String;
begin
    AConnection := TAppServerConnection.DCOM;
    AHost := AConnectionString;
    APort := 4804;
    if Pos('|', AConnectionString) > 0 then
    begin
        LParams := TStringList.Create();
        try
            LParams.LineBreak := '|';
            LParams.NameValueSeparator := '=';
            LParams.Text := AConnectionString;
            for i := 0 to LParams.Count - 1 do
            begin
                LName := LParams.Names[i];
                LValue := LParams.ValueFromIndex[i];
                if LName = 'ConnectionType' then
                    AConnection := TAppServerConnection(
                        StrToIntDef(LValue, 0))
                else if LName = 'Host' then
                    AHost := LValue
                else if LName = 'Port' then
                    APort := StrToIntDef(LValue, 4804)
                else if LName = 'Proxy' then
                    AProxy := LValue
                else if LName = 'User' then
                    AUserName := LValue
                else if LName = 'Password' then
                    APassword := DeCrypt(LValue);
            end;
        finally
            LParams.Free();
        end;
    end;
end;

База данных



Информация о параметрах подключения к базам данных хранится в реестре в ветке HKCU\Software\ASCON\Loodsman в значении DBList. Значение имеет тип REG_BINARY и в нем хранится набор данных TClientDataSet.


Набор данных содержит следующие поля:

Имя поляТипОписание
_DataBaseVARCHAR(255)Имя базы данных
_UserNameVARCHAR(255)Имя пользователя (только для аутентификации средствами SQL-сервера)
_AccessMethodINTEGERСпособ аутентификации:
0 — средствами Windows
1 — средствами SQL-сервера
2 — средствами SQL-сервера, пароль сохранен
3 — недоступная база данных
_PasswordVARCHAR(255)Пароль пользователя (только для аутентификации средствами SQL-сервера)
_ConnectedINTEGERНазначение поля точно не известно и в представленном коде не используется

Для подключения к базе данных необходимо найти в наборе данных параметры подключения, если необходим пароль и он не сохранен, то спросить пароль у пользователя. Затем вызвать метод сервера приложений ConnectToDBEx и передать ему полученные параметры.

Код получения набора данных с параметрами подключения:

function GetDBAuthListData: OleVariant;
var
    R: TRegistry;
    LSize: Integer;
    P: Pointer;
begin
    R := TRegistry.Create();
    try
        if R.OpenKeyReadOnly('Software\ASCON\Loodsman') then
        begin
            LSize := R.GetDataSize('DBList');
            if LSize > 0 then
            begin
                Result := VarArrayCreate([0, LSize - 1],
                    varByte);
                P := VarArrayLock(Result);
                R.ReadBinaryData('DBList', P^, LSize);
                VarArrayUnLock(Result);
            end;
        end;
    finally
        R.Free();
    end;
end;
procedure ConnectTo(const ABase: String);
var
    LDatabaseAuth: Integer;
    LDBListData: OleVariant;
    LDataSet: TClientDataSet;
    LUserName: String;
    LPassword: String;
begin
    LDatabaseAuth := 0;
    LDBListData := GetDBAuthListData();
    if not VarIsEmpty(LDBListData) then
    begin
        LDataSet := TClientDataSet.Create(nil);
        try
            LDataSet.Data := LDBListData;
            if LDataSet.Locate('_DataBase', ABase, []) then
            begin
                LDatabaseAuth := 
                    LDataSet.FieldValue['_AccessMethod'];
                LUserName := LDataSet.FieldValue['_UserName'];
                LPassword := LDataSet.FieldValue['_Password'];
                if LPassword <> '' then
                    LPassword := DeCrypt(LPassword);
                if (LDatabaseAuth in [1, 2]) 
                    and (LPassword = '') then
                begin
                    // Запрос имени пользователя и пароли,
                    // если они не сохранены
                    ShowLoodsmanLoginDialog(ABase,
                        LUserName, LPassword);
                end;
            end;
        finally
            LDataSet.Free();
        end;
    end;
    if LDatabaseAuth in [1, 2] then
        DCOMConnection.ConnectToDBEx(ABase,
            LUserName, LPassword)
    else
        DCOMConnection.ConnectToDB(ABase);
end;

Краткий пересказ статьи я писал на форуме Аскона, в теме Как в плагине Лоцмана определить имя сервера, к которому подключен клиент?

В следующей статье мы рассмотрим подключение к серверу и вызов методов сервера приложений.

Комментариев нет:

Отправить комментарий