Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 from rosbridge_library.capability import Capability
00034 import math
00035
00036
00037 class Fragmentation(Capability):
00038 """ The Fragmentation capability doesn't define any incoming operation
00039 handlers, but provides methods to fragment outgoing messages """
00040
00041 fragmentation_seed = 0
00042
00043 def __init__(self, protocol):
00044
00045 Capability.__init__(self, protocol)
00046
00047 def fragment(self, message, fragment_size, mid=None):
00048 """ Serializes the provided message, then splits the serialized
00049 message according to fragment_size, then sends the fragments.
00050
00051 If the size of the message is less than the fragment size, then
00052 the original message is returned rather than a single fragment
00053
00054 Since fragmentation is typically only used for very large messages,
00055 this method returns a generator for fragments rather than a list
00056
00057 Keyword Arguments
00058 message -- the message dict object to be fragmented
00059 fragment_size -- the max size for the fragments
00060 mid -- (optional) if provided, the fragment messages
00061 will be given this id. Otherwise an id will be auto-generated.
00062
00063 Returns a generator of message dict objects representing the fragments
00064 """
00065
00066 if mid is None:
00067 mid = self.fragmentation_seed
00068 self.fragmentation_seed = self.fragmentation_seed + 1
00069
00070 serialized = self.protocol.serialize(message, mid)
00071
00072 if serialized is None:
00073 return []
00074
00075 message_length = len(serialized)
00076 if message_length <= fragment_size:
00077 return [message]
00078
00079 msg_id = message.get("id", None)
00080
00081 expected_duration = int(math.ceil(math.ceil(message_length / float(fragment_size))) * self.protocol.delay_between_messages)
00082
00083 log_msg = "sending " + str(int(math.ceil(message_length / float(fragment_size)))) + " parts [fragment size: " + str(fragment_size) +"; expected duration: ~" + str(expected_duration) + "s]"
00084 self.protocol.log("info", log_msg)
00085
00086 return self._fragment_generator(serialized, fragment_size, mid)
00087
00088 def _fragment_generator(self, msg, size, mid):
00089 """ Returns a generator of fragment messages """
00090 total = ((len(msg)-1) / size) + 1
00091 n = 0
00092 for i in range(0, len(msg), size):
00093 fragment = msg[i:i+size]
00094 yield self._create_fragment(fragment, n, total, mid)
00095 n = n + 1
00096
00097 def _create_fragment(self, fragment, num, total, mid):
00098 """ Given a string fragment of the original message, creates
00099 the appropriate fragment message """
00100 return {
00101 "op": "fragment",
00102 "id": mid,
00103 "data": fragment,
00104 "num": num,
00105 "total": total
00106 }