Hey everyone,
I've recently re-written the Stomp python client and I wanted some opinions on the new version (whether it's better than what's currently in svn, how it can be improved, etc). Help from seasoned Python developers swould be appreciated.
Thanks guys!
--
Jeff
[stomp.py]
"""
This is a STOMP protocol module that is designed to be as
simple as possible.
@author Jeff Ward
"""
import socket
""" Private class for doing properties through decorators"""
def Property(function):
return property(doc=function.__doc__, **function())
class StompFrame(object):
def __init__(self, command, headers=None):
if headers is None:
headers = {}
self.__command = command
self.__headers = headers
self.__body = ""
@Property
def command():
def fget(self):
return self.__command
def fset(self, value):
self.__command = value
return locals()
@Property
def headers():
def fget(self):
return self.__headers
return locals()
@Property
def body():
def fget(self):
return self.__body
def fset(self, value):
self.__body = value
return locals()
class Connection(object):
@Property
def connected():
def fget(self):
return self.__connected
return locals()
def __init__(self, hostName, port=61613, login=None, passcode=None):
self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__connected = False
self.__hostName = hostName
self.__port = port
self.__login = login
self.__passcode = passcode
self.__receiveBuffer = ''
def connect(self):
self.__socket.connect ((self.__hostName, self.__port))
frame = StompFrame("CONNECT")
if(self.__login != None):
frame.headers["login"] = self.__login
if(self.__passcode != None):
frame.headers["passcode"] = self.__passcode
self.send (frame)
frame = self.receive()
if(frame == None or frame.command != "CONNECTED"):
# TODO: Throw an exception
pass
else:
self.__connected = True
def close(self):
frame = StompFrame("DISCONNECT")
self.send(frame)
self.__receiveBuffer = ''
self.__socket.shutdown(socket.SHUT_RDWR)
self.__socket.close()
self.__connected = False
def send(self, frame):
# Before sending, we need to check to see if
# this message is unicode, and add headers if need be.
if isinstance(frame.body, unicode):
actualBody = frame.body.encode('UTF-8')
frame.headers["content-encoding"] = "UTF-8"
frame.headers["content-length"] = len(actualBody)
frame.body = actualBody
self.__socket.sendall("%s\n" % (frame.command))
for k,v in frame.headers.items():
self.__socket.sendall ("%s:%s\n" % (k,v))
self.__socket.sendall ("\n")
self.__socket.sendall (frame.body)
self.__socket.sendall ("\x00\n")
def receive(self, timeout=None):
if timeout != None:
oldTimeout = self.__socket.gettimeout()
self.__socket.settimeout(timeout)
command = self.__readBufferLine()
frame = StompFrame(command)
header = self.__readBufferLine()
while(header != ''):
colon = header.index(':')
frame.headers[header[:colon]] = header[colon+1:]
header = self.__readBufferLine()
body = ''
# First, check to see if we have a content-length header
if frame.headers.has_key('content-length'):
# If we do, it means we can read to then end, accounting for
# the extra "null" bit at the end (which is added to all Stomp messages)
length = int(frame.headers['content-length'])
while len(self.__receiveBuffer) < length + 1: # +1 is for the final \x00
self.__readToBuffer()
encodedBody, self.__receiveBuffer = self.__receiveBuffer[:length], self.__receiveBuffer[length + 1:]
# Check if this was encoded some how and decode it if it was
if frame.headers.has_key('content-encoding'):
body = encodedBody.decode(frame.headers['content-encoding'])
else:
body = encodedBody
else:
# If there's no content length, we have an ascii string, and we can just read until
# we get a "null" character.
eofIndex = self.__receiveBuffer.find('\x00')
while eofIndex < 0:
self.__readToBuffer()
eofIndex = self.__receiveBuffer.find('\x00')
body, self.__receiveBuffer = self.__receiveBuffer[:eofIndex], self.__receiveBuffer[eofIndex + 1:]
frame.body = body
# Remove the trailing newline
self.__readBufferLine()
if timeout != None:
self.__socket.settimeout(oldTimeout)
return frame
def __readToBuffer(self):
data = self.__socket.recv(2048)
self.__receiveBuffer = self.__receiveBuffer + data
def __readBufferLine(self):
nlIndex = self.__receiveBuffer.find('\n')
while nlIndex < 0:
self.__readToBuffer()
nlIndex = self.__receiveBuffer.find('\n')
line, self.__receiveBuffer = self.__receiveBuffer[:nlIndex], self.__receiveBuffer[nlIndex + 1:]
return line
class Message:
headers={}
body=""
command=""
def init(self,cmd,hds,bdy):
self.headers=hds
self.body=bdy
self.command=cmd
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email