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: =  LIB.SocketSystem.SocketSystem
   Table: = 
       ...
       insert(nm: ?String.String, adr: ?String.String):
            ...
       lookup(nm: ?String.String) -> adr: ?String.String:
            ...
   Producer: = BasicProcess("Producer")
           PS: = Socket
           aProd: ?Socket 
           "Producer:\n".print
           PS.init(3000)
           PS.bind
           PS.listen
           aProd:= PS.accept(Producer)
           cycle
               name: ?String.String
               adr: ?String.String
               answer: ?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: ?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: =
   theServer: = LIB.Socket.Socket  -- Ref=none without LIB - adr(Socket)
   theServer.init(3000)
   theServer.connect("localhost")
   cycle
       name: ?String.String
       adr: ?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: =
   theServer: = LIB.Socket.Socket  -- Ref=none without LIB - adr(Socket)
   "Consumer:\n".print
   theServer.init(3001)
   theServer.connect("localhost")
   cycle
       name: ?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.