Thursday, 18 December 2008

Trabajando con XML-RPC en Delphi


Para trabajar con esta librería hecha por UserLand Software, y podéis encontrar la especificación de la librería en esta web: www.xmlrpc.com
  • Que és XML-RPC?
Tal como se define en la Wikipedia, el XML-RPC, es un protocolo de llamada a procedimiento remoto que usa XML para codificar los datos y HTTP como protocolo de transmisión de mensajes. En la web de UserLand, podemos encontrar el protocolo escrito en diferentes lenguajes. El proyecto para delphi, lo podemos encontrar en SourceForge : delphixml-rpc.

  • Se utiliza el XML-RPC?
Aquí os dejo un claro ejemplo de su utilización en Second Life. Donde Utilizan un Servidor XML-RPC, para enviar los datos de la Web en PHP y mediante el servidor RPC al Second Life.









  • Implementación en Delphi.
Su implementación es bastante sencilla. Una vez nos hemos descargado los ficheros del proyecto, los añadimos a nuestro proyecto:

Dentro de la misma carpeta, nos vienen pequeños ejemplos de como hacer las llamadas y como responder a estas. Un ejemplo básico enviando un pequeño string, es el siguiente:

  • Desde el lado del Cliente:
uses XmlRpcTypes, XmlRpcClient; //uses necesarios

procedure TForm1.FormCreate(Sender: TObject);
begin
  FRpcFunction := TRpcFunction.Create;
  FRpcCaller := TRpcCaller.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FRpcCaller.Free;
  FRpcFunction := nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  RpcResult: IRpcResult;
begin
  FRpcCaller.HostName := Host; //Ip del Servidor RPC (XXX.XXX.XXX.XXX) o la local (localhost)
  FRpcCaller.HostPort := Port; //Puerto 8080
  FRpcCaller.EndPoint := '/RPC2'; //Punto final del XML

  FRpcFunction.Clear;
  FRpcFunction.ObjectMethod := 'ObtenerLLamada';
  FRpcFunction.AddItem(ebMessage.Text);
  Log('Iniciando Llamada');

  try
    RpcResult := FRpcCaller.Execute(FRpcFunction);
    if RpcResult.IsError then
      Log(Format('Error: (%d) %s', [RpcResult.ErrorCode, RpcResult.ErrorMsg]))
    else
      AddMessage(RpcResult.AsString);
  except
    on E: Exception do
      Log(StringReplace(E.Message, #13#10, ': ', [rfReplaceAll]));
  end;
end;
  • Desde el lado del Servidor:
uses SyncObjs, XmlRpcServer, XmlRpcTypes; //Uses necesarios

procedure TForm1.FormCreate(Sender: TObject);
begin
  FCriticalSection := TCriticalSection.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FCriticalSection.Free;
  FRpcServer.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if not Assigned(FRpcServer) then
    FRpcServer := TRpcServer.Create;
  if not FRpcServer.Active then
  begin
    FRpcServer.ListenPort := Port; //Puerto donde escuchar 8080
    if not Assigned(FRpcMethodHandler) then
    begin
      FRpcMethodHandler := TRpcMethodHandler.Create;
      try
        FRpcMethodHandler.Name := 'ObtenerLLamada';
        FRpcMethodHandler.Method := CallMethod;
        FRpcServer.RegisterMethodHandler(FRpcMethodHandler);
        FRpcMethodHandler := nil;
      finally
        FRpcMethodHandler.Free;
      end;
    end;
    FRpcServer.Active := True;
    Button1.Caption := 'Stop Server';
    FMessage := 'xml-rpc server has been started';
    AddLog;
  end
  else
  begin
    FRpcServer.Active := False;
    Button1.Caption := 'Start Server';
    FMessage := 'xml-rpc server has been stopped';
    AddLog;
  end;
end;

procedure TForm1.CallMethod(Thread: TRpcThread; const MethodName: string;
    List: TList; Return: TRpcReturn);
var
  Msg: string;
begin
  Msg := TRpcParameter(List[0]).AsString; //Mensaje obtenido
  Return.AddItem('Has enviado ' + Msg); //Devolvemos el mensaje
  FCriticalSection.Enter; //Sincronizamos los logs
  try
    FMessage := IntToStr(GetCurrentThreadId) + ' ' + Msg;
    Thread.Synchronize(AddLog);
  finally
    FCriticalSection.Leave;
  end;
end;


El ejemplo lo podemos ver aquí:



También os podeis descargar los ejemplos compilados aquí.

0 comments:

Post a Comment