IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langages fonctionnels Discussion :

[Erlang][session_remotly_closed] requêtes http multiples


Sujet :

Langages fonctionnels

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 97
    Par défaut [Erlang][session_remotly_closed] requêtes http multiples
    Bonjour,

    J'ai un petit souci depuis quelques temps avec ceci :
    J'ai un petit serveur http tout bidon, qui renvoie la requête qu'il reçoit...

    Quand je lui envoie une requête solo, ça fonctionne.
    Quand je lui envoie plusieurs requêtes à la suite, ça fonctionne plus.
    Quand je lui envoie plusieurs requêtes à la suite, mais séparées par d'autres instructions : ça fonctionne...

    On a été plusieurs à se pencher sur le problème, mais on n'a rien trouvé.
    Donc voilà le code du serveur :
    fichier : serveur_http_simple.erl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    -module(serveur_http_simple).
    -compile(export_all).
    
    start(Port) ->
    	spawn(fun() -> ouvreConnexionEcoute(Port) end).
    
    ouvreConnexionEcoute(Port) ->
    	{ok, SocketListener} = gen_tcp:listen(Port, [{reuseaddr, true}, {active, true}]),
    	spawn(fun() -> attenteConnexion(SocketListener) end),
    	attenteEvenement(SocketListener).
    
    attenteConnexion(SocketListener) ->
    	case  gen_tcp:accept(SocketListener) of
    		{ok, Socket} ->
    			spawn(fun()-> attenteConnexion(SocketListener) end),
    			inet:setopts(Socket, [{nodelay,true},{active,true}]),
    			traiteRequete(Socket),
    			gen_tcp:close(Socket);
    		{error, MsgErreur} ->
    			io:format("Erreur de connexion ~p~n",[MsgErreur])
    	end.
    
    traiteRequete(Socket) ->
    	receive
    		{tcp,Socket,Message} -> 
    			[_Get,Uri|_Reste] = string:tokens(Message," "),
    			io:format("Le serveur HTTP a recu via la socket ~p~n", [Message]),
    			repondHttpAvecCookie(Socket, Uri, "set-cookie:call_uid=12023.BENCHEUR_ERL; Path=/\r\n")
    	end.
    
    repondHttpAvecCookie(Socket,Message,Cookie) ->
    	Reponse = "HTTP/1.1 200 OK\r\nContent-Length:"++ integer_to_list(string:len(Message)) ++ "\r\nContent-Type: text/txt\r\n"++Cookie++"\r\n"++Message ++"\r\n",
    	gen_tcp:send(Socket, Reponse).
    
    stop(Pid) ->
    	io:format("Fermeture serveur http~n"),
    	Pid!stop.
    
    attenteEvenement(SocketListener) ->
    	receive
    		stop ->
    			gen_tcp:close(SocketListener),
    			exit;
    		_ ->
    			attenteEvenement(SocketListener)
            end.


    Et voilà le code tout simple qui fait foirer le tout.
    fichier : requetes_http_multiples.erl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    -module(requetes_http_multiples).
    -compile(export_all).
    
    requetes_multiples_ok(Requete) ->
      http:request(Requete),
      timer:sleep(10),
      http:request(Requete),
      timer:sleep(10),
      http:request(Requete),
      timer:sleep(10),
      http:request(Requete),
      timer:sleep(10),
      http:request(Requete).
    
    requetes_multiples_pasok(Requete) ->
      http:request(Requete),
      http:request(Requete).

    On a essayé avec plusieurs versions d'erlang, rien à faire.

    Dans le shell erlang :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Inets = inets:start().
    c(requetes_http_multiples).
    c(serveur_http_simple).
    Serveur = serveur_http_simple:start(12345).
    ça fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    requetes_http_multiples:requetes_multiples_ok("http://localhost:12345/coucou").

    ça plante à la deuxième :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    requetes_http_multiples:requetes_multiples_pasok("http://localhost:12345/coucou").

    L'erreur qui remonte est : session_remotly_closed...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    =ERROR REPORT==== 4-Jul-2008::17:33:58 ===
    ** Generic server <0.75.0> terminating 
    ** Last message in was {tcp_closed,#Port<0.169>}
    ** When Server state == {state,
                                {request,#Ref<0.0.0.266>,<0.31.0>,0,http,
                                    {"localhost",12345},
                                    "/coucou",[],get,
                                    {http_request_h,undefined,"keep-alive",
                                        undefined,undefined,undefined,undefined,
                                        undefined,undefined,undefined,undefined,
                                        undefined,undefined,undefined,undefined,
                                        undefined,undefined,"localhost",undefined,
                                        undefined,undefined,undefined,undefined,
                                        undefined,undefined,undefined,undefined,
                                        [],undefined,undefined,undefined,
                                        undefined,"0",undefined,undefined,
                                        undefined,undefined,undefined,undefined,
                                        []},
                                    {[],[]},
                                    {http_options,"HTTP/1.1",infinity,true,[],
                                        undefined,false},
                                    "http://localhost:12345/coucou",[],none,[]},
                                {tcp_session,
                                    {{"localhost",12345},<0.75.0>},
                                    false,http,#Port<0.169>,1},
                                undefined,undefined,undefined,
                                {httpc_response,parse,[nolimit,false]},
                                {[],[]},
                                pipeline,[],nolimit,nolimit,
                                {options,
                                    {undefined,[]},
                                    0,2,2,disabled,enabled,false},
                                {timers,[],undefined},
                                httpc_manager,undefined}
    ** Reason for termination == 
    ** session_remotly_closed



    Si quelqu'un peut m'aider.

    Merci d'avance.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Par défaut
    J'ai jamais fait de erlang, mais je dirais que tu peux essayer avec {reuseaddr, false} (où alors faire récursivement une boucle dans traiteRequte, mais bon).

  3. #3
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 97
    Par défaut
    Désolé, mais ça ne marche pas.

    Merci quand même

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Par défaut
    Je viens d'installer erlang pour tester, et chez moi, ceci marche :
    Code erlang : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    traiteRequete(Socket) ->
            receive
                    {tcp,Socket,Message} -> 
                            [_Get,Uri|_Reste] = string:tokens(Message," "),
                            io:format("Le serveur HTTP a recu via la socket ~p~n", [Message]),
                            repondHttpAvecCookie(Socket, Uri, "set-cookie:call_uid=12023.BENCHEUR_ERL; Path=/\r\n"),
    			traiteRequete(Socket)
            end.

    Ceci dit, c'est peut-être une boucle infinie, et je ne sais pas comment on est censé gérer ce genre de chose. En rajoutant une gestion du message stop ?

  5. #5
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2005
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2005
    Messages : 97
    Par défaut
    D'accord, c'est bizarre que ça marche, mais bon. ^^

    Par contre, c'est sur le principe que je suis pas trop d'accord.
    Une socket, elle est censée être fermée à la fin de la requête, or là elle reste ouverte pour toutes les requêtes.

    C'est assez bizarre.
    Mais si ça marche et que je trouve rien d'autre, je pense que je vais me pencher vers cette solution.
    Merci beaucoup, je teste ça

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 36
    Par défaut
    Arf dommage j'ai pas trop le temps de répondre en profondeur, mais zieute du côté de OTP, qui aide à encapsuler différents comportement, comme le comportement d'un serveur, et qui permet de mettre ça en place sans trop se prendre la tête

    Pour ce qui est de la gestion des socket en Erlang, quand il sont en active ils envoient normalement un message de la forme {tcp_closed, Socket} quand ils meurent, et on peut changer le possesseur d'un socket via gen_tcp:controlling_process, ce qui permet de transferer la gestion du socket à un fils fraichement spawné par exemple.

    Si t'as encore des problèmes demain je repasserai

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requête HTTP multiples et Apache
    Par Invité dans le forum Apache
    Réponses: 2
    Dernier message: 16/02/2007, 21h39
  2. [Struts] Ecouter des requêtes HTTP
    Par ledruide dans le forum Struts 1
    Réponses: 16
    Dernier message: 01/12/2005, 11h53
  3. Intercepter les requêtes HTTP et les modifier.
    Par Alexandre T dans le forum Général Conception Web
    Réponses: 3
    Dernier message: 21/09/2005, 19h25
  4. Requête HTTP
    Par hogan dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 15/07/2005, 18h44
  5. [HTTP]Créer une requête http multipart/related
    Par jothi35 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 05/04/2005, 15h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo