Jump to content

Oliver Morsch

uniGUI Subscriber
  • Posts

    356
  • Joined

  • Last visited

  • Days Won

    18

Posts posted by Oliver Morsch

  1. Websocket on client side should be simple, using some javascript code you can find everywhere. Only modern browser is needed.

     

    For websocket on server side (with Delphi) you can find something here. -> 1st Option: make a separate Server for websocket -> 2nd Option: integrate it in uniGUI Server (I have no idea if this is possible!).

     

    So I have used "Long polling" to integrate in uniGUI. This was simple in newer uniGUI versions.

  2. Where is the problem making a file/folder dialog with uniGUI?

    - make a new uniform

    - You get the folders and files on server with FindFirst()/FindNext() or TDirectory.FindDirectories/TDirectory.FindFiles.

    - Put this result in a UniTree and UniListBox or UnistringGrid on the form (with some code for changing and select folder)

    - Open this form in "TMainForm.UniFileUpload1Completed" (with callback function)

     

    No javscript needed...

  3. Your code (from other post) cannot work in web.

     

    In web

    (1) the browser sends a request to the server

    (2) the server does some processing

    (3) and then the server sends the response back to the browser

    Everything you do in step 2, the browser receives after step 3

     

    But you can you do it with a "2nd communication channel" (Long poll), see here.

  4. "MessageScreen" - Blocking(!) Message- and InputDialogs and "Live" StatusMessages (with Abort option)

     

    No need for callbacks or extra threads or ...

     

    - Live Status messages (show the user at every time, what you are just doing)

     

    - Blocking(!) Input Dialog

     

    - Blocking(!) Message Dialog

     

    - "Abort option" at every time

     

    Sample Code:

     



    procedure TfrmMain.btnTestClick(Sender: TObject);
    var
      Nam: String;
      i: Integer;
      Br: Boolean;
    begin
      MS.Show;
      try
     
        // "Live" Status Messages:
        MS.StatusMsg('Step 1 / 3 ...');
        Sleep(4000); // Do Something here ...
        MS.StatusMsg('Step 2 / 3 ...');
        Sleep(4000); // Do Something here ...
        MS.StatusMsg('Step 3 / 3 ...');
        Sleep(4000); // Do Something here ...
     
        // Input Dialog:
        if MS.InputDlg('Please enter your name:', 'Bill', 50) = 1 then begin
          Nam := MS.LastAnswerVal;
          MS.MessageDlg('Your name is ' + Nam + '!', 'OK');
        end;
     
        // Message Dialog:
        case MS.MessageDlg('What do you want to do today, ' + Nam + '?', 'Do This', 'Do That', 'Do Everything', 'Do Anything' , 'Do Nothing') of
          1: MS.MessageDlg('You Pressed Button 1!', 'OK');
          2: MS.MessageDlg('You Pressed Button 2!', 'OK');
          3: MS.MessageDlg('You Pressed Button 3!', 'OK');
          4: MS.MessageDlg('You Pressed Button 4!', 'OK');
          5: MS.MessageDlg('You Pressed Button 5!', 'OK');
        else
          raise Exception.Create('There is no other Button, only 1 - 5 ?!');
        end;
     
        // "Live" Status Messages with "ABORT" option:
        Br := False;
        for i := 1  to 10000000 do begin
          MS.StatusMsg('Record ' + IntToStr(i) + ' / 10000000', 1000, True); // !!! Important: Use "Delay" (here 1000 ms) if there are many Updates per second !!!
          if MS.HasAbort then begin
            if MS.MessageDlg('Really ABORT ?', 'Yes', 'No') = 1 then begin
              Br := True;
              BREAK;
            end;
          end;
        end;
        if Br then begin
          MS.MessageDlg('User has pressed ABORT !', 'OK');
        end;
        MS.StatusMsg('Ready!');
        Sleep(2000);
     
      finally
        MS.Hide;
      end;
    end;


     

    MsgScr.zip

    post-147-0-49735100-1442885884_thumb.png

    • Upvote 3
  5. Additional you can use a (your) function "FDataModule" in your DataModule as follows:

     

    function FDataModule: TFDataModule;

    begin

      result := uniMainModule.FDataModule;

    end;

     

    Instead of "uniMainModule.FDataModule" you could you use a (String)List/Array/HashMap/... as UniMainModule field with containing all datamodules for the current session; so you have not to declare something for each of your modules in UniMainModule.

  6. This is not thread safe !!!. (session list ist a global var and there is no access control, ... )

     

    Better you store a reference to your DataModule in a Field of TUniMainModule. That would be easy to read/write - no thoughts about sessions and threads, because thread safe and per session by default.

     

     

     

  7. #2

    Use "free form" and you are free...

    UniGui forms that are not in use (displayed) will be freed for less memory consumption. If you show you them later again they are created again, but so prior changes are lost.

     

    #4

    That is how HTTP works: Server can only answer a request - if there is no request, there will be no answer.

     

    #5

    Not every keystroke or mouse move will be sent by default. Would be too much traffic.

    If you can use such high traffic depends on your own system. Do you have view users in a local network, there should be no Problem. Do you have many users over (slow) internet connection, there is a Problem In second case you should use (client side) JavaScript...

  8. #1:

    You have "Free Form" and "UniGUI managed Form". Free Form you must create/free by yourself, you can have more than one instance of it per session at a time. With UniGui Form you have only one per session, create and free will be done by uniGUI. accessing the form (function) will create it, close will free it. The difference to Delphi/VCL is that it can't use global vars for that, because each user/session wants its own instance. So there is a function "MyForm" that delivers the instance for the current session (including create when needed).

     

    #2:

    So that auto create (on access and show) and auto free (on Close) works correct.

     

    #3:

    See #1. And be aware that you do not use global vars.

     

    #4:

    UniTimer fires on client side (browser). That is needed, because browser must first send a request, otherwise Server could not answer (send something to browser).

     

    #5:

    So every key press is send to the Server -> much traffic. You can use Client Events (JavaScript in browser) and then use AjaxRequest(...) when you must process something on Server.

    • Upvote 1
  9. Rav, on 02 Jul 2015 - 11:33 PM, said:

    I looked through your long polling application, very informative, thank you!

    I think that's a little bit complicated scheme, does it have flaws?

    There are 347 downloads - and no bug reports till now...

     

    Rav, on 02 Jul 2015 - 11:33 PM, said:

    Are you planning to add WebSockets example to it?

    No.
  10. As far as I understand the TUniTimer being placed on the main form is instantiated in every session,

    Yes.

     

    so with the 100 open sessions we'll have 100 timers on the server side.

    No. TUniTimer runs/fires on client side (browser). But for every "onTimer" the browser sends a request to ther server. So you have very much network trafffic and the server must handle all these requests.

     

    Is this the right way of constructing the application?

    In my opinion: No. See option 2 and 3 in Post #4.

  11. In other words the clients display some server info and can modify some server parameters remotely.

    When the server parameter is changed (it could be also done due to other internal reasons) the server sends

    a message (delphi record) to all clients, they receive it and update the display info accordingly.

     

     

    By default web servers can't send messages to (all) clients. Servers can only answer a request.

     

    So you can do one of the following;

     

    - using TUniTimer (client (browser) sends every x seconds a request for updates to the server)

     

    - using "web sockets" (HTML5)

     

    - using "long polling" (see here)

  12. But you can show a VCL form with a TWebBrowser in it. So it looks like a standard program (with a web gui).

     

    • create a normal VCL (not UniGUI !) form in your project that is shown at startup
    • put a TwebBrowser onto this form (Align: alClient)
    • onFormShow: WebBrowser.Navigate('http://localhost:8077/');
    • onFormClose: Applicatin.Terminate; // shuts down server if form is closed

    To use a new browser version that works with UniGUI you must must add a registry entry or change !DOCTYPE (second I don't know how doing in UniGUI, but first works for me)

×
×
  • Create New...