tcp_handler.py
Go to the documentation of this file.
00001 import rospy
00002 import struct
00003 from rosbridge_library.rosbridge_protocol import RosbridgeProtocol
00004 
00005 import SocketServer
00006 
00007 class RosbridgeTcpSocket(SocketServer.BaseRequestHandler):
00008     """
00009     TCP Socket server for rosbridge
00010     """
00011 
00012     busy = False
00013     queue = []
00014     client_id_seed = 0
00015     clients_connected = 0
00016 
00017     # list of parameters
00018     incoming_buffer = 65536                 # bytes
00019     socket_timeout = 10                     # seconds
00020     # The following are passed on to RosbridgeProtocol
00021     # defragmentation.py:
00022     fragment_timeout = 600                  # seconds
00023     # protocol.py:
00024     delay_between_messages = 0              # seconds
00025     max_message_size = None                 # bytes
00026     bson_only_mode = False
00027 
00028     def setup(self):
00029         cls = self.__class__
00030         parameters = {
00031             "fragment_timeout": cls.fragment_timeout,
00032             "delay_between_messages": cls.delay_between_messages,
00033             "max_message_size": cls.max_message_size,
00034             "bson_only_mode": cls.bson_only_mode
00035         }
00036 
00037         try:
00038             self.protocol = RosbridgeProtocol(cls.client_id_seed, parameters=parameters)
00039             self.protocol.outgoing = self.send_message
00040             cls.client_id_seed += 1
00041             cls.clients_connected += 1
00042             self.protocol.log("info", "connected. " + str(cls.clients_connected) + " client total.")
00043         except Exception as exc:
00044             rospy.logerr("Unable to accept incoming connection.  Reason: %s", str(exc))
00045 
00046     def recvall(self,n):
00047         # http://stackoverflow.com/questions/17667903/python-socket-receive-large-amount-of-data
00048         # Helper function to recv n bytes or return None if EOF is hit
00049         data = ''
00050         while len(data) < n:
00051             packet = self.request.recv(n - len(data))
00052             if not packet:
00053                 return None
00054             data += packet
00055         return data
00056 
00057     def recv_bson(self):
00058         # Read 4 bytes to get the length of the BSON packet
00059         BSON_LENGTH_IN_BYTES = 4
00060         raw_msglen = self.recvall(BSON_LENGTH_IN_BYTES)
00061         if not raw_msglen:
00062             return None
00063         msglen = struct.unpack('i', raw_msglen)[0]
00064 
00065         # Retrieve the rest of the message
00066         data = self.recvall(msglen - BSON_LENGTH_IN_BYTES)
00067         if data == None:
00068             return None
00069         data = raw_msglen + data # Prefix the data with the message length that has already been received.
00070                                  # The message length is part of BSONs message format
00071 
00072         # Exit on empty message
00073         if len(data) == 0:
00074             return None
00075 
00076         self.protocol.incoming(data)
00077         return True
00078 
00079     def handle(self):
00080         """
00081         Listen for TCP messages
00082         """
00083         cls = self.__class__
00084         self.request.settimeout(cls.socket_timeout)
00085         while 1:
00086             try:
00087               if self.bson_only_mode:
00088                   if self.recv_bson() == None:
00089                       break
00090                   continue
00091 
00092               # non-BSON handling
00093               data = self.request.recv(cls.incoming_buffer)
00094               # Exit on empty string
00095               if data.strip() == '':
00096                   break
00097               elif len(data.strip()) > 0:
00098                   self.protocol.incoming(data.strip(''))
00099               else:
00100                   pass
00101             except Exception, e:
00102                 pass
00103                 self.protocol.log("debug", "socket connection timed out! (ignore warning if client is only listening..)")
00104 
00105     def finish(self):
00106         """
00107         Called when TCP connection finishes
00108         """
00109         cls = self.__class__
00110         cls.clients_connected -= 1
00111         self.protocol.finish()
00112         self.protocol.log("info", "disconnected. " + str(cls.clients_connected) + " client total." )
00113 
00114     def send_message(self, message=None):
00115         """
00116         Callback from rosbridge
00117         """
00118         self.request.send(message)


rosbridge_server
Author(s): Jonathan Mace
autogenerated on Wed Sep 13 2017 03:18:20