Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pair1 example extended #43

Open
MauiJerry opened this issue Jul 25, 2019 · 2 comments
Open

Pair1 example extended #43

MauiJerry opened this issue Jul 25, 2019 · 2 comments

Comments

@MauiJerry
Copy link

MauiJerry commented Jul 25, 2019

while learning about Pair1, I played with the example a bit, providing some extra examples and tests. Thought it might be nice to share that code so....

#from the docs page https://pynng.readthedocs.io/en/latest/core.html#available-protocols
# with some mods
# Pair1 allows single Server/Listener to connect bi-directionally with multiple Client/Dialers
# it does NOT operate as a Publisher in that a listner.send() goes to ??
import sys, traceback
from pynng import Pair1, Timeout
print("begin Pair 1 polyamorous test")

address = 'tcp://127.0.0.1:12343'
with Pair1(listen=address, polyamorous=True, recv_timeout=100) as s0, \
        Pair1(dial=address, polyamorous=True, recv_timeout=100) as s1, \
        Pair1(dial=address, polyamorous=True, recv_timeout=100) as s2:
    print("opened all 3")
    s0.send(b'hi everybody!')
    s1.send(b'hello from s1')
    s2.send(b'hello from s2')
    print("sent all three")
    print("recv_msg on s0")
    msg1 = s0.recv_msg()
    print(msg1.bytes)  # prints b'hello from s1'

    msg2 = s0.recv_msg()
    print(msg2.bytes)  # prints b'hello from s2'
    
    print("recv on s1:")
    msg01 = s1.recv()
    print(msg01)  # prints b'hello from s1'

    try:
        print("recv on s2")
        msg02 = s2.recv()
        print(msg02)  # prints b'hello from s2'
    except Timeout:
        print("Timeout on S2 waiting to hear from s0")

    print("send single msg responses")
    msg1.pipe.send(b'hey s1')
    msg2.pipe.send(b'hey s2')
    print(s2.recv())  # prints b'hey s2'
    print(s1.recv())  # prints b'hey s1'
    
    # beyond first msg, repeats will share the Pipe but not data
    s1.send(b'more from s1')
    morMsg = s0.recv_msg()
    print("morMsg: ")
    print(morMsg.bytes)
    if morMsg.pipe == msg1.pipe:
        print ("msg1 and morMsg share pipe")
    else:
        print ("msg1 and morMsg do NOT share pipe")
    print("and msg1 still says:")
    print(msg1.bytes)
    
    print("what if s0 does recv instead of recvMsg?")
    s1.send(b'again from s1')
    more = s0.recv()
    print(more)
#    print("It works, we just dont get the Message info")
    
    print("Pair1 with both listen and dial should throw exception")
    # pynng Pair1 has no code to recognize this error, allowing both arguments
    # however the underlying Socket should throw an AddressInUse exception
    try:
        with Pair1(dial=address, listen=address, polyamorous=True, recv_timeout=100) as s3:
            s3.send(b'hello out there')
            msg = s0.recv_msg()
            print("rceve on s0")
            print(msg.bytes)
            s3.send(b'hello out there')
            msg = s3.recv_msg()
            print("rceve on s3")
            print(msg.bytes)
    except:
        print("caught something", sys.exc_info()[0])
        traceback.print_exc()#sys.exc_info()[2].print_tb()
        #raise
    
print("End Pair1 test")
@codypiersall
Copy link
Owner

Hi @MauiJerry, thanks for your interest in the library and for opening an issue. You've got a good point that the docs could make it more clear what a polyamorous pair socket does when you call send on the socket instead of a pipe.

Probably when using a polyamorous pair socket that has multiple connections socket.send() shouldn't be called, since it's hard to reason about where it goes. Using recv_msg() and then calling msg.pipe.send() like you've done is a great strategy. Alternatively, you can access a list of active pipes via socket.pipes directly, and use the remote_address property of the pipe to see who the remote node is.

P. S., I made a small edit to your post to make the code format as python.

@MauiJerry
Copy link
Author

Thanks... nice to see the python technique for sharing code here. I'll try to remember it.
I have this working nicely on my rPi project, with a PubSub channel sending out updates from Server, that listens on the Pair1 ... although it currently only works using 127.... fixed address. on my TODO is getting zeroconfig working so i can use a name in my code and have the clients on PC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants