CustomTCPServerContainer

class labpyproject.core.net.custom_TCP.CustomTCPServerContainer(server_address, externalhandler=None, auto_connect=True)[source]

Bases : labpyproject.core.app.app_components.NETComp

Serveur « frontal » (conteneur du ThreadedTCPServer).

Requètes entrantes :

Prises en charge par l’objet server (ThreadedTCPServer) via le handler(CustomTCPRequestHandler) appelant la méthode handle_indexed_msg() de cet objet. Ce serveur frontal transmet ensuite les données à l’application associée via un mécanisme générique de Queues (ou par un handler externe sinon). Lors de la première connexion d’un client, celui-ci fait une demande d’identifiant unique au serveur. Cet uid permettra par la suite d’identifier le client bien que son adresse distante change au fûr et à mesure de ses reconnections (cf gestion des requètes par ThreadedTCPServer).

Requètes sortantes (vers les clients) :

ThreadedTCPServer fermant les connexions entrantes après traitement, le client doit communiquer une adresse (host, port) qu’il écoute afin que le serveur puisse l’appeler. Dans ce cas le serveur se comporte comme un client et le client comme un serveur.

Toutes les requètes sont codées (découpées, indéxées, envoyées) / décodées (reçues, analysées, recomposées) par l’utilitaire CustomRequestHelper qui prend également en charge l’insertion de codes et arguments de commandes pour les processus d’identification des clients (uid), la communication de leur adresse d’écoute (requètes sortantes) et la gestion d’accusés de réception.

Logs :

Le serveur trace les données de connection avec les clients. Il enregistre également les erreurs survenues lors des connections, envois et réceptions. A chaque occurence d’une action d’envoi ou réception, le serveur envoie au composant business (appli métier), un dict d’infos réseau via la méthode dispatch_network_infos.

Détection des connections clients « rompues sauvagement » :

A chaque survenue d’une erreur (connection, envoi, réception), on l’analyse afin de mettre à jour le statut du client.

  • S’il s’agit d’une OSError on considère son degré de gravité (voir CustomRequestHelper.ERRNO_DICT, sous ensemble de errno cohérent avec les problématiques réseau).

    • Si l’erreur est considérée comme fatale, l’état du client passe à CustomRequestHelper.STATUS_ERROR_CONNECTION.

    • Sinon, l’état du client passe à CustomRequestHelper.STATUS_UNDEFINED (client probablement déconnecté). Dans ce cas les prochaines tentatives de connection ou envoi se limiteront à un essaipour ce client. Charge à l’appli métier de décider de considérer définitivement ce client comme déconnecté.

  • Parfois un envoi ne lève pas d’erreur mais ne reçoit pas le bon accusé de réception (0 au lieu de la longueur du message envoyé). Celà peut se produire du fait d’une erreur d’encodage/décodage utf-8 (voir exemple ci dessous). Après CustomRequestHelper.SEND_MAX_COUNT tentatives infructueuses, le serveur communique le problème au composant business (voir sa méthode NET_signal_send_error(self, exobj)). L’objet d’échange contient les uids des clients en erreur, le message original et le paramètre d’accusé de réception. Charge au composant business de procéder à un nouvel essai d’envoi.

Exemple de problème d’encodage/décodage utf-8-bytes-utf-8 :

Erreurs de décodage côté client:

CustomRequestHelper._receive_buffer_block ne peut décoder un bloc de données binaires, il retourne :

UnicodeDecodeError('utf-8', b'<#bp#>|1/3|TCPSvr|457|[cmd:NEED_CONFIRMATION|]gamecmd=CHOOSE_GAME&comuid=lpsvr_gcom1002auc&uid=uid2&listeniveaux=[1- La paix sur terre,2- Quasiment non violent,3- De nouveaux participants,4- Ca se corse,5- Sauve qui peut]&msg_input=Choisissez un numÃ<#bs#>', 249, 250, 'invalid continuation byte')

ou encore:

