Jump to content

Ron

uniGUI Subscriber
  • Posts

    374
  • Joined

  • Last visited

  • Days Won

    31

Posts posted by Ron

  1. If data aware component is on Form A and its datasource is on Form B then move datasource to Form A.

    If datasource is commonly used by more than one form then move it to a DataModule.

     

    I agree, this is the approach I always use: datasource on the same form as data aware component.

     

    I also - in OnCreate on all forms - assign the database to the queries programmatically, as these did get lost.

     

    I also open the MainModule - which has the database all other forms link to - before I open other forms, at project load.

     

    Doing this, I never get this link issue mentioned above, and it all works perfectly.

  2. Sure, Delphi costs a bit, and if the total cost of UniGUI and Delphi

    is more than you plan to earn in the business, then I see the problem.

     

    The real question is how much money are you going to be able to

    generate using these tools? How fast can you pay them back?

     

    If you can generate $50.000 a year then you won't notice the costs.

    But if you can only generate $2.000 it will be tough.

  3. Regarding documentation, I think it is pretty good. There is the manual

    and also a lot of good examples. These could have been documented,

    and that will come no doubt, but most are not complicated at all.

     

    The support is great and critical issues are always fixed quickly, and

    this has happened consistently over many years, so there is no doubt

    as to the commitment of FMSoft to this project.

     

    But the best thing of it all is that UniGUI is so easy to use when you

    just get a little into it. The learning curve is not steep in my view,

    but of course it may take a little time to get used to thinking client-server

    model if webapp building is a new thing.

  4. UniGUI is so reasonably priced that there should be no need to ponder this,

    if you have one or two customers with projects ready to be made.

     

    You are getting the best web application tool in the world right now, and if you

    are not able to earn that little money it costs, during a few months, then I am

    sorry to say - with all respect - that you have nothing to do in this business.

     

    Think about it: you are getting the best, most productive tool there is, 

    and if you are not able to make money then, quickly enough to pay it back,

    whose fault is it? Is it the tool? Or is it the user? Or the business model?

     

    With UniGUI you can finish projects so fast compared to other tools,

    and it is so reasonably priced, that there is no real competition - that is the case.

     

    Of course, you can go the long route and ponder and test and try all

    kinds of things, as I did. It takes years. Or you can do things fast - with UniGUI.

     

    It's all up to you :)

     

    I am lazy. I want to earn the maximum of money using the minimum of time.

    That is why I use UniGUI.

     

    But - if you want to go the other way and earn just a little money using the

    maximum of time, then UniGUI is definitely not for you. Think Microsoft then...

  5. I would rather have API REST access to the hyperserver, so I can

    monitor many servers from one user interface, and purge nodes

    and upload to a single server etc.

     

    A restriction of the number of sessions should be set in the config file, ideally,

    and also changeable through the API.

     

    When I have 20 Hyperservers, it would be nice to be able to change

    port settings through an API, instead of editing 20 text files.

    • Upvote 1
  6. Make an ini-file called setup.ini in the same directory as your app:

    [Setup]
    Port=8088
    

    Then add this in your servermodule:

    procedure TUniServerModule.UniGUIServerModuleCreate(Sender: TObject);
    var Ini: TIniFile;
    begin	
      ServerRoot:=extractfilepath(GetModuleName(HInstance));
      Ini := TIniFile.Create(ServerRoot+'setup.ini');
      try
        Port := strToIntDef(Ini.ReadString('Setup', 'Port', '8088'), 8088);
      finally
        Ini.Free;
      end;	
    end;
    
  7. I had to give up long polling, as the indy http client was too unstable

    due to the apache server being nightly restarted. 

     

    So I had to use cross-origin scripting through the browser to access

    a local webserver running in a service, and do all processing in

    separate small applications, to make this 100% stable.

     

    So to push stuff to the local computer is not a problem.

     

    But to initiate a process from the local computer is harder

    as you want to affect the running client session, so I am going

    to set up another solution.

     

    For example, for product scanning, I will make the local scanner

    which is controlled by the service application and connected to the db

    post the product into a table at the server, and use a timer to check

    this table when the appointment window where you add products

    is opened. Only then the timer runs, and fetches the scanned products.

     

    Another way is to use websockets, but to emit it without having

    a local node server...maybe I can call up Explorer as a COM object

    and run the socket emit code minimized. Have not tried that.

  8. looks like I will process which message show to this client on client side? but it will be thousands messages from different client and only 1 from 100 I should show to client. Also it maybe not secure to send all messages to client which should not know any information from this messages.

     

    You can have different channels, like you see I have using the handshake.query parameter,

    where I use the company name to make sure only those in the same company get it.

     

    In addition you can filter out messages according to all kind of criteria before they are shown to

    the user on the client side.

  9. can I connect in the same way to any socket server, not only node.js?

     

    To any socket.io server, yes, but I do not know of any other implementations of socket.io servers

    than the node.js one. Have not found any windows binaries.

     

    Socket.io is not pure websocket protocol, not at all, but it starts there and downgrades to longpolling if the

    browser do not support websockets. So it provides for greater compatibility across browser versions.

     

    Pure websocket components are available for Delphi, from at least one guy.

  10. Thank you very much! how to use this from EXE file on another server where just only exe-file without unigui? Will I able to connect node.js server from internet? Also I do not quite understand how to check which MainForm shoud show this message and which not (if message only for several active clients from all). It would be greate to have demo application - unigui + separate exe-file with button "send message to unigui client N1". I can pay for this work.

     

    The node.js server listens on a port, and when you open up the firewall it is exposed and will be able to take client connections.

     

    The form which should show the message, is the form with the uniHtmlFrame running the JS code.

    You can process the message in the htmlFrame, as a chat box, or you can send it to the server and

    show it from there, save it etc.

     

    Since the socket.io client is written in JS, which runs only in the browser or in node.js, you have to

    go through one of these. You can push messages locally into the node.js server in different ways,

    but that would be the way to go, if you cannot send it from one of the clients.

     

    In the example above, the client should of course only connect to localhost when testing, and

    be pointed to the actual IP or domain of the live server when in production.

  11. There is no websocket component in Unigui yet, but you may be able to use socket.io with node.js:

    const
      socketToken = 'mySpecialToken';
    
    procedure TMainForm.myHtmlFrameAjaxEvent(Sender: TComponent; EventName: string;
      Params: TUniStrings);
    begin  
      if eventname='doSocketAuth' then 
      begin
        UniSession.AddJS('socket.emit("authenticate", {token: "' + socketToken + '"});');
      end;
      if eventname='gotData' then 
      begin
        //myData:=strtointdef(Params.Values['mydata'], 0);
        //do something with it
      end;
    end;
    
    //to broadcast some data
    procedure TMainForm.socketPush(myData:integer);
    begin
       UniSession.AddJS('if(socket !== undefined)socket.emit("'+companyName+'", ' + inttostr(myData) + ');');
    end;
    
    //some JS to run somewhere to setup the socket connection and catch the incoming data
    if(socket === undefined){
      var socket = io('http://127.0.0.1:3000/?company=' + companyName, {
      reconnection: true, 
      reconnectionDelay: 3000, 
      reconnectionAttempts: 20, 
      forceNew: false,
      secure: true
    });
    }
    
    socket.on('connect', function(){
      ajaxRequest(MainForm.myHtmlFrame, ["doSocketAuth"], { });
    });
    
    socket.on(companyName, function(data){ 
      ajaxRequest(MainForm.myHtmlFrame, ["gotData"], { mydata : data }); 
    });
      
    //node.js script to run an https socket io server
    var fs = require('fs');
    var https = require('https');
    var app = require('express')();
    var options = {
      key: fs.readFileSync('c:/my.key'),
      cert: fs.readFileSync('c:/my.crt')
    };
    var serverPort = 3000;
    var server = https.createServer(options, app);
    var io = require('socket.io')(server);
    
    io.on('connection', function(socket){
      companyName=socket.handshake.query.company;
      socket.auth = false;
      socket.on('authenticate', function(data){
        if(data.token == 'mySpecialToken'){
          socket.auth = true;
        }
      });
     
      setTimeout(function(){
        if (!socket.auth) {
          socket.disconnect('unauthorized');
        }
      }, 1000);
    	
      socket.on(companyName, function(msg){
        if (socket.auth)io.emit(companyName, msg);
      });
    });
    
    server.listen(serverPort, function(){
      console.log('Socket.io https server listening on port ' + serverPort);
    });
    
    

    You will also need to add socket.io.js to the CustomFiles in servermodule and of course set up the node server.

    • Upvote 2
  12. See attached project, basically you can split the html and the JS.

    procedure TMainForm.UniFormShow(Sender: TObject);
    begin
      HTMLFrame2.HTML.Text:='<div id="fb-root"></div>'+
      '<div class="fb-page" data-href="https://www.facebook.com/sbkattila" data-tabs="timeline" data-width="300" data-height="500" data-small-header="true" data-adapt-container-width="true" data-hide-cover="false" data-show-facepile="false">'+
      '<blockquote cite="https://www.facebook.com/sbkattila" class="fb-xfbml-parse-ignore">'+
      '  <a href="https://www.facebook.com/sbkattila">SBK Attila</a>'+
      '</blockquote>'+
      '</div>';
    
    
      UniSession.AddJS('(function(d, s, id) {  ' +
        'var js, fjs = d.getElementsByTagName(s)[0]; ' +
        'if (d.getElementById(id)) return; ' +
        'js = d.createElement(s); js.id = id;  ' +
        'js.src = "https://connect.facebook.net/sv_SE/sdk.js#xfbml=1&version=v3.1&appId=1802520233141884&autoLogAppEvents=1";  ' +
        'fjs.parentNode.insertBefore(js, fjs);  ' +
      '}   ' +
      '(document, "script", "facebook-jssdk"));');
    end;
    

    Project1.zip

    • Like 1
  13. Developing Unigui has no doubt been a monumental task, and considering that

    this has been done primarily by a single individual - with a lot of support and encouragement

    along the way of course - and followed up consistently through all the various

    challenges, is highly impressive. It has no doubt taken an extreme amount of

    dedication and discipline, and I am just happy that such people exist, to be honest.

     

    I would probably pay 10 times as much for Unigui subscriptions, if I had to.

    I know it might sound a bit far-fetched, but I don't have words to describe how much I appreciate it.

    Farshad has proven himself to be such a helpful character, that he will always be part of my prayers.

    And from what I understand, he has a lot of loyal supporters in here :)

     

    As a rule, I never praise people like this, but a couple of times in my life I can handle an Exception,

    knowing that all good gifts come from above, from a higher power :)

    • Upvote 1
  14. Just to clarify, there is not need to to have XData, you can use it but theres no need to, you can use php, python asp.net , mormot(I've done some teste with mormot), or what ever tecnologia you want.

    there is no need to buy nothing else than to tms web core for 295. So in fact is mush cheaper then unigui.

     

     

    Sure, you can use any REST server or even create your own using the Indy http server.

     

    But to make the comparison fair, XData is needed to get close to the RAD level which Unigui works on,

    as you then get client components working with their db mapping/entity system, speeding up the development process.

     

    I could write my webapps using notepad++ and get it all for free, but it would take me about 200 years.

    • Upvote 1
  15. @DelphiDude - have you watched this video on "From Database to Web App through REST server with TMS XData and TMS Web Core"?

     

    https://youtu.be/AZs9e2DNXdI

     

     

    Thanks, I have tried this, but only got "Error connecting to XData server", although

    I was able to connect in design-time and get table field data etc.

     

    No doubt one needs this Data Modeler tool and the XData server if doing anything useful,

    so then we are at about 900 Euros total.

  16. If form2 can only be accessed through form1, then form1 has to be active if form2 is visible.

     

    Unless you have closed form1, that is. But you can then close form2 too, to make sure

    that form1 is always active before form2 gets shown. Syncronized closing.

     

    Otherwise you can save the form visibility state in a global variable, visible or not, updated on

    OnShow and OnClose. Or you can combine the two interfaces by using an expandable panel

    or variable form height where hidden parts of the form contain the second interface controls.

  17. I think it is close to impossible to beat Unigui when it comes to ease of use,

    and relatively small learning curve. You can do a high perceptage of

    projects without the need for heavy modifications, and deployment 

    could hardly be easier unless it also compiled to a server-side language

    like python or php.

     

    In the beginning Unigui could compile JS clients only, so an option to compile

    to both server-side and client-side languages would be interesting, or

    alternatively components for a restful db connection as TMS has.

  18. There are two more differences I want to add:

     

    1. If you will be running many applications, you can probably reduce costs if you spread

    pure JS clients on smaller and cheaper Linux servers, and run them all against one big REST data server

    which may then run on a more expensive Windows or Linux box, or hired in the cloud.

     

    That way you would also separate the applications, instead of running them all on one VPS box

    to save money, and this would add to the stability, and they can run on different domains.

     

    My point is that the splitting of client from server may be beneficial in some cases.

     

    2. The long-term support security is probably greater with TMS, as they are a bigger

    company than Farshad's FMSoft. Unigui's advantage here is that it is becoming so stable

    and mature now that high level support needs are reduced, and the community is

    gradually more and more able to add to the long-term support security. No matter what

    happens, I guess we can be pretty sure that Unigui is here to stay, like TMS.

    • Upvote 3
  19. After some more testing, it is clear that Unigui and TMS Web will never be the same.

     

    First of all, Unigui is producing a client-server solution, whereas TMS Web only compiles a JS client.

     

    So with Unigui, you are on both the server and the client side in the same project, and this makes

    DB connectivity a lot easier.

     

    With TMS Web you have to set up a separate REST server to serve the data, and work with

    entities, which are Delphi objects that mirror DB tables. It can work with several different servers,

    like the their own XData server, Google Cloud, RAD Server and maybe some more.

     

    But this complicates things quite a bit, and creates a steeper learning curve, no doubt.

     

    For the security they use webtokens, which is the industry standard as far as I know,

    so this should be OK. But of course the whole JS application is exposed, and can be downloaded.

    How easy it is to reverse-engineer this I do not know.

     

    You can include pure JS, in asm blocks, as these are then not compiled. 

    Since working with REST, they have Swagger integration, where you can test your REST API.

     

    They are websocket ready: got both client and server websocket components.

    The pas2js compiler related to the FPC project is used, but a validated version of it.

     

    Having it all in a DLL or EXE simplifies things a lot, and makes it easier for the typical Delphi

    programmer to take the step into the world of web applications. Unigui provides possibilities

    for direct JS access, and also for both fixed UI positioning as well as utilizing the ExtJS

    responsive web capabilities, whereas in TMS Web you also have the fixed option, but

    to get responsiveness you have to assign classnames/IDs and then create the CSS yourself,

    as far as I understand it.

     

    Getting the XData server up was not hard, MySQL connectivity worked, but the client-server

    communication I have not been able to solve yet. URLs must be registered, and they have

    a so-called Sparkle webserver at the core of this.

     

    When it comes to deployment, I see the argument that TMS Web itself only needs a simple webserver,

    but then what about the data? If you compile your own XData server, you have to run it there too,

    and at least will need shell access if on a Linux box. Anyway, installing an XData server as a

    service will probably be a tiny bit easier than setting up IIS or Apache for serving DLLs.

     

    Unigui and TMS Web have inherent differences, and both have their strengths and weaknesses,

    although the only limitation for Unigui right now is the lack of portability, as it runs only on Windows.

     

    TMS Web is based on the FNC component library, whereas Unigui is based on ExtJS, which has

    a greater support base and is more mature. TMS has a very good planner component, though,

    which may be more advanced than the ExtJS version. So at the component level there are some

    differences which may be critical for specific projects, but at the end of the day I think Unigui is

    the easier way to go right now for the typical Delphi developer starting with the web.

     

    Price for TMS Web is 300 Euros and for XData server 500 Euros, a total of 800 Euros.

    Price for Unigui Complete is about 750 Euros.

    • Upvote 4
  20.  

    It is a possibility but I have similar validations in several tables and it would imply changing them all and in this case it would not be the best solution.

     

    That is what batch SQL is for :) If 3 minutes of copy & paste can save me 3 days of trouble, I am all in.

  21. I have a project with about 100 forms and no datamodule.

     

    The MainModule has about 100 queries and a single db connection,

    and no datasources.

     

    Each form has from 0 to around 30 queries max, with datasources.

     

    Having the datasources on the forms makes things simpler,

    as the db-aware components' reference to the DS is local,

    and same with the DS-dataset reference.

     

    However, since the dataset references to the connection is

    not local to the form, I have to open the MainModule with the

    connection first, so it is available to the datasets on the forms

    before I open them. Also have to make sure the connection

    is not live at compile time, otherwise it fails at runtime.

     

    To make sure this does not get messed up, I assign all dataset

    connection properties in code, at the OnCreate of the forms.

×
×
  • Create New...