[Twisted-Python] "blocking" on a response to a client

Hi Again, So, separate question: I have a client that's making a connection to a websocket from a server. The client needs to send an "auth" message once the websocket is up, and the client code shouldn't progress until it receives an affirmative response. How do I do this in a non-blocking way when using twisted? (inside an inlineDeferred method in this case!) Similarly, how do I get this dance to happen again if the websocket drops? How would I do some kind of backoff on he connection retries? And, icing on the cake, where can I find good examples of how to write automated tests for all of the above? cheers, Chris

Chris Withers <chris@simplistix.co.uk> writes:
There's nothing really special about an @inlineCallbacks method -- it just returns a Deferred so you can handle it like any other Deferred-returning method.
Similarly, how do I get this dance to happen again if the websocket drops? How would I do some kind of backoff on he connection retries?
The "Autobahn" Python libraries support all the above. They might not be great as "examples" per se (because these libraries also support asyncio so use a compatibility layer called txaio), but a connecting (+ reconnecting) client starts here: https://github.com/crossbario/autobahn-python/blob/master/autobahn/wamp/comp... You could also use the built-in Twisted "ClientService" to keep a protocol connected (the above doesn't because it's also doing asyncio) but see: https://twistedmatrix.com/documents/current/api/twisted.application.internet...
And, icing on the cake, where can I find good examples of how to write automated tests for all of the above?
It's kind of well-hidden :/ but the "most modern" way is to use something based on twisted.test.iosim.IOPump as I understand it. I haven't used this, though so maybe someone else can explain. It's of course possible to use more-traditional mocking and fakes to write tests. Essentially one way is to "drive" your protocol to the correct state (e.g. right before an auth is required) and then do the various tests on authentication. You can also do unit-tests of the actual authentication methods themselves (e.g. "does it parse stuff properly", etc). Again there's *some* examples in the Autobahn repository above. Here are some "not IOPump" examples using the Twisted "StringTransport" helper (this isn't WebSocket but should give some ideas): https://github.com/meejah/txtorcon/blob/master/test/test_torcontrolprotocol.... -- meejah

On Tue, Nov 6, 2018 at 6:42 AM Chris Withers <chris@simplistix.co.uk> wrote:
Put the rest of your code in a callback on a Deferred that fires when the event you're interested in happens. When using inlineCallbacks, that's like: yield the_event_youre_interested_in # ... more code At least, this is the extremely-localized solution to the problem. There are many possible ways to structure such a thing. It's easy to describe this one because you said you're using inlineCallbacks and didn't say anything else about how your code is organized. Jean-Paul

On 06/11/2018 13:47, Jean-Paul Calderone wrote:
Right, but I'm still too stupid to join the dots :-( More concretely, I want to spin up an autobahn websocket client, have it connect, send a login message, confirm that worked, send a 'create' message, confirm that worked, and *then* let the rest of my code progress... I'm surprised there don't appear to be any example of this floating around, and disappointed at the lack of examples of good tests for these things. Chris

On Tue, Nov 6, 2018 at 4:51 PM, Chris Withers <chris@withers.org> wrote:
If you have not yet looked at the AutoBahn site, then I would do so. I think you will find some good examples of dealing with web sockets and twisted. I don't know anything much about web sockets so can't offer much more that this. Here is a link https://github.com/crossbario/autobahn-python/tree/master/examples/twisted/w... Regards John Aherne -- *John Aherne* *www.rocs.co.uk <http://www.rocs.co.uk>* 020 7223 7567

Chris Withers <chris@simplistix.co.uk> writes:
There's nothing really special about an @inlineCallbacks method -- it just returns a Deferred so you can handle it like any other Deferred-returning method.
Similarly, how do I get this dance to happen again if the websocket drops? How would I do some kind of backoff on he connection retries?
The "Autobahn" Python libraries support all the above. They might not be great as "examples" per se (because these libraries also support asyncio so use a compatibility layer called txaio), but a connecting (+ reconnecting) client starts here: https://github.com/crossbario/autobahn-python/blob/master/autobahn/wamp/comp... You could also use the built-in Twisted "ClientService" to keep a protocol connected (the above doesn't because it's also doing asyncio) but see: https://twistedmatrix.com/documents/current/api/twisted.application.internet...
And, icing on the cake, where can I find good examples of how to write automated tests for all of the above?
It's kind of well-hidden :/ but the "most modern" way is to use something based on twisted.test.iosim.IOPump as I understand it. I haven't used this, though so maybe someone else can explain. It's of course possible to use more-traditional mocking and fakes to write tests. Essentially one way is to "drive" your protocol to the correct state (e.g. right before an auth is required) and then do the various tests on authentication. You can also do unit-tests of the actual authentication methods themselves (e.g. "does it parse stuff properly", etc). Again there's *some* examples in the Autobahn repository above. Here are some "not IOPump" examples using the Twisted "StringTransport" helper (this isn't WebSocket but should give some ideas): https://github.com/meejah/txtorcon/blob/master/test/test_torcontrolprotocol.... -- meejah

On Tue, Nov 6, 2018 at 6:42 AM Chris Withers <chris@simplistix.co.uk> wrote:
Put the rest of your code in a callback on a Deferred that fires when the event you're interested in happens. When using inlineCallbacks, that's like: yield the_event_youre_interested_in # ... more code At least, this is the extremely-localized solution to the problem. There are many possible ways to structure such a thing. It's easy to describe this one because you said you're using inlineCallbacks and didn't say anything else about how your code is organized. Jean-Paul

On 06/11/2018 13:47, Jean-Paul Calderone wrote:
Right, but I'm still too stupid to join the dots :-( More concretely, I want to spin up an autobahn websocket client, have it connect, send a login message, confirm that worked, send a 'create' message, confirm that worked, and *then* let the rest of my code progress... I'm surprised there don't appear to be any example of this floating around, and disappointed at the lack of examples of good tests for these things. Chris

On Tue, Nov 6, 2018 at 4:51 PM, Chris Withers <chris@withers.org> wrote:
If you have not yet looked at the AutoBahn site, then I would do so. I think you will find some good examples of dealing with web sockets and twisted. I don't know anything much about web sockets so can't offer much more that this. Here is a link https://github.com/crossbario/autobahn-python/tree/master/examples/twisted/w... Regards John Aherne -- *John Aherne* *www.rocs.co.uk <http://www.rocs.co.uk>* 020 7223 7567
participants (5)
-
Chris Withers
-
Chris Withers
-
Jean-Paul Calderone
-
John Aherne
-
meejah