TcpIp connection
-.- Connecting to a remote system Cells can run locally or remotely but communicate in the same way, by sending and receiving messages. Of course the connection with the remote system has to be established, before being able to communicate with cells on a remote system. The part of the virtual machine responsible for that is the connection manager. Below you can find a simple example that demonstrates how a link between two systems is set up and how cells on the different systems exchange messages. In this example the send and receive side of the program are combined in one program, so you don't have to flip from one file to another - but obviously they do not need to be in the same program. This example establishes a connection with itself over tcp/ip and sends some messages. In order to run this program you need to know the name (or ip address) of your computer. On Windows you can easily get that by going to settings (window key to get the menu, select settings, then 'system' and then 'about'). The same program can be run on two interconnected computers - the only thing to change is the name (or ip addresses) of the systems to interconnect. The message exchange is as follows: Caller ConxMgr Callee Connect to Apollo on port 27524 -------> <------- Listen on port 27524 Connected <------- -------> Accept incoming connection on 27524 <--------------- Send 'HelloThere(name)' to caller reply 'MyNameIs(name)' ---------------> Send 'x' messages to Callee ---------------> Count the messages Ask how many received ---------------> <--------------- reply nr of messages Note that connecting to a remote system and exchanging messages is easy - no boiler plate code for queueing messages, buffer management, synchronisation etc. is required. To run the example, compile and instantiate ConxTest. -.------------------------------------------------------------------------------------------------- use Windows, Math, Strings, Editor, System -.- The connection test creates two callers and two callees. -.- design ConxTest is cell Caller, Callee cell Creator constructor is -- Create a window for output and set it as stdout system <- stdout.Set( create MenuWindow("Connecting to a remote CellSpeak system over Tcp/Ip")) -- Create two callers that will connect to a port on a remote system.. create CallerDesign("Bob", "Apollo","27524") create CallerDesign("Tim", "Apollo","27526") -- Create two callees that will listen to a port .. create CalleeDesign("Alice", "27524") create CalleeDesign("Judy", "27526") end end -.- The caller tries to connect to another system and sends a number of test messages -.- design CallerDesign( ansi Name, ansi Remote, ansi Port) is cell ConxMgr -- The connection manager cell cell Callee -- The id of the cell that replied keep Name, Remote, Port -- we keep the parameters constructor is -- The caller needs the connection manager - the service is called "ConxMgr" system <- Service.Get("ConxMgr") end on Service.Provider(ansi Service, cell Provider) do -- check the service Service is "ConxMgr" ? ConxMgr = Provider : yield -- We want to set up a connection with a remote system ConxMgr <- TCPIP.Connect(Remote, Port) end -- The connection mgr sends this message if the connection was successful (or was already established) on TCPIP.Connected( ConxClass Conx ) do -- set the protocol to be used over the connection - the last parameter is the cell that will handle the comms ConxMgr <- Set.Protocol( Conx, "CLSPK", self ) -- print a message on the display system <- println("[Name]: connection [Remote] port [Port] established.") end -- The following messages are handled by the 'handler' - the last parameter in the Set.Protocol message on CLSPK.Ready( cell Callee ) do keep Callee -- Give some feedback system <- println("[Name]: CellSpeak protocol ready to talk to cell [Callee]") -- Send hello Callee <- HelloThere(Name) -- Send a nr of test messages for i=1 to 1000 => Callee <- TestMessage("MSG[i] 0123456789 abcdefghijklmnopqrstuvwxyz") -- ask how many received Callee <- HowManyReceived end -- The response from the callee on MyNameIs(ansi NameCallee) do system <- println("[Name]: my counterpart's name is [NameCallee]") end -- The Callee reports the nr of messages received on Received(int count, ansi CalleeName) do system <- println("[Name]: [CalleeName] received a total of [count] messages - closing connection") ConxMgr <- TCPIP.Close( Callee ) end end -.- The callee listens to incoming calls on a specific port and replies to requests from the caller -.- design CalleeDesign(ansi Name, ansi Port) is cell ConxMgr, Caller keep Name, Port constructor is -- The callee also needs the connection manager system <- Service.Get("ConxMgr") end destructor is -- close the connection and stop listening ConxMgr <- TCPIP.Stop.Listening(Port) end on Service.Provider(ansi Service, cell Provider) do -- check that we have received the right service - otherwise yield Service is "ConxMgr" ? ConxMgr = Provider : yield -- We tell the connection manager that we want to listen for incoming cellspeak connections on a port ConxMgr <- TCPIP.Listen( Port ) end -- we get a confirmation of a connection on TCPIP.Accept( ConxClass Conx ) do -- feedback system <- println("[Name] accepts connection [Conx].") -- Set the protocol and the handling cell ConxMgr <- Set.Protocol( Conx, "CLSPK", self ) end -- The protocol has been set successfuly on CLSPK.Ready( cell Caller ) do keep Caller end -- The following are messages that the caller can send and that we respond to on HelloThere(ansi RemoteName) do system <- println("[Name]: [RemoteName] says hello to me") sender <- MyNameIs(Name) end -- The caller will send a series of test messages .. int ReceiveCount = 0 on TestMessage(byte[] Content) do ReceiveCount += 1 end -- ..and ask how many were received on HowManyReceived do -- answer sender <- Received(ReceiveCount, Name) -- we stop the test (pending messages will be sent) ConxMgr <- TCPIP.Close(Caller) end end