Une connection websocket est une connection/liaison double flux (full duplex) entre un client (frontend) et un serveur (backend). Il existe d'autre type de connection full duplex, comme par exemple TCP sockets.
It is a specification to allow synchronous bidirectional communication between a client and a server.
While similar to TCP sockets, it is a protocol that operates as an upgraded HTTP connection, exchanging variable-length frames between the two parties, instead of a stream.
Cette connection double flux utilise une connection http. Plus précisément, le canal websocket est créé dans la connection http.
il n'est pas possible d'utiliser l'outil de développment du navigateur web pour retrouver les reponses du serveur ; c'est assez logique puisque l'outil a été fait pour visualiser une communication http à la base.
Peut être qu'une visu correcte viendra dans les prochaines versions de navigateur web. =⇒ en attendant, il faudra activer un handler sur reception des réponses du backend pour logger ses réponses
Toujours dans ce sens, la mise en oeuvre est effectuée par les techniques suivantes : Streaming (xdr-streaming, iframe-htmlfile, iframe-eventsource) ou Polling http (xhr-polling, iframe-xhr-polling, xdr-polling, ou jsonp-polling)
Voir à la fin de cet article une analyse de trame que j'avais faite pour l'application naza, mais je n'en suis plus vraiment certain.
Plus d'information ici : https://github.com/sockjs/sockjs-client
It defines a protocol for clients and servers to communicate with messaging semantics.
It does not define any implementation details, but rather addresses an easy-to-implement wire protocol for messaging integrations.
It provides higher semantics on top of the WebSockets protocol and defines a handful of frame types that are mapped onto WebSockets frames. Some of these types are :
On se sert des websocket pour mettre en oeuvre des messages broker (agent de messages).
Un agent de messages peut valider, transformer et rediriger les messages. Il agit comme médiateur entre les émetteurs et les récepteurs en leur permettant de communiquer efficacement avec un couplage minimum entre eux.
Principe : Le client peut :
Le backend décide comment traiter le message recu, et quoi en faire ; Il peut :
Il y a donc énormément de possibilités, et le fonctionnement n'a rien avoir le sytème de requete/réponse des appels REST.
Néanmoins, dans spring messaging, des outils ont été prévus pour aller dans le sens d'un mécanisme qui ressemble aux requete/réponse des appels REST ; il s'agit de l'annotation @SendToUser.
Elle permet de mettre en oeuvre les websockets, la communication de base full duplex entre chaque client désirant initier une connection et le backend. Elle permet d'instancier et d'utiliser des objets “Websocket” qui représente une connection websocket avec un serveur backend. On pourrait l'utiliser pour communiquer directement avec le backend.
Elle permet de mettre en oeuvre le protocole STOMP1.1 over websocket. C'est donc une surcouche de la couche websocket
Chercher la classe WebsocketService dans le code angular du projet naza-front ou naza-emulator-front, ainsi que les classes 'services' qui l'utilisent pour mettre en oeuvre les envoies et souscription aux channels.
Chercher les classes suivantes dans le code java du projet naza-core ou naza-emulator-back :
Logiquement, quand le backend met en oeuvre du http (appels rest) et des websocket, alors logiquement les appels rest ont déjà été protégés par une authentification pour les requetes http. Du coup, au moment de la création de la connection websocket, qui commence par la création d'une connection http, à partir de la session http du navigateur, alors le frontend est déjà authentifié (par son cookie JSESSIONID ?). Par conséquent, il n'a rien à faire de plus pour sécuriser les websocket dans ce cas.
Remarque : Dans naza-emulator-back, j'ai ajouté des protection quand même :
Dans le cas où l'on ne souhaite utiliser que les websocket et par de requetes rest, alors il existe des méthodes de sécurisation, comme :
REQ : http://localhost:4201/socket/836/ohfdrc25/xhr_streaming?t=1575375026074
REP :
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
o
a["CONNECTED\nversion:1.1\nheart-beat:0,0\n\n\u0000"]
a["MESSAGE\ndestination:/opcuaserver/arp-pa-link/result\ncontent-type:application/json;charset=UTF-8\nsubscription:sub-5\nmessage-id:ohfdrc25-842976\ncontent-length:481\n\n{\"CASSE\":[\"BELLAP0\",\"BELLAP4\",\"MAUREP0\",\"MAUREP4\",\"SSJUNP0\",\"SSJUNP4\"],\"NIORT\":[\"M.HERP0\",\"M.HERP4\",\"MELLEP0\",\"MELLEP4\",\"NIORTP0\",\"NIORTP4\",\"ROM P0\",\"ROM P4\",\"ROM P7\",\"SSFLOP0\",\"SSFLOP4\",\"SSMAIP0\",\"SSMAIP4\"],\"FLEAC\":[\"CIVRAP0\",\"CIVRAP4\",\"CONF6P0\",\"CONF6P4\",\"COUR P0\",\"COUR P4\",\"FLEACP0\",\"FLEACP4\",\"I.JOUP0\",\"I.JOUP4\",\"LAITIP0\",\"LAITIP4\",\"LONGCP0\",\"LONGCP4\",\"LUSIGP0\",\"LUSIGP4\",\"LUXE P0\",\"LUXE P4\",\"MANSLP0\",\"MANSLP4\",\"MINIEP0\",\"MINIEP4\",\"PAPAUP0\",\"PAPAUP4\",\"POITIP0\",\"POITIP4\"]}\u0000"]
a["MESSAGE\ndestination:/opcuaserver/content/get-all-automatons/result\ncontent-type:application/json;charset=UTF-8\nsubscription:sub-3\nmessage-id:ohfdrc25-842977\ncontent-length:2746\n\n{\"CONF6_AUT8\":{\"name\":\"CONF6_AUT8\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"CONF6_AUT8_AUT_STATE_COMMAND\",\"stateTi\":\"CONF6_AUT8_AUT_STATE\"},\"LONGC_AUT8\":{\"name\":\"LONGC_AUT8\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"LONGC_AUT8_AUT_STATE_COMMAND\",\"stateTi\":\"LONGC_AUT8_AUT_STATE\"},\"LONGC_AUT9\":{\"name\":\"LONGC_AUT9\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"LONGC_AUT9_AUT_STATE_COMMAND\",\"stateTi\":\"LONGC_AUT9_AUT_STATE\"},\"CONF6_AUT9\":{\"name\":\"CONF6_AUT9\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"CONF6_AUT9_AUT_STATE_COMMAND\",\"stateTi\":\"CONF6_AUT9_AUT_STATE\"},\"I.JOU_AUT9\":{\"name\":\"I.JOU_AUT9\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"I.JOU_AUT9_AUT_STATE_COMMAND\",\"stateTi\":\"I.JOU_AUT9_AUT_STATE\"},\"I.JOU_AUT8\":{\"name\":\"I.JOU_AUT8\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"I.JOU_AUT8_AUT_STATE_COMMAND\",\"stateTi\":\"I.JOU_AUT8_AUT_STATE\"},\"NIORT_AUT1\":{\"name\":\"NIORT_AUT1\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"NIORT_AUT1_AUT_STATE_COMMAND\",\"stateTi\":\"NIORT_AUT1_AUT_STATE\"},\"FLEAC_AUT2\":{\"name\":\"FLEAC_AUT2\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"FLEAC_AUT2_AUT_STATE_COMMAND\",\"stateTi\":\"FLEAC_AUT2_AUT_STATE\"},\"BELLA_AUT2\":{\"name\":\"BELLA_AUT2\",\"behaviour\":\"LATE_ANSWER\",\"status\":\"Disactivated\",\"commandTi\":\"BELLA_AUT2_AUT_STATE_COMMAND\",\"stateTi\":\"BELLA_AUT2_AUT_STATE\"},\"NIORT_AUT2\":{\"name\":\"NIORT_AUT2\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"NIORT_AUT2_AUT_STATE_COMMAND\",\"stateTi\":\"NIORT_AUT2_AUT_STATE\"},\"FLEAC_AUT3\":{\"name\":\"FLEAC_AUT3\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"FLEAC_AUT3_AUT_STATE_COMMAND\",\"stateTi\":\"FLEAC_AUT3_AUT_STATE\"},\"BELLA_AUT3\":{\"name\":\"BELLA_AUT3\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"BELLA_AUT3_AUT_STATE_COMMAND\",\"stateTi\":\"BELLA_AUT3_AUT_STATE\"},\"CIVRA_AUT4\":{\"name\":\"CIVRA_AUT4\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"CIVRA_AUT4_AUT_STATE_COMMAND\",\"stateTi\":\"CIVRA_AUT4_AUT_STATE\"},\"SSFLO_AUT1\":{\"name\":\"SSFLO_AUT1\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"SSFLO_AUT1_AUT_STATE_COMMAND\",\"stateTi\":\"SSFLO_AUT1_AUT_STATE\"},\"CIVRA_AUT3\":{\"name\":\"CIVRA_AUT3\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"CIVRA_AUT3_AUT_STATE_COMMAND\",\"stateTi\":\"CIVRA_AUT3_AUT_STATE\"},\"MELLE_AUT9\":{\"name\":\"MELLE_AUT9\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"MELLE_AUT9_AUT_STATE_COMMAND\",\"stateTi\":\"MELLE_AUT9_AUT_STATE\"},\"MELLE_AUT8\":{\"name\":\"MELLE_AUT8\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"MELLE_AUT8_AUT_STATE_COMMAND\",\"stateTi\":\"MELLE_AUT8_AUT_STATE\"},\"SSFLO_AUT2\":{\"name\":\"SSFLO_AUT2\",\"behaviour\":\"OK\",\"status\":\"Disactivated\",\"commandTi\":\"SSFLO_AUT2_AUT_STATE_COMMAND\",\"stateTi\":\"SSFLO_AUT2_AUT_STATE\"}}\u0000"]
a["MESSAGE\ndestination:/opcuaserver/content/get-all-branchState/result\ncontent-type:application/json;charset=UTF-8\nsubscription:sub-4\nmessage-id:ohfdrc25-842978\ncontent-length:3443\n\n{\"A.VOUL41ZPIOU\":{\"branchName\":\"A.VOUL41ZPIOU\",\"connectionState\":\"BOTH_SIDE\"},\"AIGREL41ZVERV\":{\"branchName\":\"AIGREL41ZVERV\",\"connectionState\":\"SIDE_1\"},\"BELLAL41I.JOU\":{\"branchName\":\"BELLAL41I.JOU\",\"connectionState\":\"NO_SIDE\"},\"BELLAL41MAURE\":{\"branchName\":\"BELLAL41MAURE\",\"connectionState\":\"BOTH_SIDE\"},\"BODUTL41CIVRA\":{\"branchName\":\"BODUTL41CIVRA\",\"connectionState\":\"BOTH_SIDE\"},\"BODUTL41LONGC\":{\"branchName\":\"BODUTL41LONGC\",\"connectionState\":\"BOTH_SIDE\"},\"CIVRAL41ZDALI\":{\"branchName\":\"CIVRAL41ZDALI\",\"connectionState\":\"BOTH_SIDE\"},\"CONF6L41LONGC\":{\"branchName\":\"CONF6L41LONGC\",\"connectionState\":\"BOTH_SIDE\"},\"CONF6L41SSJUN\":{\"branchName\":\"CONF6L41SSJUN\",\"connectionState\":\"BOTH_SIDE\"},\"COUR L41LAITI\":{\"branchName\":\"COUR L41LAITI\",\"connectionState\":\"BOTH_SIDE\"},\"COUR L41ZDALI\":{\"branchName\":\"COUR L41ZDALI\",\"connectionState\":\"BOTH_SIDE\"},\"FLEACL41PALAN\":{\"branchName\":\"FLEACL41PALAN\",\"connectionState\":\"BOTH_SIDE\"},\"GOISEL41SSFLO\":{\"branchName\":\"GOISEL41SSFLO\",\"connectionState\":\"BOTH_SIDE\"},\"GOISEL41ZGOIS\":{\"branchName\":\"GOISEL41ZGOIS\",\"connectionState\":\"SIDE_2\"},\"HOUCHL41PAPAU\":{\"branchName\":\"HOUCHL41PAPAU\",\"connectionState\":\"BOTH_SIDE\"},\"HOUCHL41POITI\":{\"branchName\":\"HOUCHL41POITI\",\"connectionState\":\"BOTH_SIDE\"},\"I.JOUL41LAITI\":{\"branchName\":\"I.JOUL41LAITI\",\"connectionState\":\"BOTH_SIDE\"},\"LAITIL41PLAN5\":{\"branchName\":\"LAITIL41PLAN5\",\"connectionState\":\"BOTH_SIDE\"},\"LAITIL41ROM\":{\"branchName\":\"LAITIL41ROM\",\"connectionState\":\"BOTH_SIDE\"},\"LAITIL41ZPIOU\":{\"branchName\":\"LAITIL41ZPIOU\",\"connectionState\":\"BOTH_SIDE\"},\"LONGCL41NAUCL\":{\"branchName\":\"LONGCL41NAUCL\",\"connectionState\":\"BOTH_SIDE\"},\"LONGCL41ZMAGD\":{\"branchName\":\"LONGCL41ZMAGD\",\"connectionState\":\"BOTH_SIDE\"},\"LUSIGL41MINIE\":{\"branchName\":\"LUSIGL41MINIE\",\"connectionState\":\"BOTH_SIDE\"},\"LUSIGL41SSMAI\":{\"branchName\":\"LUSIGL41SSMAI\",\"connectionState\":\"BOTH_SIDE\"},\"LUXE L41ZMANS\":{\"branchName\":\"LUXE L41ZMANS\",\"connectionState\":\"BOTH_SIDE\"},\"LUXE L41ZVERV\":{\"branchName\":\"LUXE L41ZVERV\",\"connectionState\":\"BOTH_SIDE\"},\"M.HERL41SSMAI\":{\"branchName\":\"M.HERL41SSMAI\",\"connectionState\":\"BOTH_SIDE\"},\"MAGDEL41ZMAGD\":{\"branchName\":\"MAGDEL41ZMAGD\",\"connectionState\":\"BOTH_SIDE\"},\"MANSLL41ZMANS\":{\"branchName\":\"MANSLL41ZMANS\",\"connectionState\":\"BOTH_SIDE\"},\"MELLEL41ZGOIS\":{\"branchName\":\"MELLEL41ZGOIS\",\"connectionState\":\"BOTH_SIDE\"},\"MELLEL41ZMAGD\":{\"branchName\":\"MELLEL41ZMAGD\",\"connectionState\":\"BOTH_SIDE\"},\"MINIEL41ZPIOU\":{\"branchName\":\"MINIEL41ZPIOU\",\"connectionState\":\"BOTH_SIDE\"},\"NAUCLL41S.MOU\":{\"branchName\":\"NAUCLL41S.MOU\",\"connectionState\":\"BOTH_SIDE\"},\"NAUCLL41ZMANS\":{\"branchName\":\"NAUCLL41ZMANS\",\"connectionState\":\"BOTH_SIDE\"},\"NIORTL41SSFLO\":{\"branchName\":\"NIORTL41SSFLO\",\"connectionState\":\"BOTH_SIDE\"},\"NIORTL41TREVI\":{\"branchName\":\"NIORTL41TREVI\",\"connectionState\":\"BOTH_SIDE\"},\"NIORTL41ZCHA9\":{\"branchName\":\"NIORTL41ZCHA9\",\"connectionState\":\"BOTH_SIDE\"},\"NIORTL42SSFLO\":{\"branchName\":\"NIORTL42SSFLO\",\"connectionState\":\"BOTH_SIDE\"},\"PALANL41ZVERV\":{\"branchName\":\"PALANL41ZVERV\",\"connectionState\":\"BOTH_SIDE\"},\"PAPAUL41PLAN5\":{\"branchName\":\"PAPAUL41PLAN5\",\"connectionState\":\"BOTH_SIDE\"},\"ROM Y742\":{\"branchName\":\"ROM Y742\",\"connectionState\":\"BOTH_SIDE\"},\"SSFLOL41ZGOIS\":{\"branchName\":\"SSFLOL41ZGOIS\",\"connectionState\":\"BOTH_SIDE\"},\"SSMAIL41ZCHA9\":{\"branchName\":\"SSMAIL41ZCHA9\",\"connectionState\":\"BOTH_SIDE\"},\"SSSAVL41ZDALI\":{\"branchName\":\"SSSAVL41ZDALI\",\"connectionState\":\"BOTH_SIDE\"},\"TREVIL41ZCHA9\":{\"branchName\":\"TREVIL41ZCHA9\",\"connectionState\":\"SIDE_2\"}}\u0000"]
a["MESSAGE\ndestination:/emulatorSettings/result\ncontent-type:application/json;charset=UTF-8\nsubscription:sub-11\nmessage-id:ohfdrc25-842980\ncontent-length:145\n\n{\"lastMeasuresUpdateStr\":\"13:10:23\",\"lastLoadedSnapshot\":\"zone_melle_20190617.xiidm\",\"currentServerSynchronization\":0,\"enableMeasureUpdate\":true}\u0000"]
...
REQ : http://localhost:4201/socket/249/ygt2rpfy/xhr_send?t=1575377978027 REP : Chaine de requete : t:1575375047394 Paramètres : 0 SUBSCRIBE id:sub-0 destination:/app-build-infos/result � 1 SEND destination:/app/app-build-infos � 2 SUBSCRIBE id:sub-1 destination:/opcuaserver/filter/get-all-items/result � 3 SEND destination:/app/opcuaserver/filter/get-all-items � 4 SUBSCRIBE id:sub-2 destination:/opcuaserver/content/get-all-remotedatas/result � 5 SEND destination:/app/opcuaserver/content/get-all-remotedatas � 6 SUBSCRIBE id:sub-3 destination:/opcuaserver/content/get-all-automatons/result � 7 SEND destination:/app/opcuaserver/content/get-all-automatons � 8 SUBSCRIBE id:sub-4 destination:/opcuaserver/content/get-all-branchState/result � 9 SEND destination:/app/opcuaserver/content/get-all-branchState � 10 SUBSCRIBE id:sub-5 destination:/opcuaserver/arp-pa-link/result � ...
⇒ xhr_streaming correspond aux données envoyées par le back sur la socket, pour une des souscriptions effectuées par le client websocket (_websocketService.subscribe( canal de souscription ) Remarque : ces requêtes apparaissent dans le debuggeur de firefox sous la forme de requête. Pourtant, ce sont bien des réponses du backend, envoyées sur un ou plusieurs canaux souscrits par le client.
⇒ xhr_send correspond à tous les envois depuis le frontend vers le backend : ca peut être des demande de souscriptions (SUBSCRIBE) ou des requêtes (SEND)