1. Hans Groeneveld
  2. PowerBuilder
  3. Thursday, 4 January 2024 14:11 PM UTC

Our application (PB 2022 R2) connect to a SQL Anywhere 17 db.

By a inherited transaction object.

We do have also C# applications that also connect to the same database.
From the C# application  we like to send a message to the PowerBuilder application.
The PB application should catch the message (by some event) and pops the message, or do something with it.

In SQL Anywhere we cal sent a message using the SQL statement MESSAGE.
For example:
MESSAGE 'this is a message' TO CLIENT FOR CONNECTION 123 ;

But how can I catch this message in the transaction object?
I googled for a while and found something around db_register_a_callback.

Anybody any idea how to solve this?

Maybe a complete other way..?

Thanks
Hans

 

 

 

Arthur Hefti Accepted Answer Pending Moderation
  1. Friday, 5 January 2024 09:41 AM UTC
  2. PowerBuilder
  3. # 1

Hi

You could loop through the open windows in C# until you find your PB app e.g. by title and send a message to the PB app. The app has do define a custom event on the main window where e.g. wparm can be used to identify the sender and lparam as the command.

We did this in PB. Windows API functions used are FindWindowA, GetWindowTextW and GetWindow to find the window and Send( <Handle of the window found>, 1024, <id>, <command> ). You need to find the C# equivalents.

On the PB side define an event e.g. ue_automate and map it to pb_custom01. In the script check if wparm = <id> and execute a command based on the value of <command>

Regards
Arthur

Comment
There are no comments made yet.
Ronnie Po Accepted Answer Pending Moderation
  1. Thursday, 4 January 2024 18:44 PM UTC
  2. PowerBuilder
  3. # 2

Hi Hans,

I haven't used this before, but the SQL Anywhere documentation states

"FOR clause For messages TO CLIENT, this clause specifies which connections receive notification about the message. By default, the connection receives the message the next time a SQL statement or a WAITFOR DELAY statement is executed."

It seems that you might need to pull the message from the client by issuing a (dummy?) SQL statement and monitoring the transaction object.

Comment
  1. Hans Groeneveld
  2. Friday, 5 January 2024 07:41 AM UTC
Thanks Ronnie, that needs a continues loop, because we need a quick response. When a user clicks a button in the browser (a app that connects to the db), the PB should open, for example a offer window, that corresponds with the information in the browser. A timer/loop will take in this situation too much resources.
  1. Helpful
  1. Ronnie Po
  2. Friday, 5 January 2024 08:20 AM UTC
Can you have the C# application send the message directly to the PowerBuilder app using TCP/IP, or is there some reason that you must use the database? Roland Smith has some nice sample code that you can use to set up a TCP/IP listener in your PB app:

https://www.topwizprogramming.com/freecode_winsock.html
  1. Helpful
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Thursday, 4 January 2024 18:18 PM UTC
  2. PowerBuilder
  3. # 3

Hi Hans;

  I have done this tons of times in the past using various DBMS venfor types. My  KISS principle that I used was to create a App_Message table and update it with a row targeted to another App(s). Then in the other Apps(ie: PB) use a Timer to "Poll" the App_Message table for passing messages for work to be performed. Then when that row is been fully processed by the related App(s), set a column flag on the message row to make it "processing completed". This "low tech" approach has always been super easy to implement & maintain IMHO. Food for thought.  HTH   ;-)

Regards ... Chris

Comment
  1. Hans Groeneveld
  2. Friday, 5 January 2024 07:30 AM UTC
Thanks Chris. We use that old school method also but for this problem I need a immediattely repsone. When a user clicks a button in the browser (a appp that connects to the db), the PB should open, for example, a offer window that corresponds with the information in the browser.

  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Thursday, 4 January 2024 14:21 PM UTC
  2. PowerBuilder
  3. # 4

Hi Hans,

You can call a powerbuilder event from C#, passing a string parameter:

https://docs.appeon.com/pb2022/application_techniques/Triggering_PowerScript_events_from_code.html 

Comment
  1. Hans Groeneveld
  2. Thursday, 4 January 2024 15:50 PM UTC
Thanks Miguel.



The following code return a -5 when I use 'w_test'. w_test is a window that is opened already.



Then I use 'w_t', a window object that is not opened already, I got a -50.

But this if I got this to work it will only work if the C# app is running at the same PC. That is not always the case.



integer ll_return

dno_test = CREATE dotnetobject //dno_test is an instance variable

IF IsValid(dno_test) THEN

ll_return = dno_test.RegisterObject("w_test", w_test)

if ll_return <> 1 then

MessageBox("Error", "RegisterObject w_dotnettest failed" + String(ll_return))

end if

ELSE

MessageBox("Error", "RegisterObject not created..?")

END IF

  1. Helpful
  1. Miguel Leeuwe
  2. Thursday, 4 January 2024 15:53 PM UTC
My bad, I thought it was a C# DLL that you had imported with the DLL import tool of powerbuilder.
  1. Helpful
  1. Chris Pollach @Appeon
  2. Friday, 5 January 2024 14:57 PM UTC
This was so easy to implement when we had the Distributed PB feature as it had the "Server Push" capability. :-(
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.