jeffthibault / python-nostr

A Python library for Nostr
MIT License
274 stars 87 forks source link

[BUG] The client is stuck after a few minutes running #85

Closed yaohaizhou closed 1 year ago

yaohaizhou commented 1 year ago

I want to run a client bot on the server. When a client chats with it, it will return what the client says. The code runs well in the first few minutes, but it cannot receive messages and send messages after that. The process is stuck at while relay_manager.message_pool.has_events(): (because when I stop the process, the exception location is in this line)

The code is below


# keys
bob_keys = ("XXX",
            "XXX")

bob_private = PrivateKey.from_nsec(bob_keys[0])
bob_public = bob_private.public_key.hex()

# event filter
filters = Filters([Filter(
                    # authors=[alice_public], 
                    kinds=[EventKind.ENCRYPTED_DIRECT_MESSAGE],
                    pubkey_refs=[bob_public],
                    since=int(time.time()) # the create time should after current time
                    )])
subscription_id = "sub"
request = [ClientMessageType.REQUEST, subscription_id]
request.extend(filters.to_json_array())

# nostr config
relay_manager = RelayManager()
relay_manager.add_relay("wss://nostr.yaohaizhou.com")
relay_manager.add_subscription_on_all_relays(subscription_id, filters)
# time.sleep(1.25) # allow the connections to open

conversation_id = {}
parent_id = {}

# DMs
while(1):
    # print("loop")
    while relay_manager.message_pool.has_events():
        # pdb.set_trace()
        # print("New event!")
        event_msg = relay_manager.message_pool.get_event()
        alice_public = event_msg.event.public_key
        alice_name = event_msg.event.public_key[:6]

        try:
            decrypted_contents = bob_private.decrypt_message(
                event_msg.event.content,  # the encrypted message, sent by Alice
                alice_public  # we now use Alice's public key to decrypt it again
            )
            print(alice_name+f" said: {decrypted_contents}")
        except:
            pass

        print("Chatbot: ")

        dm = EncryptedDirectMessage(
            recipient_pubkey=alice_public,
            cleartext_content=decrypted_contents
        )
        bob_private.sign_event(dm)
        relay_manager.publish_event(dm)
yaohaizhou commented 1 year ago

Alright, I solved this by adding ping-pong signal in websocket. Add ping_interval=30,ping_timeout=5, in relay.py

    def connect(self):
        self.ws.run_forever(
            ping_interval=30,
            ping_timeout=5,
            sslopt=self.ssl_options,
            http_proxy_host=self.proxy_config.host if self.proxy_config is not None else None,
            http_proxy_port=self.proxy_config.port if self.proxy_config is not None else None,
            proxy_type=self.proxy_config.type if self.proxy_config is not None else None,
        )