===== Concept ===== ==== Websocket ==== 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.\\ - Dans le sens client --> serveur, on peut voir les requetes dans la section requete/réponse de l'outil de développment du webbrowser. (les souscription a des canaux (STOMP 'SUBSCRIBE' messages), ou les envoies de messages (STOMP 'SEND' messages)) \\ - Dans l'autre sens, server --> client : 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 ==== STOMP ==== 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 : * connect * subscribe * unsubscribe * send (messages sent to the server) * message (for messages send from the server) BEGIN, COMMIT, ROLLBACK (transaction management) ==== Utilisation ==== 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 : - souscrire à des channels pour recevoir les messages provenants du backend (envoyés symboliquement sur ce channel) - envoyer des messages au backend sur channel donné Le backend décide comment traiter le message recu, et quoi en faire ; Il peut : * ne rien faire du tout du message * le redistribuer à tous les autres clients ayant souscrit au même channel * transformer les message et l'envoyer sur un autre channel (à tous les clients qui y ont souscrit à l'instant t) * relayer le message à une queue de traitement qui le renverra enrichi/transformé, pour ensuite renvoyer le message sur un channel que des clients écoutent (ont souscript). * A tout moment, de manière complètement indépendante du front, décider d'envoyer des messages sur un channels (pour notifier l'ensemble des clients qui l'écoutent). 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. ===== Mise en oeuvre dans naza : 2 librairies ===== ==== Coté front ==== === Librairie sockjs === 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. === Librairie stomp === Elle permet de mettre en oeuvre le protocole STOMP1.1 over websocket. C'est donc une surcouche de la couche websocket === Exemple d'utilisation === 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. ==== Coté backend ==== Chercher les classes suivantes dans le code java du projet naza-core ou naza-emulator-back : * WebSocketConfiguration * CommonWebSocketController * WebSocketWriterImpl ===== Sécurisation/Protection d'accès ===== ==== besoin de protection rest et websocket ==== 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 : - Au moment de la création de la connection de la websocket, avec la classe *HttpHandshakeInterceptor* - A chaque réception de message d'un client frontend (type SEND) : NazaWsInboundChannelInterceptor.isUserAuthorizationTokenValid() ; Je dis au frontend d'envoyer le token d'authentification envoyé dans le header Authorization pour les appels rest. ==== utilisation de websocket uniquement ==== 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 : https://github.com/spring-projects/spring-framework/blob/master/src/docs/asciidoc/web/websocket.adoc#token-authentication ===== Etude des échanges websocket/stomp à partir de F12 dans le navigateur firefox ===== 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)