我正在使用gevent-socketio将实时数据从python脚本推送到浏览器。但是我希望它能够从解释器以交互方式工作,以便服务器继续在后台运行。一些伪代码:
#start server with the application and keep it running on the background
server_inst=MyAppServer()
#send data to the sever that pushes it to a browser (prints "foo" to the browser)
server_inst.send_data('foo')
看过线程后,我仍然感到困惑,它是如何做/应该做的。任何指针都适用。
答案 0 :(得分:0)
是否有理由让服务器和控制台程序成为同一个进程?
如果不是,我会建议使用两个单独的进程和命名管道。如果这个解决方案不理想,无论出于何种原因,请提供更多详细信息。
无论如何,这里有一些代码可能对您实现Pipe类很有用。我不确定你需要通信的数据到底是什么形式,所以你可以使Pipe类抽象出一些简单的协议和/或使用pickle。
def __init__(self,sPath):
"""
create the fifo. if it already exists just associate with it
"""
self.sPath = sPath
if not os.path.exists(sPath):
try:
os.mkfifo(sPath)
except:
raise Exception('cannot mkfifo at path \n {0}'.format(sPath))
self.iFH = os.open(sPath,os.O_RDWR | os.O_NONBLOCK)
self.iFHBlocking = os.open(sPath,os.O_RDWR)
def base_read(self,iLen,blocking=False):
iFile = self.iFHBlocking if blocking else self.iFH
while not self.ready_for_reading():
import time
time.sleep(0.5)
lBytes = ''.encode('utf-8')
while len(lBytes)<iLen:
self.lock()
try:
lBytes += os.read(iFile,1)
self.unlock()
except OSError as e:
self.unlock()
if e.errno == 11:
import time
time.sleep(0.5)
else:
raise e
return lBytes
def base_write(self,lBytes,blocking = False):
iFile = self.iFHBlocking if blocking else self.iFH
while not self.ready_for_writing():
import time
time.sleep(0.5)
while True:
self.lock()
try:
iBytesWritten = os.write(iFile, lBytes)
self.unlock()
break
except OSError as e:
self.unlock()
if e.errno in [35,11]:
import time
time.sleep(0.5)
else:
raise
if iBytesWritten < len(lBytes):
self.base_write(lBytes[iBytesWritten:],blocking)
def get_lock_dir(self):
return '{0}_lockdir__'.format(self.sPath)
def lock(self):
while True:
try:
os.mkdir(self.get_lock_dir())
return
except OSError as e:
if e.errno != 17:
raise e
def unlock(self):
try:
os.rmdir(self.get_lock_dir())
except OSError as e:
if e.errno != 2:
raise e
def ready_for_reading(self):
lR,lW,lX = select.select([self.iFH,],[],[],self.iTimeout)
if not lR:
return False
lR,lW,lX = select.select([self.iFHBlocking],[],[],self.iTimeout)
if not lR:
return False
return True
def ready_for_writing(self):
lR,lW,lX = select.select([],[self.iFH,],[],self.iTimeout)
if not lW:
return False
return True
我有一个更完整的类我愿意分享的实现,但我认为我用它抽象的协议对你来说可能没用......你将如何使用它在你的服务器和你的服务器中创建一个实例控制台应用程序使用相同的路径然后使用base_read和base_write来完成脏工作。这里所有其他的东西都是为了避免奇怪的竞争条件。
希望这有帮助。