demo fonctionelle
Superviseur basique et filtrage
This commit is contained in:
parent
7a9a0421e6
commit
d0a49e744e
4 changed files with 172 additions and 0 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
import socket
|
import socket
|
||||||
|
@ -15,6 +16,7 @@ from coapthon.messages.request import Request
|
||||||
from coapthon.messages.response import Response
|
from coapthon.messages.response import Response
|
||||||
from coapthon.serializer import Serializer
|
from coapthon.serializer import Serializer
|
||||||
|
|
||||||
|
from coapthon.client.superviseur_local import SuperviseurLocalBase
|
||||||
|
|
||||||
__author__ = 'Giacomo Tanganelli'
|
__author__ = 'Giacomo Tanganelli'
|
||||||
|
|
||||||
|
@ -65,6 +67,8 @@ class CoAP(object):
|
||||||
|
|
||||||
self._receiver_thread = None
|
self._receiver_thread = None
|
||||||
|
|
||||||
|
self.superviseur = SuperviseurLocalBase(self)
|
||||||
|
|
||||||
def purge_transactions(self, timeout_time=defines.EXCHANGE_LIFETIME):
|
def purge_transactions(self, timeout_time=defines.EXCHANGE_LIFETIME):
|
||||||
"""
|
"""
|
||||||
Clean old transactions
|
Clean old transactions
|
||||||
|
@ -166,6 +170,7 @@ class CoAP(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._socket.sendto(raw_message, (host, port))
|
self._socket.sendto(raw_message, (host, port))
|
||||||
|
self.superviseur.envoie_message(message)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if self._cb_ignore_write_exception is not None and isinstance(self._cb_ignore_write_exception, collections.Callable):
|
if self._cb_ignore_write_exception is not None and isinstance(self._cb_ignore_write_exception, collections.Callable):
|
||||||
if not self._cb_ignore_write_exception(e, self):
|
if not self._cb_ignore_write_exception(e, self):
|
||||||
|
@ -273,6 +278,7 @@ class CoAP(object):
|
||||||
source = (host, port)
|
source = (host, port)
|
||||||
|
|
||||||
message = serializer.deserialize(datagram, source)
|
message = serializer.deserialize(datagram, source)
|
||||||
|
self.superviseur.reception_message(message)
|
||||||
|
|
||||||
if isinstance(message, Response):
|
if isinstance(message, Response):
|
||||||
logger.info("receive_datagram - " + str(message))
|
logger.info("receive_datagram - " + str(message))
|
||||||
|
|
|
@ -28,6 +28,7 @@ class HelperClient(object):
|
||||||
self.protocol = CoAP(self.server, random.randint(1, 65535), self._wait_response, sock=sock,
|
self.protocol = CoAP(self.server, random.randint(1, 65535), self._wait_response, sock=sock,
|
||||||
cb_ignore_read_exception=cb_ignore_read_exception, cb_ignore_write_exception=cb_ignore_write_exception)
|
cb_ignore_read_exception=cb_ignore_read_exception, cb_ignore_write_exception=cb_ignore_write_exception)
|
||||||
self.queue = Queue()
|
self.queue = Queue()
|
||||||
|
self.superviseur = self.protocol.superviseur
|
||||||
|
|
||||||
def _wait_response(self, message):
|
def _wait_response(self, message):
|
||||||
"""
|
"""
|
||||||
|
|
108
coapthon/client/superviseur_local.py
Normal file
108
coapthon/client/superviseur_local.py
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class SuperviseurLocalBase():
|
||||||
|
"""Class de base pour le superviseur
|
||||||
|
"""
|
||||||
|
def __init__(self, client_CoAP) -> None:
|
||||||
|
self.client = client_CoAP
|
||||||
|
self._n_tokken = 0
|
||||||
|
self._n_envoie = 0
|
||||||
|
|
||||||
|
def envoie_message(self, message) -> None:
|
||||||
|
self.envoie_token(message.token)
|
||||||
|
|
||||||
|
def reception_message(self, message) -> None:
|
||||||
|
self.reception_token(message.token)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_RTT(self):
|
||||||
|
"""Valeur minimum du RTT"""
|
||||||
|
return min(self.RTTs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def avg_RTT(self):
|
||||||
|
"""Moyenne du RTT."""
|
||||||
|
return sum(self.RTTs)/len(self.RTTs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tau_retransmission(self):
|
||||||
|
"""Rapport du nombre de message correspondant à des restransmission sur le nombre de message total."""
|
||||||
|
return 1 - self._n_tokken/self._n_envoie
|
||||||
|
|
||||||
|
|
||||||
|
class SuperviseurLocal(SuperviseurLocalBase):
|
||||||
|
"""
|
||||||
|
Class implementant la supervision local de chaque client.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client_CoAP) -> None:
|
||||||
|
super().__init__(client_CoAP)
|
||||||
|
self._dict_envoie = {}
|
||||||
|
self._dict_reception = {}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def RTTs(self):
|
||||||
|
RTTs = []
|
||||||
|
for token in self._dict_reception:
|
||||||
|
if token in self._dict_envoie:
|
||||||
|
RTTs.append(
|
||||||
|
self._dict_reception[token][0] - self._dict_envoie[token][-1])
|
||||||
|
return RTTs
|
||||||
|
|
||||||
|
def envoie_token(self, token) -> None:
|
||||||
|
"""Enregistre l'envoie d'un token
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token (int): Token à enregistrer
|
||||||
|
"""
|
||||||
|
self._n_envoie += 1
|
||||||
|
if token in self._dict_envoie:
|
||||||
|
self._dict_envoie[token].append(time.time())
|
||||||
|
else:
|
||||||
|
self._n_tokken += 1
|
||||||
|
self._dict_envoie[token] = [time.time()]
|
||||||
|
|
||||||
|
def reception_token(self, token) -> None:
|
||||||
|
"""Enregistre l'arrivée d'un token
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token (int): Token à enregister
|
||||||
|
"""
|
||||||
|
if token in self._dict_reception:
|
||||||
|
self._dict_reception[token].append(time.time())
|
||||||
|
else:
|
||||||
|
self._dict_reception[token] = [time.time()]
|
||||||
|
|
||||||
|
|
||||||
|
class SuperviseurLocalFiltre(SuperviseurLocalBase):
|
||||||
|
def __init__(self, client_CoAP, rtt_init=0.001, alpha_l=0.01, alpha_s=0.1) -> None:
|
||||||
|
super().__init__(client_CoAP)
|
||||||
|
self._dict_envoie = {}
|
||||||
|
self.alpha_l = alpha_l
|
||||||
|
self.alpha_s = alpha_s
|
||||||
|
self.RTT_L = rtt_init
|
||||||
|
self.RTT_S = rtt_init
|
||||||
|
self.RTTs = []
|
||||||
|
|
||||||
|
def envoie_token(self, token) -> None:
|
||||||
|
"""Enregistre l'envoie d'un token
|
||||||
|
|
||||||
|
Args:
|
||||||
|
token (int): Token à enregistrer
|
||||||
|
"""
|
||||||
|
self._n_envoie += 1
|
||||||
|
if token in self._dict_envoie:
|
||||||
|
self._dict_envoie[token].append(time.time())
|
||||||
|
else:
|
||||||
|
self._n_tokken += 1
|
||||||
|
self._dict_envoie[token] = [time.time()]
|
||||||
|
|
||||||
|
def reception_token(self, token) -> None:
|
||||||
|
if token in self._dict_envoie:
|
||||||
|
r = time.time() - self._dict_envoie[token][-1]
|
||||||
|
self.RTTs.append(r)
|
||||||
|
self.RTT_L = r*self.alpha_l + (1 - self.alpha_l) * self.RTT_L
|
||||||
|
self.RTT_S = r*self.alpha_s + (1 - self.alpha_s) * self.RTT_S
|
||||||
|
else:
|
||||||
|
raise ValueError
|
57
demo_superviseur.py
Normal file
57
demo_superviseur.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
from coapthon.client import superviseur_local
|
||||||
|
|
||||||
|
from coapthon.client.helperclient import HelperClient
|
||||||
|
from coapthon.client.superviseur_local import SuperviseurLocal, SuperviseurLocalFiltre
|
||||||
|
from coapthon.utils import parse_uri
|
||||||
|
|
||||||
|
|
||||||
|
host, port, path = parse_uri("coap://localhost:5683/basic")
|
||||||
|
try:
|
||||||
|
tmp = socket.gethostbyname(host)
|
||||||
|
host = tmp
|
||||||
|
except socket.gaierror:
|
||||||
|
pass
|
||||||
|
print('start client')
|
||||||
|
client = HelperClient(server=(host, port))
|
||||||
|
print('client started')
|
||||||
|
client.protocol.superviseur = SuperviseurLocalFiltre(client)
|
||||||
|
super = client.protocol.superviseur
|
||||||
|
|
||||||
|
rtt_l = []
|
||||||
|
rtt_s = []
|
||||||
|
|
||||||
|
for n_rep in range(1000):
|
||||||
|
# print('rep{}'.format(n_rep))
|
||||||
|
response = client.get(path)
|
||||||
|
rtt_l.append(super.RTT_L)
|
||||||
|
rtt_s.append(super.RTT_S)
|
||||||
|
# time.sleep(1)
|
||||||
|
# print("{} : \n{}".format(n_rep, response.pretty_print()))
|
||||||
|
client.stop()
|
||||||
|
|
||||||
|
print(super.min_RTT, super.avg_RTT, super.tau_retransmission)
|
||||||
|
|
||||||
|
fig, axs = plt.subplots(2)
|
||||||
|
|
||||||
|
axs[0].hist(super.RTTs, 100, density=True)
|
||||||
|
|
||||||
|
axs[0].set_xlabel('RTT (s)')
|
||||||
|
axs[0].set_xlim(left=0)
|
||||||
|
|
||||||
|
# axs[1].step(range(1000), super.RTTs, where='post', label='$RTT$')
|
||||||
|
axs[1].plot(rtt_l, label="$RTT_L$")
|
||||||
|
axs[1].plot(rtt_s, label="$RTT_S$")
|
||||||
|
|
||||||
|
|
||||||
|
axs[1].set_ylim(bottom=0)
|
||||||
|
axs[1].set_xlabel('Nombre de message')
|
||||||
|
axs[1].set_ylabel('RTT (s)')
|
||||||
|
axs[1].legend()
|
||||||
|
|
||||||
|
fig.suptitle('Resultat sur un serveur local')
|
||||||
|
|
||||||
|
fig.tight_layout()
|
||||||
|
fig.savefig('demo.png')
|
Loading…
Reference in a new issue