So I’m looking into a tool that I have an idea for.
I want to communicate from computer A’s Maya instance on my network to computer B’s Maya instance on my network. I don’t want to send scenes or anything, but rather a tiny stream of information.
I’m curious as to how I would start researching this and things that I can use. I’d prefer to use Python, but if I have to use a method utilizing C++ instead, that would be fine.
Thanks.
You want a peer-to-peer ad hoc network in python. There are a few examples of this out there you can borrow from. And you might want to look at twisted or another framework, but those bring along a lot of overhead.
You might also want to look into the world on Remote Procedure Calls in Python. RPC is a superset of messaging over Python-P2P systems that not only passes messages, but those messages say, “Run this code for me.” In your case, the code you want executed might just be sendAMessage(myMessage) or logAnError(myError). You define what those functions mean.
This is all vanilla Python. I would probably write the communications layer as it’s own module, and then wrap that in a Maya specific module. This way you can reuse the same code in any Python application. On the Maya side, you’re going to have to look into multithreading and Maya’s special needs when dealing with multithreading.
Good Luck Mr. Bond
EDIT: Oh yeah, one of the things you’re going to have to think about is “how do your peers find each other?” The easiest way to do this if you own all the machines in question is to post a list of the peers you want to be able to talk to each other along with the code. If you want this to happen automatically, the term for this is auto-discovery, and that rabbit hole is pretty deep unless you find a library that does it for you. You can also set it up so that one machine is the central server and that machine communicates with all the other machines and optionally provides look-up services between them if you want it truly peer-to-peer.
For example, you want two artists to be able to chat with each other from within Maya. Each Maya session would register itself with the central server, and when one of them sends a message to the other, it either gets sent through the server, or it asks the server for the other’s IP address.
[QUOTE=btribble;27663]You want a peer-to-peer ad hoc network in…[/QUOTE] AWESOME. Thank you so much, I’m sure this will help out a ton. I’ll start looking through it after work today!
Or you can just use the commandport to send Mel or python code directly to Maya via the lab.
Might be useful if you’re doing this on windows
import socket
import subprocess
from Queue import Queue
from threading import Thread
"""
module lan
this namespace is for utility functions deailing with simple questions about the
local network. It's not for serious networking code - just for inspecting the
LAN (eg, looking to see what other machines are around
"""
def _ip_format(item):
"""
Convert an ip string into a tuple (N.N.N.N)
"""
return tuple(map(int, item.split(".")))
def _ip_to_str(ip):
"""
Converts an ip tuple (N.N.N.N) to a string
"""
if hasattr(ip, '__iter__'):
return (".".join(map(str, ip)))
else:
return ip
def ip_info():
"""
Returns a dictionary with the hostname, ip address, and subnet mask of the local machine
Note this uses the windows ipconfig command, and it will return the first
set of info it finds -- if there are multiple adapters it will return the
first one it sees
If the command can't be parsed, raises a RuntimeError
"""
po = subprocess.Popen("ipconfig", stdout=subprocess.PIPE)
subnet, ip, gateway = None, None, None
retcode = po.communicate()
for eachLine in retcode[0].splitlines():
if eachLine:
if eachLine.count("Subnet Mask"):
subnet = _ip_format(eachLine.partition(":")[-1].strip())
if eachLine.count('IPv4 Address'):
ip = _ip_format(eachLine.partition(":")[-1].strip())
if eachLine.count('Default Gateway'):
gateway = _ip_format(eachLine.partition(":")[-1].strip())
if subnet and ip and gateway:
return {
"subnet": subnet,
"ip": ip,
"gateway": gateway
}
raise RuntimeError, "unable to determine IP info"
def ping(ip):
"""
Pings the supplied ip ( a string or a tuple). Returns -1 if the hose cannot be found and 1 if it can.
@todo: parse out the actual ping time
"""
po = subprocess.Popen("ping -n 1 " + _ip_to_str(ip), stdout=subprocess.PIPE)
result = po.communicate()[0]
if result.count("unreachable"):
return -1
else:
return 1
def scan_local_network(threads=4):
"""
Scans the local network and returns a list of all visible machines. This
process takes several seconds of real time. User can supply an number of
threads to use in the scan, which speeds up the query ( default nubmer of
threads is 4)
The entries in the result are in the same format as socket.gethostbyaddr
"""
ip_queue = Queue()
results = []
subnet = ip_info()['ip']
for suffix in range(0, 255):
newIp = subnet[0], subnet[1], subnet[2], suffix
ip_queue.put(newIp)
# inner proc
def _test_ip(in_q, out_q):
while in_q.not_empty:
ip = _ip_to_str(in_q.get())
p = ping(ip)
if p > -1:
try:
machine = socket.gethostbyaddr(_ip_to_str(ip))
out_q.append(machine)
except:
pass
in_q.task_done()
# spin up as many threads as requested. Numbers > 4 don't help too much
for i in range(threads):
worker = Thread(target=_test_ip, args=(ip_queue, results))
worker.setDaemon(True)
worker.start()
# block until scan is complete
ip_queue.join()
return results
__all__ = ['ping', 'scan_local_network', 'ip_info']
[QUOTE=Theodox;27682]Might be useful if you’re doing this on windows[/QUOTE]
Thanks, Steve!
I’m not sure if that would work(just because I’ve never done it) but I’ll definitely look into it as an option. Thanks!