UnicodeDecodeError('utf-8', b'<#bp#>|2/3|TCPSvr|457|©ro de niveau pour commencer à jouer.&msg_input_alt=Choisissez un niveau puis cliquez sur : \n- partie (pour jouer) \n- démo (pour regarder une partie automatique)&typechoix=CHOOSE_GAME&comuid=lpsvr_gcom1001abs<MSGUID=TCPSvr_117<#bs#>', 22, 23, 'invalid start byte')

Remarque: le décodage bytes vers utf-8 est effectué de manière stricte.

CustomRequestHelper.receive_indexed_request (le service de réception de requête) retourne alors au client :

ParseDataError("CustomTCP._parse_request_part : invalid bloc of data")

Lors de tentatives de réceptions ultérieures, le service identifiera des blocs incomplets qui ne pourront reconstituer une requète intègre, il retournera alors :

ParseDataError("CustomTCP._analyse_list_mixedblocs : can't reconstruct blocs")

En définitive le client retournera un accusé de réception avec pour valeur 0 indiquant une erreur de réception de données.

Au bout de CustomRequestHelper.SEND_MAX_COUNT (15) essais, le serveur appelle BUSINESSComp.NET_signal_send_error (via le mécanisme générique de tâches):

NET_signal_send_error exobj= SatelliteExchangeObject channelname=NET_CHANNEL typeexchange=SEND_ERROR
*msg = gamecmd=CHOOSE_GAME&comuid=lpsvr_gcom1002auc&uid=uid2&listeniveaux=[1- La paix sur terre,2- Quasiment non violent,3- De nouveaux participants,4- Ca se corse,5- Sauve qui peut]&msg_input=Choisissez un numéro de niveau pour commencer à jouer.&msg_input_alt=Choisissez un niveau puis cliquez sur :
- partie (pour jouer)
- démo (pour regarder une partie automatique)&typechoix=CHOOSE_GAME&comuid=lpsvr_gcom1001abs
*confirmrecept = True
*clients = ['uid2']

On remarque que les bytes posant problème côté client sont liés aux caractères
accentués é et à.

Dans cet exemple le composant métier (GameManager de l’application Labpyrinthe) renverra au client d’uid uid2 la commande de jeu CHOOSE_GAME qui finira par être reçue correctement (au bout de 15 puis 4 essais unitaires).

Constructeur : initie le processus de connection

Paramètres
  • server_address (tuple) – (host, port)

  • externalhandler (function) – fonction externe appelée en fin de traitement d’une requète entrante

  • auto_connect (boolean) – connection automatique à l’initialisation, vrai par défaut

Rq: plutôt que externalhandler, utiliser de préférence le mécanisme par défaut de Queues hérité de app_components.

Attributes Summary

uid

identifiant unique du serveur

Methods Summary

allow_new_connections(allow)

Indique si le serveur accepte de nouvelles connections.

check_connections(exobj)

le composant métier demande au composant réseau de vérifier sa / ses connection(s).

connect(exobj)

Ordre de connection à l’adresse pré définie ou à l’adresse éventuellement indiquée dans : exobj.dictargs={« host »:, « port »:}

disconnect(exobj)

Déconnexion du serveur.

dispatch_network_infos()

Envoie au composant Business les infos réseau.

dispatch_network_status(msg)

Informe le composant business de l’état de connection principale (réception).

dispatch_to_external_handler(dictreceive)

Transmission à l’application associée en toute fin du traitement de la requète

do_server_accept_new_connections()

Indique si le serveur accepte de nouvelles connections.

get_network_infos()

Retourne un dictionnaire d’infos sur le serveur et les clients.

handle_indexed_msg(dictreceive)

Méthode de traitement des requètes entrantes.

net_shutdown(exobj)

Ordre de clôture du seul composant réseau.

send(clients, msg[, confirmrecept])

Envoie un message à une liste de clients avec accusé de réception.

sendFromExchangeObject(exobj)

