2017-07-05 3 views
-1

J'ai un serveur socket Web qui se connecte aux clients. Le code suivant est: -Twisted Python - Pousser les données vers la socket Web

from twisted.internet.protocol import Factory 
from twisted.protocols.basic import LineReceiver 
from twisted.internet import reactor 

class Chat(LineReceiver): 

    def __init__(self, users): 
     self.users = users 
     self.name = None 
     self.state = "GETNAME" 

    def connectionMade(self): 
     self.sendLine("What's your name?") 

    def connectionLost(self, reason): 
     if self.users.has_key(self.name): 
      del self.users[self.name] 

    def lineReceived(self, line): 
     if self.state == "GETNAME": 
      self.handle_GETNAME(line) 
     else: 
      self.handle_CHAT(line) 

    def handle_GETNAME(self, name): 
     if self.users.has_key(name): 
      self.sendLine("Name taken, please choose another.") 
      return 
     self.sendLine("Welcome, %s!" % (name,)) 
     self.name = name 
     self.users[name] = self 
     self.state = "CHAT" 

    def handle_CHAT(self, message): 
     # Need to send the message to the connected clients. 


class ChatFactory(Factory): 

    def __init__(self): 
     self.users = {} # maps user names to Chat instances 

    def buildProtocol(self, addr): 
     return Chat(self.users) 


reactor.listenTCP(8123, ChatFactory()) 
reactor.run() 

Les clients se connectent au code ci-dessus (serveur) et envoient les données au serveur.

Maintenant, j'ai un autre script python, fondamentalement un scrapper qui scraps le web, le traite et finalement besoin d'envoyer les données aux clients connectés.

script.py

while True: 
    # call `send_message` function and send data to the connected clients. 

Comment puis-je parvenir ?? Tout exemple serait d'une grande aide !!

MISE À JOUR

After using Autobahn

J'ai un serveur qui va chercher les données de l'API 3ème partie. Je veux envoyer ces données à tous les clients socket Web connectés. Voici mon code: -

class MyServerProtocol(WebSocketServerProtocol): 
    def __init__(self): 
     self.connected_users = [] 
     self.send_data() 

    def onConnect(self, request): 
     print("Client connecting: {0}".format(request.peer)) 

    def onOpen(self): 
     print("WebSocket connection open.") 
     self.connected_users.append(self) # adding users to the connected_list 

    def send_data(self): 
     # fetch data from the API and forward it to the connected_users. 
     for u in self.users: 
      print 1111 
      u.sendMessage('Hello, Some Data from API!', False) 

    def onClose(self, wasClean, code, reason): 
     connected_users.remove(self) # remove user from the connected list of users 
     print("WebSocket connection closed: {0}".format(reason)) 


if __name__ == '__main__': 

    import sys 

    from twisted.python import log 
    from twisted.internet import reactor 

    factory = WebSocketServerFactory(u"ws://127.0.0.1:9000") 
    factory.protocol = MyServerProtocol  

    reactor.listenTCP(9000, factory) 
    reactor.run() 

Mon serveur ne recevra jamais un message ou recevra probablement, mais au moment il n'y a pas de cas d'utilisation, donc pas besoin d'événement OnMessage pour cet exemple).

Comment écrire ma fonction send_data pour envoyer des données à tous mes clients connectés?

+1

Quoi de 'send_message'? Où sont les "websockets"? –

+0

'send_message' sera une fonction via laquelle les données seront transmises aux clients web connectés (sockets)? – PythonEnthusiast

+1

"websockets" est un protocole spécifique - https://en.wikipedia.org/wiki/WebSocket - qui ne semble pas être utilisé dans votre exemple de code. Si vous avez vraiment besoin de WebSockets, jetez un oeil à Autobahn. –

Répondre

0

Vous devez éviter ce modèle lorsque le logiciel écrit avec Twisted:

while True: 
    # call `send_message` function and send data to the connected clients. 

Twisted est un système multi-tâches coopératif. "Coopérative" signifie que vous devez abandonner le contrôle de l'exécution périodiquement afin que les autres tâches aient une chance de s'exécuter.

twisted.internet.task.LoopingCall peut être utilisé pour remplacer un grand nombre while ... boucles (en particulier while True boucles):

from twisted.internet.task import LoopingCall 
LoopingCall(one_iteration).start(iteration_interval) 

Ceci appellera one_iteration toutes iteration_interval secondes. Entre les deux, il abandonnera le contrôle de l'exécution pour que d'autres tâches puissent s'exécuter. Faire one_iterationone_iterationone_iterationone_iterationone_iteration Envoyer un message à un client consiste simplement à donner one_iteration une référence à ce client (ou à ces clients, s'ils sont nombreux).

Ceci est une variante de la FAQ How do I make Input on One Connection Result in Output on Another.

Si vous avez un ChatFactory avec un dict contenant tous vos clients, simplement passer cette usine à one_iteration:

LoopingCall(one_iteration, that_factory) 

ou

LoopingCall(lambda: one_iteration(that_factory)) 
+0

Je pense que vous n'avez pas compris ma question. Permettez-moi de le recadrer un peu. Veuillez voir la question mise à jour. – PythonEnthusiast