tcp_handler.py
Go to the documentation of this file.
1 import rospy
2 import struct
3 from rosbridge_library.rosbridge_protocol import RosbridgeProtocol
4 
5 try:
6  import SocketServer
7 except ImportError:
8  import socketserver as SocketServer
9 
10 class RosbridgeTcpSocket(SocketServer.BaseRequestHandler):
11  """
12  TCP Socket server for rosbridge.
13  An instance of this class is created for each request.
14  """
15 
16  busy = False
17  queue = []
18  client_id_seed = 0
19  clients_connected = 0
20  client_count_pub = None
21 
22  # list of parameters
23  incoming_buffer = 65536 # bytes
24  socket_timeout = 10 # seconds
25  # The following are passed on to RosbridgeProtocol
26  # defragmentation.py:
27  fragment_timeout = 600 # seconds
28  # protocol.py:
29  delay_between_messages = 0 # seconds
30  max_message_size = None # bytes
31  unregister_timeout = 10.0 # seconds
32  bson_only_mode = False
33 
34  def setup(self):
35  """
36  Called before the handle() method to perform any initialization
37  actions required. The default implementation does nothing.
38  """
39  cls = self.__class__
40  parameters = {
41  "fragment_timeout": cls.fragment_timeout,
42  "delay_between_messages": cls.delay_between_messages,
43  "max_message_size": cls.max_message_size,
44  "unregister_timeout": cls.unregister_timeout,
45  "bson_only_mode": cls.bson_only_mode
46  }
47 
48  try:
49  self.protocol = RosbridgeProtocol(cls.client_id_seed, parameters=parameters)
50  self.protocol.outgoing = self.send_message
51  cls.client_id_seed += 1
52  cls.clients_connected += 1
53  if cls.client_count_pub:
54  cls.client_count_pub.publish(cls.clients_connected)
55  self.protocol.log("info", "connected. " + str(cls.clients_connected) + " client total.")
56  except Exception as exc:
57  rospy.logerr("Unable to accept incoming connection. Reason: %s", str(exc))
58 
59  def recvall(self,n):
60  # http://stackoverflow.com/questions/17667903/python-socket-receive-large-amount-of-data
61  # Helper function to recv n bytes or return None if EOF is hit
62  data = bytearray()
63  while len(data) < n:
64  packet = self.request.recv(n - len(data))
65  if not packet:
66  return None
67  data.extend(packet)
68  return data
69 
70  def recv_bson(self):
71  # Read 4 bytes to get the length of the BSON packet
72  BSON_LENGTH_IN_BYTES = 4
73  raw_msglen = self.recvall(BSON_LENGTH_IN_BYTES)
74  if not raw_msglen:
75  return None
76  msglen = struct.unpack('i', raw_msglen)[0]
77 
78  # Retrieve the rest of the message
79  data = self.recvall(msglen - BSON_LENGTH_IN_BYTES)
80  if data == None:
81  return None
82  data = raw_msglen + data # Prefix the data with the message length that has already been received.
83  # The message length is part of BSONs message format
84 
85  # Exit on empty message
86  if len(data) == 0:
87  return None
88 
89  self.protocol.incoming(data)
90  return True
91 
92  def handle(self):
93  """
94  Listen for TCP messages and do all the work to service a request.
95  """
96  cls = self.__class__
97  self.request.settimeout(cls.socket_timeout)
98  while True:
99  try:
100  if self.bson_only_mode:
101  if self.recv_bson() == None:
102  break
103  continue
104 
105  # non-BSON handling
106  bytes = self.request.recv(cls.incoming_buffer)
107 
108  # Exit on empty message because socket was closed
109  if len(bytes) == 0:
110  break
111  else:
112  string_encoded = bytes.decode().strip()
113  if len(string_encoded) > 0:
114  self.protocol.incoming(string_encoded)
115 
116  except Exception as e:
117  pass
118  self.protocol.log("debug", "socket connection timed out! (ignore warning if client is only listening..)")
119 
120  def finish(self):
121  """
122  Called when TCP connection finishes.
123  Called after the handle() method to perform any clean-up actions required.
124  If setup() raises an exception, this function will not be called.
125  """
126  cls = self.__class__
127  cls.clients_connected -= 1
128  self.protocol.finish()
129  if cls.client_count_pub:
130  cls.client_count_pub.publish(cls.clients_connected)
131  self.protocol.log("info", "disconnected. " + str(cls.clients_connected) + " client total." )
132 
133  def send_message(self, message=None, compression="none"):
134  """
135  Callback from rosbridge
136  """
137  if self.bson_only_mode:
138  self.request.sendall(message)
139  elif message is not None:
140  self.request.sendall(message.encode())
141  else:
142  rospy.logerr("send_message called with no message or message is None, not sending")
143 
rosbridge_server.tcp_handler.RosbridgeTcpSocket.unregister_timeout
float unregister_timeout
Definition: tcp_handler.py:31
rosbridge_server.tcp_handler.RosbridgeTcpSocket.incoming_buffer
int incoming_buffer
Definition: tcp_handler.py:23
rosbridge_server.tcp_handler.RosbridgeTcpSocket.client_count_pub
client_count_pub
Definition: tcp_handler.py:20
rosbridge_server.tcp_handler.RosbridgeTcpSocket.socket_timeout
int socket_timeout
Definition: tcp_handler.py:24
rosbridge_server.tcp_handler.RosbridgeTcpSocket.fragment_timeout
int fragment_timeout
Definition: tcp_handler.py:27
rosbridge_server.tcp_handler.RosbridgeTcpSocket.max_message_size
max_message_size
Definition: tcp_handler.py:30
rosbridge_server.tcp_handler.RosbridgeTcpSocket.clients_connected
int clients_connected
Definition: tcp_handler.py:19
rosbridge_server.tcp_handler.RosbridgeTcpSocket.protocol
protocol
Definition: tcp_handler.py:49
rosbridge_server.tcp_handler.RosbridgeTcpSocket.handle
def handle(self)
Definition: tcp_handler.py:92
rosbridge_server.tcp_handler.RosbridgeTcpSocket.client_id_seed
int client_id_seed
Definition: tcp_handler.py:18
rosbridge_server.tcp_handler.RosbridgeTcpSocket.recv_bson
def recv_bson(self)
Definition: tcp_handler.py:70
rosbridge_server.tcp_handler.RosbridgeTcpSocket.send_message
def send_message(self, message=None, compression="none")
Definition: tcp_handler.py:133
rosbridge_library::rosbridge_protocol
rosbridge_server.tcp_handler.RosbridgeTcpSocket.bson_only_mode
bool bson_only_mode
Definition: tcp_handler.py:32
rosbridge_server.tcp_handler.RosbridgeTcpSocket.setup
def setup(self)
Definition: tcp_handler.py:34
rosbridge_library::rosbridge_protocol::RosbridgeProtocol
rosbridge_server.tcp_handler.RosbridgeTcpSocket.delay_between_messages
int delay_between_messages
Definition: tcp_handler.py:29
rosbridge_server.tcp_handler.RosbridgeTcpSocket.finish
def finish(self)
Definition: tcp_handler.py:120
rosbridge_server.tcp_handler.RosbridgeTcpSocket
Definition: tcp_handler.py:10
rosbridge_server.tcp_handler.RosbridgeTcpSocket.recvall
def recvall(self, n)
Definition: tcp_handler.py:59


rosbridge_server
Author(s): Jonathan Mace
autogenerated on Tue Oct 3 2023 02:12:49