PDA

View Full Version : Problems using viznet.client.connect


fordprefect
10-16-2012, 05:53 AM
Hi,

I am trying to set up automated server-client connection between the machines in our virtual reality network. Our network consists of 3 computers (MASTER, HEAD1, HEAD2). Working with the basic elements from the Vizard Help > Reference > Networking > Multi User environment works fine. But this approach needs always the master starting first, then the client, and when the master is disconnected it does not reconnect. So I was playing around a bit but ran into several issues:

1. When reading Help: the command index for <viznet:client>.connect says Return Value: None. Whereas when I look into the Reference>Networking>viznet or ..>Multi User Environment, the return value of this command is always used like in
if viznet.client.connect('MASTER'):
print 'connected'

2. Trying to test it in interactive mode out of the Vizard IDE on HEAD1 but bad luck:
>>> import viz
>>> import viznet
>>> viznet.client.connect('MASTER')
False

The result is always the same, even if 'MASTER' is on the network and started the Vizard IDE, and issuing there in interactive mode these commands:
>>> import viz
>>> import viznet
>>> viznet.server.start()


I found a similar thread from some time ago but without a solution posted.

3. Because we already use the command successfully from script, next thing I try is putting these commands into a python script:
import viz
import viznet

_networkMachines = ('MASTER', 'HEAD1', 'HEAD2', 'HEAD3')

for machine in _networkMachines:
print 'testing machine:', machine,
if viznet.client.connect(machine):
print ' -> connected +++'
viznet.client.disconnect() # (1)
else:
print 'does not run a server ---'

if viz.net.getName().upper() == 'HEAD1':
viznet.server.start()

viz.go()


Given the following scenario:
HEAD1: executing script & starting server and the simulation
HEAD2: online being idle, not running Vizard
HEAD3: not on the network
MASTER: executing the script, displaying the following output result:
testing machine: MASTER -> connected +++
testing machine: HEAD1 -> connected +++
testing machine: HEAD2 -> connected +++
** ERROR: Failed to connect to 'HEAD3'
testing machine: HEAD3 does not run a server ---


Which leaves me with the impression that viznet.client.connect does just a ping on the requested machine but not really confirms a handshake connection at all.

BTW, without the line marked with (1) even HMD3 would look like connected; so it seems further that viznet.client.connect returns True when already connected, ignoring that the connection request was for another machine.

If I am not doing anything wrong, then I would recommend that WorldViz changes the connect command in that it only returns true when there is indeed a connection established with the requested machine, meaning that there runs the server. And returns a couple of errors like
not on the network
not running viznet.server
before connecting to {requestedServer} you have to close existing connection to {currentServer} first (disconnect).


Any comments and/or ideas and/or solutions?
Thanks, Walter

fordprefect
10-18-2012, 10:58 AM
No luck with an answer yet, so I look for a work-around myself. Extend the communication protocol with a connection-test and connect-confirm network events
import viz
import viznet

CONN_TEST = viznet.id("connTest")
CONN_CONF = viznet.id("connConf")

myName = viz.net.getName()

and, for testing reasons, just try to confirm a connection between MASTER and HEAD1, running the same script on each machine:
if myName == 'HEAD1':
doClient()
else:
doServer()

viz.go()

with the server part:
def srvrConnectTest(e):
viznet.server.sendClient(e.client, CONN_CONF, server=myName)
print 'connect confirmation sent'

def doServer():
viznet.server.start()
viz.callback(CONN_TEST, srvrConnectTest)

and the client code being:
import threading
_TIMEOUT = 3.0
_myServer = None
_confirmEvent = threading.Event()

def clntConnectConfirm(e):
_myServer = e.server
print 'received confirmation from', e.server
_confirmEvent.set()

def doClient():
_lookfor = 'MASTER'
if not viznet.client.connect(_lookfor):
print _lookfor, 'does not run'
else:
viz.callback(CONN_CONF, clntConnectConfirm)
print 'asking for connection confirmation...'
viznet.client.send(CONN_TEST, client=myName)
_confirmEvent.clear()
_confirmEvent.wait(_TIMEOUT)
print 'the server's name is', _myServer

but this does not work as it seems that the event queue is only worked upon when the script is completed: the wait time on the Event is always used up, the server replies immediately and the client does only react on the event in the very end. (relevant) Output on the client is:
asking for connection confirmation...
the server's name is None
received confirmation from MASTER

Any idea what I have to do to get the information in time, when I need it, and not ages later??

Thanks,
Best Regards,
Walter

farshizzo
10-18-2012, 02:34 PM
Hi,

A couple things to note:


viznet currently uses UDP sockets for communication, not TCP. So there is no actual connection taking place. As long as the server address exists, it will report a successful "connection".
Network message events are triggered during the main update loop, not asynchronously. So if you are blocking the main thread, then you won't be receiving any network events.


I'd recommend looking into the Python Twisted library (http://twistedmatrix.com/trac/). It supports much more advanced networking features.

However, you can perform a blocking handshake by manually updating the network events in a while loop. Here is a minimal example:

Server code:
import viz
import viznet
viz.go()

HANDSHAKE = viznet.id('ConnectHandshake')

viznet.server.start()

# Perform handshake with clients
def onStartClient(e):
viznet.server.sendClient(e.sender,HANDSHAKE)
viz.callback(viznet.CLIENT_CONNECT_EVENT,onStartCl ient)

Client code:
import viz
import viznet
import vizact
viz.go()

SERVER = 'MASTER'

HANDSHAKE = viznet.id('ConnectHandshake')

def ConnectServer(server,timeout=2.0):
d = viz.Data(connected=False)
if viznet.client.connect(server):
def _handshake(e):
d.connected = True
cb = vizact.addCallback(HANDSHAKE,_handshake)
expire = viz.tick() + timeout
while not d.connected and viz.tick() < expire:
viz.waitTime(0.1)
viz.update(viz.UPDATE_NETWORK)
cb.remove()
return d.connected

if ConnectServer(SERVER):
print 'Connected'
else:
print 'Not Connected'

Hope that is helpful.