Замените reactor.spawnProcess(proto, addr)
на reactor.spawnProcess(proto, addr, ['maze'], {})
.
Опыт прошлых лет показал, что если вы не передадите exe-имя в качестве первого аргумента, тогда ничего полезного не произойдет.Однако мне еще предстоит найти разумное объяснение, почему это происходит.
Также вам не нужно global reactor
.При импорте reactor
вы добавляете его в пространство имен скрипта верхнего уровня.Это означает, что все функции и классы в одном и том же файле могут использовать его без объявления глобального или повторного импорта.
Кроме того, вам не следует использовать sleep(0.01)
, поскольку:
- Егоне встроенная функция.Вам необходимо импортировать его из модуля
time
. - Twisted - это асинхронная структура, в которой функция должна избегать блокировок любой ценой, и
time.sleep()
( ссылка )) по определению является блокирующим вызовом.
Вместо этого следует использовать reactor.callLater()
ссылку , где вы предоставляете это обратный вызов и период времени.Это позволит витой обрабатывать другие вещи (например, новое соединение), пока вы ждете.
Наконец, ваш код на данный момент потребует от пользователя ввода ввода, прежде чем программа запросит какой-либо.Это потому, что getWrit
просто отправляет материал, уже находящийся в буфере, а не спрашивает пользователя.Это означает, что если пользователь не отправил никаких данных до вызова getWrit
, он просто вернет пустую строку.
Было бы лучше, если бы вы использовали отложенный метод.Затем вы должны вызвать getWrit
, который бы немедленно возвратил отложенный и очистил буфер данных.Затем в dataReceived
вы добавляете данные в буфер, пока не получите символ новой строки (\n
).В этот момент вы бы назвали отложенный набор в getWrit
.
Примерно так:
print 'Preall test works!'
from twisted.internet import reactor, protocol, defer
from twisted.python import log
import sys
print 'Imports done'
class PrgShell(protocol.Protocol):
data = ''
class PrgProto(protocol.ProcessProtocol):
def __init__(self, out):
print 'Prgproto instance made'
self.transportout = out.transport
self.out = out
def outReceived(self, data):
"""Called when process sends data. We send it on to transport, however if it's 'I want input', we need to activate input."""
print 'Sub said: '+data
if data == "input":
print 'Sub wants input'
self.transportout.write("input")
d = self.out.getWrit() # getWrit returns a deferred. We store it in d to make the code more readable
d.addCallback(self.sendInput) # Here we add self.sendInput to the callback chain.
# This way self.sendInput gets called with the user input.
else:
self.transportout.write(data)
def sendInput(self, data):
self.transport.write(data)
def getWrit(self):
print 'Proto gave input to prg'
self.deferred = defer.deferred()
self.data = ''
return self.deferred
def connectionMade(self):
print 'Connected'
proto = self.PrgProto(self)
addr = "C:\\Documents and Settings\\papa\\My Documents\\Python\\Files\\Maze\\exe\\maze.exe"
reactor.spawnProcess(proto, addr, ['maze'], {})
print 'Procces spawned!'
def dataReceived(self, data):
print 'Data recived: '+data
self.data+=data
if self.data.endswith('\n'):
if self.deferred:
# We got a newline character, and there is a deferred to call, so lets call it
d, self.deferred = self.deferred, None # This will set self.deferred to none to stop mistakes later
d.callback(self.data) # Call the deferred with data. This will send the data to sendInput above.
self.data = '' # Clear the buffer
print 'About to do stuff'
factory = protocol.ServerFactory()
factory.protocol = PrgShell
#f = open("errors.txt", 'w')
#log.startLogging(f)
#print 'Logging started'
reactor.listenTCP(8000,factory)
print 'Runing'
reactor.run()