0

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')

スレッディングを見て、私はそれがどのようにできるか/すべきかまだ混乱しています。適切なポインタ。

4

1 に答える 1

0

サーバーとコンソール プログラムを同じプロセスにする理由はありますか?

そうでない場合は、2 つの別個のプロセスと名前付きパイプを使用することをお勧めします。この解決策が何らかの理由で理想的でない場合は、詳細を教えてください。

とにかく、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 を使用して、汚い作業を行います。ここにある他のすべてのものは、奇妙な競合状態を避けるためのものです。

お役に立てれば。

于 2012-11-19T14:18:29.833 に答える