Help: connecting to google map service using lNet lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Leledumbo · 2010-12-17 10:15 I'm trying to connect to a google map service, but the app hangs in infinite loop. GoogleMapConnector.Connecting is never set to false despite of the TimeOut property I set in the constructor. Code: [Select]unit wmmain; {$mode objfpc}{$H+} interface uses   Classes, SysUtils, FileUtil, HTTPDefs, websession, fpHTTP,   fpWeb, lHTTP; type   { TMainWebModule }   TMainWebModule = class(TFPWebModule)     procedure TFPWebActions0Request(Sender: TObject; ARequest: TRequest;       AResponse: TResponse; var Handled: Boolean);     procedure TFPWebActions1Request(Sender: TObject; ARequest: TRequest;       AResponse: TResponse; var Handled: Boolean);     procedure DataModuleCreate(Sender: TObject);     procedure DataModuleDestroy(Sender: TObject);     function GoogleMapConnectorOnInput(ASocket: TLHTTPClientSocket; ABuffer: pchar; ASize: integer): integer;     procedure GoogleMapConnectorOnDoneInput(ASocket: TLHTTPClientSocket);   private     { private declarations }     GoogleMapConnector: TLHTTPClient;     ResponseBuf: String;   public     { public declarations }   end; var   MainWebModule: TMainWebModule; implementation {$R *.lfm} const   QueryStr = 'restoran';   GoogleAPIKey = 'ABQIAAAAR16qAFe_aeUB7PXwb4ENZxRHYi30yMAYkyoiSwporea1 yo0xLRTg3lf_7VNbntYiWxJvDo5nIAW_SA'; { TMainWebModule } procedure TMainWebModule.TFPWebActions0Request(Sender: TObject;   ARequest: TRequest; AResponse: TResponse; var Handled: Boolean); begin   AResponse.Content := '

Hello, World 1!

