Journal Javascript 'push'

Posté par .
Tags : aucun
8
12
nov.
2009
Bonjour les gens,

Juste un petit journal pour présenter une truc qui pourrait intéresser des gens :

J'ai voulu regarder comment faire du push javascript pour jouer un peu (on est d'accord, c'est pas vraiment du push mais on va faire semblant).

Je sais peut être pas faire une recherche sur google, mais je suis tombé que sur des trucs qui ont l'air super compliqués à mettre en place, allant jusqu'à la mise en place d'un nom de domaine pour le système. En plus, à ce que j'ai vu, ce sont les clients eux même qui envoient les choses à envoyer aux autres clients et le serveur peut rien faire. Ça pue.

J'ai donc fait mon propre système de push en javascript avec un nombre minimal de fonctionnalités, mais qui au moins marche (comme je veux) et qui est simple.

Vu qu'apache adore gérer une tétrapétée de connexions ouvertes qui servent à rien, j'ai codé un serveur en python qui tourne sous un autre port et une petite librairie php qui va envoyer les données à envoyer au serveur python qui va les redistribuer aux clients.

Y'a une notion de channel: Un client écoute que sur certains channels et donc reçoit les message que de ceux ci. Le channel 'debug' est réservé.

En pratique :
- Le serveur python attend les clients qui font une requête GET spécialement formatée. La connexion reste ouverte jusqu'à ce que des données pour le client arrivent ou que 25 secondes se sont écoulés.
- Le client fait une requête au serveur python et attend des données. Si tout c'est bien passé (code http 200), il traite les données et recommence.
- Le script qui veut envoyer des données aux clients les envoie dans un paquet udp au serveur python. Donc j'ai fait un truc en php, mais en brainfuck c'est possible aussi.

J'ai la femme de faire un beau schéma mais vous voyez lisez l'idée.

Avantage :
- Apache meurt pas sous une tonne de connexions
- Ça prend 30s à mettre en place
- C'est pas compliqué et légé
- C'est zoli

Problèmes :
- Je sais absolument pas si ça tiens la charge, si quelqu'un a 500 postes pour essayer..
- Ça marche pas avec opera et surement pleins d'autre navigateurs. Fx 3.5 et chrome ça marche donc bon :]

Aussi fou que ça puisse paraitre, ça à marché du premier coup avec mon IE winé. J'ai pas trop compris pourquoi mais bon hein. J'espère que ça marche dans tous les cas (vu que j'étais en local), au pire y'a le plugin google ;)

Petite FAQ:

- Depuis quand c'est possible de faire des requêtes ajax sur un autre port|domaine ?
-- Depuis la création de l'header (entre autres) Access-Control-Allow-Origin.

- Mais c'est pas sécurisé, tout le monde qui envoie un paquet UDP au serveur peut causer aux clients
-- Non. Parce que d'abord iptables, ensuite il y a possibilité de définir un secret partagé entre le script php et le serveur python et enfin on peut changer le port.

- Il se passe quoi si des données arrivent sur un channel alors que le client est entrain de se reconnecter ?
-- Un id du dernier message envoyé est maintenu entre le client et le serveur, si quand le client se reconnecte des messages ont été envoyés pour lui, ils sont automatiquement réenvoyé au client.

- Cool, mais si je veux envoyer des données en push à un seul client sans que les autres puissent écouter ?
-- Le channel 'idclient-unsupersecreptdelamortquitue' devrais faire l'affaire ;)

Tout ça en licence BSD parque pourquoi pas. Une petite capture par ici, toutes les sources par là. Jetez quand même un oeil (mais pas trop loin parque faudra aller le rechercher) dans la source du serveur, y'a 2-3 options.

Si y'a un gros bug que j'ai pas vu y'a mon mail en gros dans les fichiers.

