2009-05-07 6 views
0

Je suis en train d'écrire une application Web dans laquelle je dois transférer des données du serveur vers les clients connectés. Ces données peuvent être envoyées à partir de n'importe quel autre script à partir d'une application Web. Par exemple, un utilisateur apporte des modifications sur le serveur et les autres utilisateurs doivent être avertis à ce sujet.Filetage du serveur TCP en tant que proxy entre l'utilisateur connecté et le socket unix

Donc, mon idée est d'utiliser le socket unix (chemin vers la prise en fonction de #ID utilisateur) pour envoyer des données pour l'utilisateur correspondant (scripts d'applications Web se connecte à cette prise et écrire des données). La deuxième partie est ThreadingTCPServer qui acceptera les connexions utilisateur et transmettra les données du socket unix à l'utilisateur via la connexion TCP.

Voici le flux de travail:

  1. occasion se connecter au serveur TCP
  2. Django scénario unixsocket ouvert et écrire des données.
  3. TCP Server lit les données du socket unix et les envoie pour ouvrir la connexion avec l'utilisateur.

J'espère que vous comprenez mon idée :)

Donc, j'ai 2 questions:

1.Quels pensez-vous de mon idée en général? Est-ce une bonne ou une mauvaise solution? Toutes les recommandations sont les bienvenues.

2.Voici mon code.

import SocketServer 
import socket 
import netstring 
import sys, os, os.path 
import string 
import time 

class MyRequestHandler(SocketServer.BaseRequestHandler): 
    def handle(self): 
     try: 
      print "Connected:", self.client_address 

      user = self.request.recv(1024).strip().split(":")[1] 
      user = int(user) 
      self.request.send('Welcome #%s' % user) 

      self.usocket_path = '/tmp/u%s.sock' % user 
      if os.path.exists(self.usocket_path): 
       os.remove(self.usocket_path) 

      self.usocket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) 
      self.usocket.bind(self.usocket_path) 
      self.usocket.listen(1) 

      while 1: 
       usocket_conn, addr = self.usocket.accept() 
       while 1: 
        data = usocket_conn.recv(1024) 
        if not data: break 
        self.request.send(data) 
        break 
       usocket_conn.close() 
       time.sleep(0.1) 

     except KeyboardInterrupt: 
      self.request.send('close') 
      self.request.close() 

myServer = SocketServer.ThreadingTCPServer(('', 8081), MyRequestHandler) 
myServer.serve_forever() 

et je suis une exception

File "server1.py", line 23, in handle 
    self.usocket.listen(1) 
    File "<string>", line 1, in listen 
error: (102, 'Operation not supported on socket') 
+0

La deuxième question a été résolue. socket.SOCK_STREAM doit être utilisé à la place de socket.SOCK_DGRAM dans le socket UNIX. –

Répondre

1

Je pense que vous ne devriez pas utiliser les sockets unix. Si votre application devient (un jour) populaire ou critique, vous ne pourrez pas ajouter un autre serveur pour ajouter de l'évolutivité ou pour le rendre redondant et à sécurité intégrée.

Si, d'autre part, vous mettrez les données dans F.E. memcached (et le "dataset number" de l'utilisateur en tant que clé séparée) Vous pouvez mettre des données dans memcached à partir de plusieurs serveurs et les lire depuis plusieurs serveurs. Si l'utilisateur se déconnecte et se reconnecte à partir d'un autre serveur, vous pourrez toujours obtenir les données pour lui. Vous pouvez également utiliser une base de données (pour le rendre plus sûr), ou un mélange de base de données et memcached si vous le souhaitez, mais j'ai vu une application utilisant des sockets unix de la manière que vous essayez, et la programmeur regretté plus tard. La table peut contenir des colonnes userid, data et timestamp et vous pouvez vous souvenir du dernier horodatage de l'utilisateur donné.

+0

Le nombre maximum d'utilisateurs connectés est, disons, de 1000 utilisateurs en même temps. Je pense que ce n'est pas tellement qu'un serveur gère 1000 connexions. La base de données est utilisée pour cela, bien sûr. Merci pour la solution memcached, je vais y réfléchir .. mais je ne sais pas s'il est possible d '"écouter" de nouvelles données au lieu de les enregistrer toutes les secondes par exemple. –

+0

Avez-vous vraiment, vraiment besoin des données instantanément? Dans la plupart des cas, vous ne le faites pas. Je l'admets, parfois, mais pas aussi souvent que les gens le pensent. BTW: Vous pouvez obtenir plus de 1000 sockets ouverts si vous augmentez ulimit. –

0

C'est trop complexe. Utilisez le module socketserver, s'il vous plaît.

+0

myServer = SocketServer.ThreadingTCPServer (('', 8081), MyRequestHandler) est-il pas? –

+0

C'est ce que http://docs.python.org/library/socketserver.html # asynchronous-mixins dit –

0

Vous devez utiliser Twisted, ou, plus précisément, Orbited, de pousser des données à vos clients. L'exemple de code que vous avez publié comporte un certain nombre de problèmes potentiels, et il serait beaucoup plus difficile de déterminer ce qu'ils sont tous que de simplement utiliser un code prédéfini pour faire ce dont vous avez besoin.

Questions connexes