';   Handled := true; end; procedure TMainWebModule.TFPWebActions1Request(Sender: TObject;   ARequest: TRequest; AResponse: TResponse; var Handled: Boolean); var   StatusStr: String; begin   ResponseBuf := '';   if GoogleMapConnector.Connect then begin     while GoogleMapConnector.Connecting do Sleep(100);     AResponse.Content := 'Respon:' +ResponseBuf;   end else begin     Str(GoogleMapConnector.Response.Status,StatusStr);     AResponse.Content := Format('HTTP %s: %s',       [StatusStr,GoogleMapConnector.Response.Reason]);   end;   Handled := true; end; procedure TMainWebModule.DataModuleCreate(Sender: TObject); begin   GoogleMapConnector := TLHTTPClient.Create(Self);   with GoogleMapConnector do begin     Timeout     := 10;     Host        := 'http://maps.google.com';     Port        := 80;     URI         := Format('maps/geo?q=%s&output=json&oe=utf8&sensor=false' +       '&key=%s',[QueryStr,GoogleAPIKey]);     OnInput     := @Self.GoogleMapConnectorOnInput;     OnDoneInput := @Self.GoogleMapConnectorOnDoneInput;   end; end; procedure TMainWebModule.DataModuleDestroy(Sender: TObject); begin   GoogleMapConnector.Free; end; function TMainWebModule.GoogleMapConnectorOnInput(ASocket: TLHTTPClientSocket;   ABuffer: pchar; ASize: integer): integer; var   TempBuf: String; begin   SetString(TempBuf,ABuffer,ASize);   ResponseBuf := ResponseBuf + TempBuf; end; procedure TMainWebModule.GoogleMapConnectorOnDoneInput(   ASocket: TLHTTPClientSocket); begin   GoogleMapConnector.Disconnect; end; initialization   RegisterHTTPModule('main', TMainWebModule); end. Btw, I'm behind a proxy. Do I need to set up anything? Platform: i386-win32 ---------------------------------------------------------------------- Leledumbo · 2010-12-17 12:59 Solved with Synapse ---------------------------------------------------------------------- JD · 2010-12-17 13:32 I'm glad to know that you got it to work. But I'm of the opinion that Lazarus/FreePascal could do with small sample applications in the following areas a) Web applications using modern API's - Google, Skype, Amazon, IMDB etc b) Multitier database applications on LANs, WANs or the Internet c) Graphics applications d) Applications interacting with Java, Android, .NET etc e) Applications showcasing Lazarus/FreePascal's reporting capabilities In my opinion, these are the things necessary to convince corporate decision makers that Lazarus/FreePascal is not a hobbyist' toy. To many of us are reinventing the wheel again & again because Lazarus/FreePascal does not have these "gotcha" sample apps. ---------------------------------------------------------------------- Dibo · 2010-12-17 13:33 1. lNET works on non-blocking mode. I'm not familiar in messages loop, but I think your loop block lNET callback message in Application main loop. Maybe Application.ProcessMessages solve this problem: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TMainWebModule.TFPWebActions1Request(Sender: TObject;  ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);var  StatusStr: String;begin  ResponseBuf := '';  if GoogleMapConnector.Connect then begin    while GoogleMapConnector.Connecting do     begin      Sleep(100);      Application.ProcessMessages;    end;    AResponse.Content := 'Respon:' +ResponseBuf;  end else begin    Str(GoogleMapConnector.Response.Status,StatusStr);    AResponse.Content := Format('HTTP %s: %s',      [StatusStr,GoogleMapConnector.Response.Reason]);  end;  Handled := true;end; But I'm not Application.ProcessMessages fan. If you want use non- blocking sockets, you should change your TFPWebModule mechanism logic to non-blocking too. For example - changing TFPWebActions1Request procedure to Event property and call this event in GoogleMapConnectorOnDoneInput 2. I don't know which version of lNET you are using, but Host property was very sensitive for link format (like slash on end of link). In demo, they using DecomposeURL function, which return Host without "http://" prefix (maybe this is your problem). But be careful with this function. I see you are using params in link. DecomposeURL cut this params. So I written own DecomposeURL which include params in link: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses URIParser; function TMyLHttpClient.MyDecomposeURL(const URL: string; out Host, URI,  Params: string; out Port: Word): Boolean;var  uri_rec: TURI;begin  Result := True;  uri_rec := ParseURI(URL, 'http', 80);  Host := uri_rec.Host;  URI := uri_rec.Path + uri_rec.Document;  Params := uri_rec.Params;  Port := uri_rec.Port;end; Edit: 3. Maybe problem is in response code status. LHTTPClient is fine, but to much "restricted". Each HTTP response code must be implemented in source of LHTTPClient (se lhttp unit and HTTPStatusCodes const). If google return uknown status, lHTTPClient hangs forever (OnDoneInput is never called, no errors etc.). In mantis bugtracker is my patch wich add some new codes, but not accepted yet. ---------------------------------------------------------------------- Leledumbo · 2010-12-18 15:58 QuoteGraphics applicationsThere are some in the application gallery (and many more out there) QuoteApplications interacting with Java, Android, .NET etcExcept for Java, the other has entry in the wiki. I've tried JNI.pas bindings, but it seems outdated and I can't make it to work with current Oracle JDK. QuoteApplications showcasing Lazarus/FreePascal's reporting capabilitiesI remember a MRP application in the gallery. QuotelNET works on non-blocking modeYeah, I know that because I previously used it to create a chat application with many connections involved and they run without waiting each other. QuoteBut I'm not Application.ProcessMessages fan. If you want use non- blocking sockets, you should change your TFPWebModule mechanism logic to non-blocking tooThat seems a little inconvenient QuoteI don't know which version of lNET you are using0.6.4 QuoteDecomposeURL cut this params. So I written own DecomposeURL which include params in linkI haven't tried to print each host, port and uri from DecomposeURL myself. But if it really cuts that, well... that's disappointing. QuoteMaybe problem is in response code status. LHTTPClient is fine, but to much "restricted". Each HTTP response code must be implemented in source of LHTTPClient (se lhttp unit and HTTPStatusCodes const). If google return uknown status, lHTTPClient hangs forever (OnDoneInput is never called, no errors etc.). In mantis bugtracker is my patch wich add some new codes, but not accepted yet.Actually, that's not it. My biggest problem is that I NEVER call SendRequest and in the waiting loop I NEVER call CallAction. After that, I believe it works. But since I have to pass through a proxy, it still fails. That's why I moved to Synapse. Plus, the code is much shorter now. A lesson learned: not every problem can be solved with component based approach easily.