Как мне получить веб-пуш с данными, поступающими из сокета? - PullRequest
1 голос
/ 04 октября 2011

Вот мой текущий код:

#!/usr/bin/env python
from twisted.application import internet, service
from twisted.application.service import IServiceMaker, MultiService
from twisted.protocols import basic
from twisted.internet  import reactor, protocol, defer
from twisted.internet.protocol import DatagramProtocol
import datetime

class WebPUSH(basic.LineReceiver):
    logTemplate = '''
      <script type="text/javascript">
         pushHandler.addLi('%s')
      </script>
    '''
    def __init__(self):
        self.gotRequest = False

    def lineReceived(self, line):
        if not self.gotRequest:
            self.startResponse()
            self.gotRequest = True

    def startResponse(self):
        self.sendLine('HTTP/1.1 200 OK')
        self.sendLine('Content-Type: text/html; charset=utf-8')
        self.sendLine('')
        f = open('index.html', 'r')
        self.transport.write( ''.join(f.read()) )
        f.close()
        self.logTime()

    def logTime(self):
        self.sendLine( self.logTemplate % datetime.datetime.now() )
        #reactor.callLater(2, self.logTime)

class Echo(DatagramProtocol):

    def datagramReceived(self, data, (host, port)):
        WebPUSH.logTime()
        print "received %r from %s:%d" % (data, host, port)
        self.transport.write(data, (host, port))

if __name__ == '__main__':    
    f = protocol.ServerFactory()
    f.protocol = WebPUSH
    reactor.listenTCP(8080, f)
    reactor.listenUDP(9999, Echo())

    reactor.run()

Как видите, я пытаюсь вызвать метод в WebPUSH из Echo при получении данных.Поскольку я никогда не создаю экземпляр WebPUSH, похоже, я не могу легко вызвать этот метод.Я попытался преобразовать это, чтобы использовать мультисервисный метод, но это, похоже, не сработало, хотя я уверен, что я делаю что-то не так.с искривленным или хотя бы одним таким.

Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 30 августа 2012

user970077, пример в моем блоге должен был быть упрощенной демонстрацией, чтобы показать, как работает webpush. Вот что вы пытаетесь сделать (включая предложения JFB):

#!/usr/bin/env python
from twisted.protocols import basic
from twisted.internet  import reactor, protocol, defer
import datetime

class WebPUSH(basic.LineReceiver):
    logTemplate = '''
      <script type="text/javascript">
         pushHandler.addLi('%s')
      </script>
    '''    
    def connectionMade(self):
       self.factory.listeners.append(self)
       self.startResponse()

    def connectionLost(self, reason):
        self.factory.listeners.remove(self)

    def lineReceived(self, line):
        self.sendLine( self.logTemplate % line )

    def startResponse(self):
        self.sendLine('HTTP/1.1 200 OK')
        self.sendLine('Content-Type: text/html; charset=utf-8')
        self.sendLine('')
        with open('index.html', 'r') as f:
            self.transport.write( ''.join(f.read()) )


class WebPushFactory(protocol.ServerFactory):

    protocol = WebPUSH

    def __init__(self):
        self.listeners = []


class Echo(protocol.DatagramProtocol):

    def __init__(self, listeners):
        self.listeners = listeners

    def datagramReceived(self, data, (host, port)):
        msg = '[%s:%s] %s' % (host, port, data)
        for listener in self.listeners:
            # udp is not necessarily line-oriented
            # so we can:
            # 1) feed dataReceived and wait until the line
            # delimiter arrives in an udp package 
            # triggering lineReceived:
            #listener.dataReceived( msg  )
            # or 2) fake a line by calling lineReceived direclty:
            listener.lineReceived( msg )

        print msg
        self.transport.write(data, (host, port))

if __name__ == '__main__':
    web = WebPushFactory()
    reactor.listenTCP(8080, web)
    reactor.listenUDP(9999, Echo(web.listeners))

    reactor.run() 

И клиент для его проверки (взят из UDP-клиент и сервер с Twisted Python ):

#!/usr/bin/env python
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
import sys, time

class HeartbeatSender(DatagramProtocol):
    def __init__(self, name, host, port):
        self.name = name
        self.loopObj = None
        self.host = host
        self.port = port

    def startProtocol(self):
        # Called when transport is connected
        # I am ready to send heart beats
        self.loopObj = LoopingCall(self.sendHeartBeat)
        self.loopObj.start(2, now=False)

    def stopProtocol(self):
        "Called after all transport is teared down"
        pass

    def datagramReceived(self, data, (host, port)):
        print "received %r from %s:%d" % (data, host, port)


    def sendHeartBeat(self):
        self.transport.write(self.name, (self.host, self.port))


if __name__ == '__main__':
    sender = HeartbeatSender("sender", "127.0.0.1", 9999)
    reactor.listenMulticast(9998, sender, listenMultiple=True)
    reactor.run()
0 голосов
/ 09 октября 2011

Echo экземпляру нужен экземпляр протокола WebPUSH для вызова .logTime().

Вам необходимо вести список loggers, например, в main():

...
f.loggers = []
echo = Echo()
echo.loggers = f.loggers
...

Добавьте к этому в WebPUSH.connectionMade, удалите в WebPUSH.connectionLost:

def connectionMade(self):
    self.factory.loggers.append(self)

def connectionLost(self, reason):
    self.factory.loggers.remove(self)

, затем в Echo.datagramReceived:

for time_logger in self.loggers:
    time_logger.logTime()
...