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


rosbridge_server
Author(s): Jonathan Mace
autogenerated on Thu Jun 6 2019 21:51:50