Распределенные вычисления и технологии Inprise

Создание серверной части (Delphi)


В результате использования утилиты rpcmake.exe с парамерами, соответствующими выбору Delphi в качестве языка для сервера, получим следующие файлы: a1_c.pas (stub-код, который можно встраивать в клиентское приложение), a1_s.dpr (исходный текст консольного приложения для сервера функциональности), a1.pas - файл-заготовка, используемая при создании сервера, в который разработчику следует добавить код реализации функций (примерно так, как пишутся обработчики событий), a1.inc - код, содержащий объявления функций без их реализации (секция интерфейса).

Код для сервера a1_s.dpr, сгенерированный этой утилитой, выглядит следующим образом:

{$APPTYPE CONSOLE} program a1_s;

uses SysUtils, ODET3020, a1; procedure rpc_sin1(dce_table: PTable; socket: Integer); var rv : Integer; x : Double; begin x := dce_pop_double(dce_table,'x'); dce_push_double(socket,'dce_result',sin1(x)); end; procedure rpc_handle(func: PChar; table: PTable; socket: Integer); begin if (StrComp(func,'sin1')=0) then rpc_sin1(table,socket) else dce_unknown_func(func, table, socket); end;

{Constants and global variables follow} const VARLEN = 100; var ode_file : PChar; ode_server : PChar; dce_func : PChar; argarr : array[0..5] of array[0..VARLEN] of Char; argptrs : array[0..5] of PChar; argv : PChar; argc : Integer; dce_table : PTable; called_init_func : Integer; socket, rsocket, i, rv : Integer; msgstr : String; begin {main} GetMem(ode_file,VARLEN); GetMem(ode_server,VARLEN); GetMem(dce_func,VARLEN); called_init_func := 0;

FillChar(argarr,SizeOf(argarr),#0); FillChar(argv,SizeOf(argv),#0);

for i := 0 to ParamCount + 1 do begin StrCopy(argarr[i],PChar(ParamStr(i))); argptrs[i] := @argarr[i]; end; {for}

argc := ParamCount + 1; argv := @argptrs;

rv := parse_args(argc, argv, ode_file);

if (rv=0) then begin Writeln('Env flag (-e) not set'); if ParamCount > 1 then StrCopy(ode_file,PChar(ParamStr(ParamCount))); end;

if (dce_setenv(ode_file,NIL,NIL) = 0) then begin msgstr := 'Set env '+ode_file^+' failed'; WriteLn(msgstr); msgstr := 'Reason: '+dce_errstr; Writeln(msgstr); Halt(1); end;


ode_server := dce_servername('a1'); dce_checkver(2, 0); socket := dce_init_server(ode_file,ode_server); if (socket <= 0) then begin Writeln('setup server failed'); Writeln('Reason: '+dce_errstr); dce_set_exit; end;



while(True=True) do begin dce_table := dce_waitfor_call(socket,dce_func); if (Boolean(dce_should_exit) or Boolean(dce_err_is_fatal)) then Exit else begin if (Boolean(dce_server_is_ded)) then begin dce_spawn(socket,argc,argv,ode_file,ode_server); socket := dce_retsocket; (* save for future *) end; rsocket := dce_retsocket(); (* (old socket closed) *) rpc_handle(dce_func,dce_table,rsocket); dce_send(rsocket,dce_func); dce_recv_conf(rsocket); dce_release; dce_table_destroy(dce_table); if (dce_server_is_ded=0) then dce_close_socket(rsocket); end; {else} end; {while}

FreeMem(ode_file,VARLEN); FreeMem(ode_server,VARLEN); FreeMem(dce_func,VARLEN);

dce_close_socket(rsocket); dce_table_destroy(dce_table); end.

Секция интерфейса a1.inc выглядит следующим образом:

function sin1(x: Double): Double;

Код реализации функций a1.pas имеет следующий вид (жирным шрифтом выделены строки, которые следует добавить разработчику):

unit a1; interface uses SysUtils, ODET3020; {$include a1.inc}

implementation

function sin1(x: Double): Double;

VAR I:INTEGER; R:DOUBLE;SL:DOUBLE;XX:DOUBLE; CONST DELTA=0.0001 ;

begin SL:=X; I:=1; R:=0; XX:=X*X; WHILE (ABS(SL)>DELTA) DO BEGIN R:=R+SL; SL:=-(SL*XX/(2*I))/(2*I+1); inc(i); END; result:=R;

end; {sin1} end. {unit}

Cервер можно скомпилировать из среды разработки или из командной строки, вызвав компилятор Pascal:

Dcc32 -b a1_s.dpr

Перед компиляцией проекта файл ODET3020.pas (интерфейс к ODET3020.DLL - библиотеке, содержащей Entera API) следует поместить в тот же каталог, что и компилируемый проект. Исполняемый файл также требует наличия этой библиотеки в каком-либо доступном каталоге.

Полученный сервер функциональности, как обычно, представляет собой консольное приложение.


Содержание раздела