3

I'm currently writing a project in Python which has a client and a server part. I have troubles with the network communication, so I need to explain some things...

The client mainly does operations the server tells him to and sends the results of the operations back to the server. I need a way to communicate bidirectional on a TCP socket.

Current Situation

I currently use a LineReceiver of the Twisted framework on the server side, and a plain Python socket (and ssl) on client side (because I was unable to correctly implement a Twisted PushProducer). There is a Queue on the client side which gets filled with data which should be sent to the server; a subprocess continuously pulls data from the queue and sends it to the server (see code below).

This scenario works well, if only the client pushes its results to the manager. There is no possibility the server can send data to the client. More accurate, there is no way for the client to receive data the server has sent.

The Problem

I need a way to send commands from the server to the client.

I thought about listening for incoming data in the client loop I use to send data from the queue:

def run(self):
    while True:
        data = self.queue.get()
        logger.debug("Sending: %s", repr(data))
        data = cPickle.dumps(data)
        self.socket.write(data + "\r\n")
        # Here would be a good place to listen on the socket

But there are several problems with this solution:

  • the SSLSocket.read() method is a blocking one
  • if there is no data in the queue, the client will never receive any data

Yes, I could use Queue.get_nowait() instead of Queue.get(), but all in all it's not a good solution, I think.

The Question

Is there a good way to achieve this requirements with Twisted? I really do not have that much skills on Twisted to find my way round in there. I don't even know if using the LineReceiver is a good idea for this kind of problem, because it cannot send any data, if it does not receive data from the client. There is only a lineReceived event.

Is Twisted (or more general any event driven framework) able to solve this problem? I don't even have real event on the communication side. If the server decides to send data, it should be able to send it; there should not be a need to wait for any event on the communication side, as possible.

4

2 に答える 2

2

LineReceiver「クライアントからデータを受信しないと、データを送信できないため、この種の問題に対してを使用することが適切かどうかさえわかりません。lineReceivedイベントしかありません。」

protocol.transport.writeだけでなく、どこからでもを使用してデータを送信できますlineReceived

于 2010-09-28T21:28:59.403 に答える
-1

「サーバーからクライアントにコマンドを送信する方法が必要です。」

これをしないでください。「クライアント」と「サーバー」の通常の意味を逆にします。クライアントは積極的な役割を果たし、サーバーからデータを送信したり要求したりします。

Twisted (またはより一般的なイベント駆動型フレームワーク) はこの問題を解決できますか?

すべきではありません。クライアントとサーバーの役割を逆転させています。

サーバーがデータを送信することを決定した場合、それを送信できる必要があります。

実際、間違っています。

サーバーは、クライアントがデータを要求するのを待つように制限されています。これが、一般に受け入れられている「クライアント」と「サーバー」の意味です。


「1 つはクライアントにコマンドを送信するためのもので、もう 1 つは結果をサーバーに送信するためのものです。このソリューションは、標準的なクライアント/サーバー通信のように聞こえますか?」

いいえ。

クライアントがサーバーにメッセージを送信し、サーバーから応答を受信した場合、より一般的な定義に適合します。

時々、この種のことは、それぞれが一種のサーバーである「エージェント」と、これらすべてのサーバーの単一のクライアントである「コントローラー」を持つと説明されます。

コントローラーはエージェントに作業をディスパッチします。エージェントはサーバーです。ポートをリッスンし、コントローラーからの作業を受け入れ、作業を行います。各エージェントは、(通常はselectAPI を介して) 2 つのことを同時に行う必要があります。

  • 唯一無二のクライアントから作業を受け取る既知のソケットを監視します。

  • 作業を行います (バックグラウンドで)。

これは通常、Client-Server が意味するものです。

各エージェントがサーバーである場合、多くのライブラリがこれをサポートすることがわかります。これは誰もが行う方法です。

于 2010-09-22T19:25:47.560 に答える