2010-10-19 4 views
1

Je commence tout juste à jouer avec Node.js aujourd'hui, et j'ai pensé que je commencerais par ce que je pensais être un simple script: Connexion à un serveur via des sockets, et envoyer un peu de données, et le recevoir en retour. Je crée un utilitaire de ligne de commande. Rien dans le navigateur. Un exemple de serveur serait memcached, beanstalkd, etc. Il semble que le module net soit l'outil approprié pour le travail, mais je suis encore un peu flou sur la manière de faire les choses. De l'aide serait appréciée.Node.js: Connexion à un serveur à l'aide de sockets

Mise à jour # 1

Permettez-moi de voir si je peux le décomposer en en quelques petites questions. Je déteste même poser des questions comme celle-ci, mais la documentation de Node.js est très clairsemée, et la plupart de la documentation écrite il y a 6 mois est déjà périmée.

1) Je peux donc utiliser net.stream.write() pour envoyer des données au serveur distant, mais je ne sais pas comment récupérer une réponse. Je ne suis même pas sûr de savoir comment tester quand write() est fini, car il ne prend pas de callback.

2) Quelques indices sur le fonctionnement de l'événement event.emit seraient excellents. Je pense que c'est vraiment la pierre clé qui me manque dans tout ça.

Mise à jour # 2

est ici où je suis encore confus sur la mise en œuvre d'un programme client. Permettez-moi de schématiser une demande d'envoi type => obtenir un système de réponse:

1) Je lie les rappels au module réseau pour obtenir des réponses et d'autres événements, y compris les liens nécessaires pour obtenir une réponse du serveur.

2) J'utilise stream.write() pour envoyer une requête au serveur.

3) Je ne fais rien alors, car mon événement "data" lié recevra la réponse du serveur.

Voici où les choses deviennent difficiles. Supposons que j'appelle stream.write() deux fois avant que mon événement "data" lié soit appelé. Maintenant j'ai un problème. Lorsque l'événement "data" se produit, comment puis-je savoir laquelle des 2 requêtes est une réponse? Ai-je la garantie que les réponses se dérouleront dans le même ordre que les demandes? Que faire si les réponses reviennent dans un ordre différent?

+0

Ne pas avoir beaucoup de temps ATM mais net. http://nodejs.org/api.html horloge sur 'net.Server' dans la barre latérale. Voilà. Tout est basé sur un événement, vous devez écouter l'événement 'data' du flux. L'exemple est en fait un serveur d'écho de base moins. Je peux faire d'autres exemples pour vous plus tard si vous le souhaitez. –

+0

Dans les cas où il est important que vous sachiez sur quelle 'write' le client a répondu, vous devriez probablement ajouter un ID ou quelque chose de similaire aux données que vous envoyez/recevez. Mais c'est un problème général avec le réseautage et cela n'a rien à voir avec l'approche basée sur les événements. –

Répondre

8

Tout d'abord, clarifions ce qu'est un EventEmitter. JavaScript et donc Node.js sont asynchronous. Cela signifie que, au lieu de devoir attendre les connexions entrantes sur un objet serveur, vous ajoutez un listener à l'objet et lui transmettez un callback function qui, «dès que» l'événement se produit, est exécuté.

Il y a encore des choses qui attendent ici et là en arrière-plan, mais cela a été fait abstraction de vous.

Jetons un coup d'oeil à cet exemple simple:

// #1) create a new server object, and pass it a function as the callback 
var server = net.createServer(function (stream) { 


    // #2) register a callback for the 'connect' event 
    stream.on('connect', function() { 
     stream.write('hello\r\n'); // as 
    }); 


    // #3) register a callback for the 'data' event 
    stream.on('data', function (data) { 
     stream.write(data); 
    }); 

    // #4) register a callback for the 'end' event 
    stream.on('end', function() { 
     stream.write('goodbye\r\n'); 
     stream.end(); 
    }); 
}); 

// #5) make the server listen on localhost:8124 
server.listen(8124, 'localhost'); 

Nous créons donc le serveur et le transmettre la callback function, cette fonction n'a pas encore été exécutée. Passer la fonction ici est essentiellement un raccourci pour ajouter un écouteur pour l'événement connection de l'objet serveur. Après cela, nous démarrons le serveur au #5.

Maintenant, que se passe-t-il dans le cas d'une connexion entrante?

  1. Puisque la fonction nous avons passé à createServer était lié à l'événement connection, il devient maintenant exécuté.

  2. Il ajoute les connect, data et à la stream objectend écouteurs d'événements (qui représente la connexion individuelle) en raccordant callbacks pour les événements.

  3. Après cela, le stream déclenche l'événement connect donc la fonction passée à #2 est exécuté et écrit hello\r\n au courant. Comment la fonction sait-elle quel flux elle doit écrire? Closures sont la réponse, la fonction hérite de la portée dans laquelle elle a été créée, donc à l'intérieur de la fonction stream se réfère toujours à la connexion individuelle qui a déclenché ce rappel même que nous sommes en ce moment. Maintenant, le client

  4. envoie des données sur la connexion, ce qui rend l'appel de son événement data objet stream, puisque nous avons lié une fonction à cet événement à #3 nous maintenant écho les données entrantes au client. Si le client ferme la connexion, la fonction que nous avons liée à #4 est appelée, ce qui écrit goodbye\r\n et ferme ensuite la connexion de notre côté.

Est-ce que cela rend les choses un peu plus claires? Eh bien, cela rend le tout plus facile. Node est, tout comme JavaScript est dans les navigateurs, single threaded. Il n'y a qu'une chose qui se passe à un moment donné.

Décrire simple, tous ces fin callbacks dans une file d'attente globale et sont alors appelés l'un après l'autre, de sorte que cette file d'attente peut (abstraire) ressembler à ceci:

| connection event for a new stream 
| data event for stream #12 
| callback set via setTimeout 
v close event of yet another stream 

Ceux-ci sont sont exécutées en haut maintenant Au fond, rien n'arrivera jamais entre ceux-ci. Il n'y a aucune chance, que pendant que vous faites quelque chose dans le callback lié à l'événement data, quelque chose va se passer et changera magiquement l'état du système. Même s'il y a une nouvelle connexion entrante sur le serveur, son événement sera mis en file d'attente et il devra attendre que tout ce qui précède, y compris l'événement data dans lequel vous vous trouvez, se termine.

+0

Merci pour ce bon exemple Ivo. Y a-t-il une chance de me montrer une implémentation client? Ou me pointant vers un? J'ai examiné le module node-memcache pour obtenir de l'aide, mais le modèle piloté par les événements rend les choses un peu folles. Par exemple, vous n'écrivez pas sur le serveur et attendez une réponse. Vous écrivez au serveur, et ne faites rien. À un moment donné, le serveur répondra, et l'un de vos écouteurs d'événements l'attrape.Mais il semble que vous deviez trouver des solutions créatives pour gérer cette méthodologie. – mellowsoon

+0

Si vous souhaitez établir une connexion à un serveur à partir du nœud interne, alors checkout 'net.Stream' et' net.createConnection' qui vous permettent d'établir une connexion unique. Cette connexion a alors des événements similaires, comme l'objet 'stream 'que vous obtenez une fois que quelqu'un se connecte au serveur dans mon exemple. –

+0

J'accepte votre réponse, parce que c'est une réponse claire, et je ne veux plus perdre votre temps à m'aider avec ça. Mais j'ai mis à jour ma question pour refléter quelques domaines que je suis encore confus. Merci encore! – mellowsoon

Questions connexes