2011-10-03 43 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() 
相關問題