Méthode d’envoi à partir des données comprises dans l’objet NETExchangeObject

server_start_loop()

Méthode run du thread de démarrage du serveur interne.

server_stop_loop()

Méthode run du thread d’arrêt du serveur interne.

set_address(exobj)

Affecte l’adresse d’écoute du serveur / adresse d’écriture du client.

shutdown()

Clôture du composant propagé par APPComp

Attributes Documentation

uid

identifiant unique du serveur

Methods Documentation

allow_new_connections(allow)[source]

Indique si le serveur accepte de nouvelles connections.

Paramètres

allow (boolean) –

check_connections(exobj)[source]

le composant métier demande au composant réseau de vérifier sa / ses connection(s).

Paramètres

exobj (NETExchangeObject) –

connect(exobj)[source]

Ordre de connection à l’adresse pré définie ou à l’adresse éventuellement indiquée dans : exobj.dictargs={« host »:, « port »:}

Paramètres

exobj (appcomp.NETExchangeObject) – objet d’échange

disconnect(exobj)[source]

Déconnexion du serveur.

Paramètres

exobj (appcomp.NETExchangeObject) – objet d’échange

Rq : on conserve self.netdict en cas de reconnection.

dispatch_network_infos()[source]

Envoie au composant Business les infos réseau.

dispatch_network_status(msg)[source]

Informe le composant business de l’état de connection principale (réception).

Paramètres

msg (str) – message d’info

dispatch_to_external_handler(dictreceive)[source]

Transmission à l’application associée en toute fin du traitement de la requète

  • de préférence via le mécanisme de Queues hérité de app_components (via queue_tools)

  • sinon via self.externalhandler en appel direct, s’il est défini

Paramètres

dictreceive (dict) – dict généré par CustomTCPRequestHandler.handle

do_server_accept_new_connections()[source]

Indique si le serveur accepte de nouvelles connections.

Renvoie

boolean

get_network_infos()[source]

Retourne un dictionnaire d’infos sur le serveur et les clients. Détecte les connections probablement interrompues « sauvagement ».

Renvoie

self.netdict

Type renvoyé

dict

handle_indexed_msg(dictreceive)[source]

Méthode de traitement des requètes entrantes.

Paramètres

dictreceive (dict) – dict généré par CustomRequestHelper.receive_indexed_request

Renvoie

{« reply »:Bool, « reponse »:reponse, « return_code »:return_code, « dispatch »:Bool}

Type renvoyé

dict

Reçoit le message complet associé à une requète (méthode appelée par le CustomTCPRequestHandler dans sa méthode handle).

net_shutdown(exobj)[source]

Ordre de clôture du seul composant réseau.

Paramètres

exobj (appcomp.NETExchangeObject) – objet d’échange

Rq : on ne clôt pas le process de gestion de tâches, le serveur est complètement ré initialisé, mais peut être redémarré.

send(clients, msg, confirmrecept=True)[source]

Envoie un message à une liste de clients avec accusé de réception.

Paramètres
  • clients (list) – liste d’uid

  • msg (str) – le message à envoyer

  • confirmrecept (boolean) – doit-t’on s’assurer de la réception du message (oui par défaut)

sendFromExchangeObject(exobj)[source]

Méthode d’envoi à partir des données comprises dans l’objet NETExchangeObject

Paramètres

exobj (appcomp.NETExchangeObject) – objet d’échange

server_start_loop()[source]

Méthode run du thread de démarrage du serveur interne.

server_stop_loop()[source]

Méthode run du thread d’arrêt du serveur interne.

set_address(exobj)[source]

Affecte l’adresse d’écoute du serveur / adresse d’écriture du client.

Paramètres

exobj (appcomp.NETExchangeObject) – objet d’échange avec exobj.dictargs={« host »:, « port »:}

Rq : si host ne pointe pas vers « localhost » (ou «  »), l’ip sera déterminée via CustomRequestHelper.get_ip().

shutdown()[source]

Clôture du composant propagé par APPComp