編程向?qū)?.10集成其他框架
在Kivy內(nèi)部使用Twisted框架
gthank:Twisted是用Python實(shí)現(xiàn)的基于事件驅(qū)動(dòng)的網(wǎng)絡(luò)引擎框架。Twisted誕生于2000年初,在當(dāng)時(shí)的網(wǎng)絡(luò)游戲開發(fā)者看來(lái)亦歉,無(wú)論他們使用哪種語(yǔ)言恤浪,手中都鮮有可兼顧擴(kuò)展性及跨平臺(tái)的網(wǎng)絡(luò)庫(kù)。Twisted的作者試圖在當(dāng)時(shí)現(xiàn)有的環(huán)境下開發(fā)游戲肴楷,這一步走的非常艱難水由,他們迫切地需要一個(gè)可擴(kuò)展性高、基于事件驅(qū)動(dòng)赛蔫、跨平臺(tái)的網(wǎng)絡(luò)開發(fā)框架砂客,為此他們決定自己實(shí)現(xiàn)一個(gè),并從那些之前的游戲和網(wǎng)絡(luò)應(yīng)用程序的開發(fā)者中學(xué)習(xí)呵恢,汲取他們的經(jīng)驗(yàn)教訓(xùn)鞠值。Twisted支持許多常見的傳輸及應(yīng)用層協(xié)議,包括TCP渗钉、UDP彤恶、SSL/TLS、HTTP晌姚、IMAP粤剧、SSH、IRC以及FTP挥唠。Twisted對(duì)于其支持的所有協(xié)議都帶有客戶端和服務(wù)器實(shí)現(xiàn)抵恋,同時(shí)附帶有基于命令行的工具,使得配置和部署產(chǎn)品級(jí)的Twisted應(yīng)用變得非常方便宝磨。
你可以使用kivy.support.install_twisted_reactor函數(shù)來(lái)安裝一個(gè)運(yùn)行在kivy事件循環(huán)里面的twisted反應(yīng)器弧关。任何傳遞到該函數(shù)的參數(shù)和關(guān)鍵字都會(huì)被傳遞給threadedselect反應(yīng)器交錯(cuò)函數(shù)。通常有一個(gè)參數(shù)傳遞twisted的reactor.startRunning.
警告:不像默認(rèn)的Twisted反應(yīng)器唤锉,安裝的反應(yīng)器不會(huì)處理任何的信號(hào)世囊,除非你設(shè)置了installSignalHandlers關(guān)鍵字參數(shù)為1.這將使kivy來(lái)和平時(shí)一樣來(lái)處理信號(hào),除非你明確地想twisted反應(yīng)器來(lái)處理信號(hào)窿祥。
kivy的樣例中含一個(gè)關(guān)于twisted服務(wù)端和客戶端的小例子株憾。服務(wù)端程序有一個(gè)簡(jiǎn)單的twisted服務(wù)運(yùn)行并在日志上記錄所有的信息∩柜茫客戶端程序能發(fā)送消息到服務(wù)端嗤瞎,并打印它發(fā)送及響應(yīng)它的信息。例子基于twisted文檔的的簡(jiǎn)單的Echo 例子听系,你可以在下面的鏈接找到它們:
http://twistedmatrix.com/documents/current/_downloads/simpleserv.py
http://twistedmatrix.com/documents/current/_downloads/simpleclient.py
為了測(cè)試這個(gè)例子贝奇,首先運(yùn)行echo_server_app.py,接著運(yùn)行echo_client_app.py靠胜。服務(wù)端將會(huì)使用簡(jiǎn)單的echo消息來(lái)回應(yīng)任何來(lái)自客戶端發(fā)送的消息掉瞳。
服務(wù)端:
#在導(dǎo)入和使用反應(yīng)器之前毕源,install_twisted_rector必須首先被調(diào)用
from kivy.support import install_twisted_reactor
install_twisted_reactor()
from twisted.internet import reactor
from twisted.internet import protocol
class EchoProtocol(protocol.Protocol):
def dataReceived(self, data):
response = self.factory.app.handle_message(data)
if response:
self.transport.write(response)
class EchoFactory(protocol.Factory):
protocol = EchoProtocol
def __init__(self, app):
self.app = app
from kivy.app import App
from kivy.uix.label import Label
class TwistedServerApp(App):
def build(self):
self.label = Label(text="server started\n")
reactor.listenTCP(8000, EchoFactory(self))
return self.label
def handle_message(self, msg):
self.label.text = "received: %s\n" % msg
if msg == "ping":
msg = "pong"
if msg == "plop":
msg = "kivy rocks"
self.label.text += "responded: %s\n" % msg
return msg
if __name__ == '__main__':
TwistedServerApp().run()
客戶端:
#在導(dǎo)入和使用反應(yīng)器之前,install_twisted_rector必須首先被調(diào)用
from kivy.support import install_twisted_reactor
install_twisted_reactor()
#一個(gè)簡(jiǎn)單的客戶端陕习,它能發(fā)送消息到echo服務(wù)端
from twisted.internet import reactor, protocol
class EchoClient(protocol.Protocol):
def connectionMade(self):
self.factory.app.on_connection(self.transport)
def dataReceived(self, data):
self.factory.app.print_message(data)
class EchoFactory(protocol.ClientFactory):
protocol = EchoClient
def __init__(self, app):
self.app = app
def clientConnectionLost(self, conn, reason):
self.app.print_message("connection lost")
def clientConnectionFailed(self, conn, reason):
self.app.print_message("connection failed")
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
#一個(gè)簡(jiǎn)單的kivy應(yīng)用程序创千,帶有一個(gè)文本框來(lái)輸入消息柿冲,
#并有一個(gè)文本標(biāo)簽來(lái)顯示所有的從服務(wù)端返回的消息
class TwistedClientApp(App):
connection = None
def build(self):
root = self.setup_gui()
self.connect_to_server()
return root
def setup_gui(self):
self.textbox = TextInput(size_hint_y=.1, multiline=False)
self.textbox.bind(on_text_validate=self.send_message)
self.label = Label(text='connecting...\n')
self.layout = BoxLayout(orientation='vertical')
self.layout.add_widget(self.label)
self.layout.add_widget(self.textbox)
return self.layout
def connect_to_server(self):
reactor.connectTCP('localhost', 8000, EchoFactory(self))
def on_connection(self, connection):
self.print_message("connected succesfully!")
self.connection = connection
def send_message(self, *args):
msg = self.textbox.text
if msg and self.connection:
self.connection.write(str(self.textbox.text))
self.textbox.text = ""
def print_message(self, msg):
self.label.text += msg + "\n"
if __name__ == '__main__':
TwistedClientApp().run()