'socket.recv is empty but the result is showing in Maya
I am trying to get values for the rotation of joints in Maya into an external IDE. I have successfully been able to send commands and Maya responds properly but I am having trouble understanding how to receive the results back in the IDE.
I have tried using socket.recv and socket.recvmsg but got errors for both.
Code running in PyCharm
import socket
host = 'localhost'
port = 7720
code1 = ("servo_1 = [cmds.getAttr('joint2.rotateY')]\\n"
"print servo_1")
try:
# Connect to Maya Command Port
maya = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
maya.connect( (host,port) )
# Send Command Through Socket --> Can Only Send MEL Commands
message = 'python("{}")'.format(code1)
print message
maya.send(message)
reply = maya.recv(4096)
print reply
except:
raise Exception, 'Connection Failed To : %s:%s' % (host, port)
finally:
#Close Socket Connection
maya.close()
Code in Maya to open the commandPort
import maya.cmds as cmds
if not cmds.commandPort(':7720', q=True, echoOutput=True, noreturn=False):
cmds.commandPort(name=':7720')
The expected output is [43.74] as is shown in Maya but the actual output in PyCharm
Solution 1:[1]
I got it to work by setting up a client socket connection from Maya to PyCharm making a python socket server and setting up maya as the client and using the pickle module to send a list.
Python Server
import socket
import pickle
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(4096)
if not data: break
conn.send(data)
data2 = pickle.loads(data)
print 'servo_1 = %s' % (data2)
conn.close()
Maya Client
import socket, pickle
import maya.cmds as cmds
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
max = int(cmds.playbackOptions( q=True, aet=True))
servo_1 = [cmds.getAttr("joint2.rotateY")]
data_string = pickle.dumps(servo_1)
s.send(data_string)
data = s.recv(4096)
data_arr = pickle.loads(data)
s.close()
print 'Received', repr(data_arr)
Solution 2:[2]
CommandPort is meant for sending commands rather than retrieving output, there's still a way to do it: the trick is you need to send each command and receive output separately: https://forums.cgsociety.org/t/telnet-or-socket-no-result-back-from-maya/1730817/2
But the smart way to do is using maya.api.OpenMaya MCommandMessage message callback to stream output that maya received; So basically, a server (editor) client (maya) to send command, and another client (editor) server to stream output. This is how plugin's like MayaCharm (for PyCharm) and MayaSublime (for Sublime) work, and this is what I ended up choosing after some research. See detail examples:
https://www.xingyulei.com/post/maya-commandport/
https://www.xingyulei.com/post/maya-streaming/
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ben Gagnon |
| Solution 2 | xingyulei |
