2011-10-03 22 views
1

这里是我当前的代码:如何使用来自套接字的数据实现webpush?

#!/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的方法。因为我从来没有真正实例化WebPUSH,所以看起来我可以很轻松地调用这个方法。我试图将其转换为使用多服务方法,但似乎没有工作,虽然我确信我做错了什么。

没有(只要我可以谷歌)任何很好的例子在multiservice扭曲或至少这样的一个。

任何帮助将不胜感激。

+1

目前尚不清楚,对我来说,至少,什么你实际上是想在这里完成。看起来你有一个UDP协议,它连接到HTTP实现的一半,并且你对类和实例之间的区别有些困惑。我不明白'MultiService'与什么有关。你想制作一个长轮询的Web服务器吗? – Glyph

回答

0

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() 
0

user970077,e我的博客中的xample是为了展示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 client and server with 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() 
相关问题