Ha et ça s'appelle ZuperPush. Je vous laisse raler comme d'habitude sur le nom des projets auxquels je participe :]
  • # Cometd ?

    Posté par . Évalué à 3.

    Pour faire du push en JS, j'ai déjà utilisé Cometd qui est assez simple et bien implémenté dans la plupart des langages côté serveur. Est-ce que tu as regardé celui-là ? Si oui, quels avantages/inconvénients par rapport à ta solution ?
    • [^] # Re: Cometd ?

      Posté par . Évalué à 2.

      Simple ?

      http://cometd.org/documentation/primer

      Moi je trouve pas hein, après peut être que ça l'est dans la vrai vie mais c'est super mal expliqué. En plus tu dois avoir JQuery ou dojo si je comprend bien donc..
      • [^] # Re: Cometd ?

        Posté par (page perso) . Évalué à 2.

        je sais que sur cometd ils ont mis en place des mécaniques de pool de thread pour justement pouvoir monter en charge sans écrouler le serveur sous le poids des 10000 process...
        et c'est une de leur force en l'occurence

        Maintenant si c'est pour faire un mini tchat sur un site perso pour 10 personnes, ton implémentation du push devrait convernir parfaitement
  • # BOSH

    Posté par (page perso) . Évalué à 2.

    Juste pour information puisque c'est quelque chose d'un peu similaire, y'a une XEP qui décrit un protocol permettant de faire du dialogue bi-directionnel over HTTP, BOSH:
    http://xmpp.org/extensions/xep-0124.html

    Ce que tu as fait est un peu un sous-ensemble de BOSH puisque ça permet uniquement de faire serveur->client, mais d'un autre côté ça utilise seulement une connection HTTP au lieu de 2.
    • [^] # Re: BOSH

      Posté par . Évalué à 2.

      Ouais mais est ce que c'est du travail de pro ?...

      ---[]
  • # Solutions similaires ?

    Posté par (page perso) . Évalué à 2.

    Comment ZuperPush se positionne par rapport à nginx-http-push-module[1] ou à tornado[2] ?

    [1] : http://pushmodule.slact.net/
    [2] : http://www.tornadoweb.org/
    • [^] # Re: Solutions similaires ?

      Posté par . Évalué à 2.

      Le [1] il te faut Nginx ce qui est pas forcément le cas, le [2] ça semble un serveur complet (après j'avoue, je regarde de loin).

      ZuperPush tu peut l'utiliser sans avoir besoin de dépendance à un serveur particulier et l'intégrer à n'importe quoi. C'est plus un complément à ce que tu veux qu'une solution complète ou un plugin pour un programme particulier.

      Si t'as codé tout ton site en brainfuck avec un serveur custom et que tu veux rajouter du push, ba c'est possible avec mon bête script pyhton qui tourne à coté, t'as rien d'autre à faire =)
      • [^] # Re: Solutions similaires ?

        Posté par (page perso) . Évalué à 2.

        Merci pour ta réponse. Je comprends mieux comment se positionne ZuperPush.

        Pour info, tu aurais pu utiliser Tornado, qui est un framework web en Python qui convient bien pour ce genre d'utilisation. Ça t'aurait peut-être permis de gagner du temps.
  • # Push ?

    Posté par . Évalué à 2.

    Tu peux m'expliquer ce que tu veux faire ?

    Tu veux pouvoir envoyer des informations au client (un navigateur potentiellement) depuis le serveur ?
    • [^] # Re: Push ?

      Posté par (page perso) . Évalué à 3.

      Le push c'est quand le serveur envoie des données à un client quand elle sont disponible.
      Le pull (la méthode la plus répandue) c'est quand le client demande des donnée au serveur.

      Ce qu'il veut faire, je pense, c'est "singer" du pull, puisque le protocole HTTP (qu'on me corrige si je me trompe) ne permet pas directement le push. En gros il veut un système ou le client ouvre une connexion, et quand les données sont dispos, le serveur les pousse dans la connexion. Éventuellement, il ne ferme pas la connexion pour pouvoir pousser d'autres données par la suite quand elles seront dispos.
      • [^] # Re: Push ?

        Posté par . Évalué à 3.

        Exactement. Le protocole http c'est de la forme "client qui dit bonjour au serveur, serveur qui répond, stop". Si tu as un client email, ça fait que tu dois aller demander au serveur toutes les minutes si y'a des nouveaux mail et tu as une marge de quelques secondes à une minute avant d'être informé. Le push c'est quand c'est le serveur qui se connecte lui même au client et lui dit "surprise, t'as un mail" dans la microseconde ou il est arrivé. Mais vu qu'on est toujours en HTTP et que c'est pas prévu pour fonctionner comme ça, il faut tricher un peut comme expliqué en dessus :)
        • [^] # Re: Push ?

          Posté par . Évalué à 2.

          C'est exactement ce que j'ai fais il y peu.

          Un demon qui tourne en "tache de fond" coté JavaScript et qui rapatrie les infos sous formes XML.

          Le temps de rapatriement depend de :
          1°/ l'activité du client, plus il est actif, plus le rafrachissement est fréquent, sinon, il se mets en "veille"
          2°/ de la charge serveur

          Et ensuite, selon le XML retourné, plusieurs partie du logiciel javascript sont mis à jour ou pas.

          Quand une action est effectué, genre "envoyer un message", ça le fait a travers le demon et du coup ça mets tout à jour.


          JavaScript, ça déchire :)
  • # Projet similaire

    Posté par . Évalué à 3.

    J'avais fait un truc similaire mais en Erlang pour la partie serveur. Couplé à la base de données Mnesia cela permet d'écouter les évènements de la base, insertion ou suppression de tuples par exemple et de reporter les évènements directement au client (navigateur).

    Le bousin (adresse de preprod pour faire n'importe quoi) : http://www.euphorik.ch:8090
    Le code : http://dev.euphorik.ch/repositories/browse/euk/tags/1.1.6
  • # J'ai la femme de faire un beau schéma

    Posté par (page perso) . Évalué à 4.

    J'ai la femme de faire un beau schéma

    Tu veux dire que est occupé avec ta compagne et qu'en conséquence de quoi tu n'as pas le temps de faire du dessin ?

    Bon d'accord .... ---> [x]

    Alexandre COLLIGNON

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.