Defining a TCP/IP server
To define the server, you use nonvisual parts in the VA: Communications, TCP feature. The example uses a TCP Socket part to listen for and send messages from the database parts.
Begin by adding a nonvisual part named, for example, MyServer, to MyDatabaseTCPIPApp. (To simplify this example, the client and server code are both in MyDatabaseTCPIPApp. To package and deploy this example, you must create a separate application to hold the code for the TCP/IP server.)
Go to the Public Interface Editor and add two attributes: one attribute, data, uses a String data type; and the other, clientSocket, uses an AbtSocket data type. Next, add two events, startServer and endServer, and add then with their defaults.
Go to the Composition Editor and do the following:
1. Using the Add Part menu choice of the Options menu, add a part representing the class MyDatabaseRecord to the free-form surface. You might also name the part dbRcd.
If you have difficulty adding the part, run MyDatabaseRecord initializeAfterLoad to set fixedSize.
2. Drop a Multi-row Query part on the free-form surface and tear off its resultTable attribute. In the settings for the Multi-row Query part, add a query named selectAStaffMember. This query uses a Database Short Integer Field for its host variable id and has the SQL statement below.
SELECT *
FROM STAFF
WHERE (STAFF.ID = :id)
3. Tear off the clientSocket attribute for MyServer.
4. Drop two Variable parts on the free-form surface. For one variable, change its type to AbtSocket and its name to serverSocket. For the other variable, change its name to rowAsString; keep Object as its type.
Go to the Script Editor and add the following methods.
Add the class method startServer:
startServer
"Set the port. This example uses 2012 though you can you any port number."
(MyServer new) startServerOnPort: 2012.
Then add four instance methods:
acceptAndRecive
acceptAndReceive
self clientSocket: (self subpartNamed: 'serverSocket') value accept.
self clientSocket bufferLength: 4098.
self data: (self clientSocket receiveWithLengthInData) contents.
connectAndRunQuery
connectAndRunQuery
| dbm dsn logonSpec spec conn rt rowAsString |
(AbtDbmSystem activeDatabaseConnectionWithAlias: 'serverAlias') isNil
ifTrue: [
dbm := (AnAcessSet serverAlias) dbmClass.
dsn := (AnAcessSet serverAlias) dsn.
logonSpec := AbtDatabaseLogonSpec
id: ((self subpartNamed: 'dbRcd') abtAtAttribute: #userid)
password: ((self subpartNamed: 'dbRcd') abtAtAttribute: #password)
server: dsn.
spec := (AbtDatabaseConnectionSpec
forDbmClass: dbm dataSourceName: dsn)
promptEnabled: false.
conn := spec connectUsingAlias: 'serverAlias' logonSpec: logonSpec.
((AbtDbmSystem activeDatabaseConnectionWithAlias: 'serverAlias') isNil)
ifTrue: [ (self subpartNamed: 'clientSocket of MyServer')
abtPerformAction: #sendIncorporatingLength:
with: (self subpartNamed: 'dbRcd') data ].
].
self subpartNamed: 'Multi-row Query1') executeQueryAsTransaction.
rt := (self subpartNamed: 'resultTable of Multi-row Query1') value.
rowAsString := (rt rows) collect: [ :aRow| aRow asString ].
( rowAsString isEmpty )
ifFalse: [ (self subpartNamed: 'dbRcd') abtAtAttribute: #results
put: (rowAsString at: 1). ].
(self subpartNamed: 'clientSocket of MyServer')
abtPerformAction: #sendIncorporatingLength:
with: (self subpartNamed: 'dbRcd') data.
(self subpartNamed: 'clientSocket of MyServer')
abtPerformAction: #disconnect
portNumber
StartServerOnPort:
startServerOnPort: aPort
(self subpartNamed: 'serverSocket')
value: (AbtSocket serverSocketOnPort: aPort).
self acceptAndReceive.
Return to the Composition Editor and make the following connections:
1. Connect the endServer event of MyServer to the disconnect action of the serverSocket variable.
2. Connect the self attribute of the rowAsString variable to the results attribute of dbRcd (MyDatabaseRecord).
3. Connect the hostVar attribute of dbRcd to the id attribute of the Multi-row Query part.
4. Connect the data event of MyServer to the initializeWith: action of dbRcd.
5. Connect parameter1 (aString) of the data-initializeWith: connection to the data method of MyServer.
6. Connect the sent event of the clientSocket of MyServer tear-off to the disconnect action of the clientSocket of MyServer tear-off.
7. Connect the disconnected event of the clientSocket of MyServer tear-off to the acceptAndReceive script.
8. Connect the data event of MyServer to the connectAndRunQuery script.
9. Connect the startServer event of MyServer to the startServerOnPort: script.
10. Connect parameter1 of the startServer-startServerOnPort: connection to the portNumber script.
When you finish, the Composition Editor shows:
Last modified date: 05/21/2020