The example here describes a TableServer that keeps track of the name and address of people.
It consists of a Table object and two objects Producer and Consumer that both are subpatterned from BasicProcess.
The Producer listen on a Socket on port 3000 from new entries and the Consumer listen on a Socket on port 3001 for requests to lookup the name of a person.
The TablesServer is subpatterned from SocketSystem, which defines non-blocking sockets.
Compared to the simple sockets defined here, the accept and receive methods have an extra argument being the calling object and these methods suspend the caller if no object is trying to connect (accept) and if no data is available (receive). The implementation of accept and receive is similar to the implementation of _kbhit and get described here.
TableServer: obj LIB.SocketSystem.SocketSystem
Table: obj
...
insert(nm: ref String.String, adr: ?String.String):
...
lookup(nm: ref String.String) -> adr: ?String.String:
...
Producer: obj BasicProcess("Producer")
PS: obj Socket
aProd: ref Socket
"Producer:\n".print
PS.init(3000)
PS.bind
PS.listen
aProd:= PS.accept(Producer)
cycle
name: ref String.String
adr: ref String.String
answer: reff String.String
name:= aProd.receive(Producer)
adr:= aProd.receive(Producer)
Table.insert(name,Adr)
answer:= "Inserted: " + name + ":" + adr + "\n"
answer.print
aProd.send(answer)
Consumer: = BasicProcess("Consumer")
CS: = Socket
aCons: ref Socket
"Producer:\n".print
CS.init(3001)
CS.bind
CS.listen
aCons:= CS.accept(Consumer)
cycle
name: ?String.String
adr: ?String.String
answer: ?String.String
name:= aCons.receive(Consumer)
adr:= Table.lookup(name)
answer:= "Address of: " + name + " is " + adr + "\n"
answer.print
aCons.send(answer)
cycle
Producer.resume
Consumer.resume
The Producer and Consumer objects are shown here.
Producer: obj
theServer: = LIB.Socket.Socket -- Ref=none without LIB - adr(Socket)
theServer.init(3000)
theServer.connect("localhost")
cycle
name: var String.String
adr: var String.String
"Type a name: ".print
name:= LIB.BasicIO.keyboard.ReadLine
theServer.send(name)
"Type an address: ".print
adr:= LIB.BasicIO.keyboard.ReadLine
theServer.send(adr)
("Producer received: " + theServer.receive + "\n").print
theServer.close;
Consumer: obj
theServer: = LIB.Socket.Socket -- Ref=none without LIB - adr(Socket)
"Consumer:\n".print
theServer.init(3001)
theServer.connect("localhost")
cycle
name: var String.String
"Type a name: ".print
name:= LIB.BasicIO.Keyboard.ReadLine
theServer.send(name)
("Consumer received: " + theServer.receive + "\n").print
theServer.close;
In this example, the three objects are supposed to run on the same machine as three different processes.