Jump to content

chkaufmann

Members
  • Content Count

    167
  • Joined

  • Last visited

Posts posted by chkaufmann


  1. 17 hours ago, corneliusdavid said:

    The quickest and cheapest way was to add Thinfinity VirtualUI to the Delphi code and set up a server where the Delphi app could access the data locally and all users use the app through a web browser--with very minimal changes to the code (still Delph XE VCL!). It works great and everyone is happy.

    I looked at this some years ago. I liked the way the solved the problem to upload/download files in the browser client. This is a feature I need and I'm not sure, if it is solved in TSPlus.

     

    But the latest website and the difficulty to get price information makes me suspicious. Looks like the technical stuff is reduced to minimum and moved to background and you have to deal with sales people and high pricing.


  2. 9 hours ago, Olli73 said:

    I think tsplus webserver could do the job ...

    This looks interesting. How does it compare to "Thinfinity VirtualUI". I looked at this some years ago, but it was not 100% correct in HTML5 mode. Compared to that, the TSPlus Demo server with Excel looks perfect in Firefox. In addition, I think "Thinfinity VirtualUI" is driven by investors and not technical people anymore...


  3. We have a client / server application which we offer on an platform with RDP access (application only) for users. On the same server I run a REST API (https) with a mobile application accessing data in the same database.

     

    For one client it is not possible anymore to open an application over RDP. I need to find a solution using https only.

     

    The client application has too many features (including a map) to move to a browser platform easily. Even TMS Webcore is not a solution since we have too many customized controls. As far as I understand it is not possible to offer RDP access using a HTTPS connection or is it? Or are there any other options I have? I'm thinking about a n-tier solution where my client sends the requests to the API instead of the database. But maybe I missed an easier way to overcome the client restriction about not to use the RDP ports.

     

    Regards
    Christian


  4. Yes PostgreSQL is powerfull, so from that point of view, it looks heavy. But there is a Windows installer, quite simple. I think it may even configured for "silent install".

     

    Firebird comes in two version, one is with an embedded server. This you can install by just copying some files. And another advantage is, that you have single file databases. The only disadvantage is, that the database file have to be on a local drive with the embedded server.

    We used Firebird in many projects, however, when a database becomes bigger (several million records), it became a bit tricky with performance when you do many updates / deletes. That's when I started to use PostgreSQL which is more tolerant here. And PostgreSQL supports native JSON and Gis features.

     

    Christian


  5. I created the following helper method to normalize Unicode strings with different representations of ä, ö, ü:

    function TBSStringHelper.Length: Integer;
    begin
      Result := TBSStringHelperCaller.Length(Self);
    end;
    
    function TBSStringHelper.NormalizeNFC: String;
    var
      bufLen : Integer;
      buffer : PWideChar;
    begin
      Result := Self;
      bufLen := NormalizeString(NormalizationC, PWideChar(Self), Length, nil, 0);
      if bufLen > 0 then begin
        GetMem(buffer, bufLen);
        try
          bufLen := NormalizeString(NormalizationC, PWideChar(Self), Length, buffer, bufLen);
          if bufLen > 0 then begin
            Result := buffer;
            SetLength(Result, bufLen);
          end;
        finally
          FreeMem(buffer);
        end;
      end;
    end;

    But when I use this function many times, I get a memory corruption error and at some point an access violation. What is wrong here? I'm on Delphi 11, Update 1.

     

    Christian


  6. On 12/21/2024 at 6:39 PM, Remy Lebeau said:

    The TSearchRec::FindData field is the raw WIN32_FIND_DATA data that Find(First|Next)File() actually reported.

    But when I look in WinApi.Windows.pas, then FindFirstFile maps to external symbol FindFirstFile (and not FindFirstFileW) for a parameter TWIN32FindData. It has to be TWIN32FindDataW, then FindFirstFileW is used.

     

    I'm still on Delphi 11, Update 1. So maybe this changed with the latest version?

     

    Christian


  7. Since some years there is the unit IOUtils.pas. There are many duplicated functions:

     

    ExtractFileExt()   -   TPath.GetExtension()

    ExtractFileName() - TPath.GetFileName()

    FileAge()  - TFile.GetLastWriteTime()

     

    My code uses SysUtils.pas in most places, and I'm not sure if I should change this to use the functions from the new unit IOUtils.pas because the others will be deprecated at some point? And is there a comparisation table anywhere? It looks like not all functions work exactly the same way especially when it comes to throw exceptions.

     

    Christian


  8. 1 hour ago, Remy Lebeau said:

    And how are you doing that, when there is no OnCommandGet event fired for that connection? The only option would be to use the OnConnect event, in which case you could instead just assign a ReadTimeout to the connection and let TIdHTTPServer close the connection when no request arrives.

    You mean get that exception? Maybe it's only when run the code with break points in the debugger.

     

    Anyway, it works fine now and get the details for my monitor functionality.


  9. Thanks for the details.

     

    It seems, there are two connections when I send a GET request with postman. But in the first one I end method TIdIOHandler.RaiseConnClosedGracefully. When I test with the Chrome browser, there is only one context / connection.

     

    Christian


  10. I try to use my own subclass for TIdServerContext to monitor the requests to my server.

     

    Now I sent a simple GET request with Postman to my server and noticed, that two context objects were created, but the OnCommandGet event is only called once. What is the reason for that?

     

    Then I plan to iterate all current requests like this:

    tmpList := IdHTTPServer1.Contexts.LockList;
    for i := 0 to tmpList.Count -1 do begin
      tmp := TMyContext(tmpList[i]);
      // read some info from tmp
    end;
    IdHTTPServer1.Contexts.UnLockList;

    Can I be sure, that all items will be alive. Or is it possible, that one of the context items was freed before I could read info from it?

     

    Christian


  11. I have a question regarding memory usage for strings.

     

    When I load a big number of persons, there are many hundred with the same name. Is this handled automatically so that there will be only one copy of the string for a certain name or should I write my own code for this? Or does it depend how the strings are loaded and to what kind of variable these are assigned?

     

    I didn't find a good source to read about this topic. Any hints for that?

     

    Thanks

     

    Christian


  12. Just a question regarding Nexus Quality Suite: I looked at it some years ago and I noticed, if you have a big project, the performance for Line Timer / Method Timer was not very good when configuring which methods to trace and which not. Was there an improvement in this regard?

     

    And by the way: AQTime was a perfect profiler, I really miss it. Then it was aquired by SmartBear and since then it's terrible because the only improvement of the product they made was adding more and more annoying registration code.

     

    Christian


  13. Unfortunately Indy TIdFTP Client does not support SFTP. The discussions about this I found are already some years old. Is there a chance this will be added?

     

    And if not, what is a good alternative? I need something that can be fully integrated in my application so that it works for users who can just enter a servername, username and password.

     

    Christian


  14. 14 hours ago, Dalija Prasnikar said:

    There is not enough context around what you are trying to do, so it is hard to say what is the most appropriate solution. From how it looks now, I would say that what @David Heffernan proposed looks most suitable. You would have to create and remove items in the dictionary when thread is created and destroyed. 

    The TBSItemProvider objects are used by any thread. And what David writes will work. I was thinking of something like this as well. The question for me is, how to do the cleanup: Either I have to call a function at the end of each thread or is there a global place to do this?

     

    Christian


  15. This is my use case. 

      TBSItemProvider = class(TBSManagedInterface)
      strict private
        FNotificationCache  : Integer;                            
        FNotificationCaches : IBSList<TNotifyCacheItem>;          
      public 
        procedure DisableNotifications;
        procedure EnableNotifications;
       end;

    My application has 1-n objects of type TBSItemProvider. Basically this is used to handle the records of one database table.

     

    Normally the provider distributes messages/notifications after each insert/update/delete operation of one item.

     

    When a thread changes many items, I call DisableNotifications and in this case, notifications are cached in FNotificationCaches. So this is the reason these two private variables should be "per thread".

     

    Christian


  16. On 7/13/2023 at 6:29 PM, Anders Melander said:

    The parameters in the above are: -debug -v -pause -bind:$EXENAME $PATH($EXENAME)$NAMEONLY($EXENAME).map -include:0001

    Thanks for your instructions. I did like this, but when I call map2pdb I get a long list of errors. For example I get many lines like "Debug: Module has no source files: xxxxxxx" where xxxxxxx is the name of a unit, that is part of the project.

    Then the only thing I can start in VTune is "Hotspots". This runs fine and at the end I get a summary report. But this is not really helpfull since the "Top Hotspots" are Windows calls only.

    Using the Caller/Callee I can find my units, but when I open I don't see a lot: Percentage is there, CPU Time is zero most of the times and I don't see the number of calls.

     

    I used AQTime before, but support and I have no working version anymore. They had a call tree and a graphic where you could easily navigate down all routines.

     

    Maybe I just didn't find the correct view in VTune yet.

     

    My questions

    - Should I care about these errors when creating the pdb file? How to understand the error and how to solve it?

    - Where can I find a good tutorial for VTune in order to get the info I used before with AQTime?

     

    Thanks for any help

     

    Christian


  17. I'm using Superobjects to handle JSON data. Now I have to handle a result, where there are identifiers with dots:

     

    { "splash.annually": "normal" }

     

    This library cannot handle this data because it looks at "splash.annually" as path.

     

    Can somebody recommend me another library? What I like with Superobjects: It is fast and it offers reference counted object handling using interfaces.

     

    Regards
    Christian


  18. 47 minutes ago, Remy Lebeau said:

    Have you tried enabling the sslvrfPeer flag in the sslIO.SSLOptions.VerifyMode property?

    Yes. But I just set a break point in DoVerifyPeer without event assigned to OnVerifyPeer. Now I added an event and it works.

     

    What I don't understand, how I can verify that it is really the original certificate from my server.

     

    The Url is https://www.swimrankings.net/. The event is called two times. Both times AOk=False, once AError is 20, the second time it is 21.

     

    When I set AOk to true, the request works, if I do nothing in the event, the request doesn't work at all.

     

    With my limited knowledge about encryption I'm a bit lost here.

     

    Christian

     

×