Поддержание другого постоянного TCP-соединения с TCPServer

Я подключаюсь к серверу XMPP с использованием slixmpp, мне нужен доступ к этому соединению при обслуживании протокола HTTP, я пытаюсь поддерживать постоянное соединение, а не подключаться к серверу XMPP для каждого HTTP-запроса. Я использую TCPServer для получения функциональности HTTP. Я написал этот код.

import logging

from slixmpp import ClientXMPP
from slixmpp.exceptions import IqError, IqTimeout
import socketserver

from time import sleep
class EchoBot(ClientXMPP):

        def __init__(self, jid, password):
            ClientXMPP.__init__(self, jid, password)

            self.add_event_handler("session_start", self.session_start)
            self.add_event_handler("message", self.message)

        def session_start(self, event):
            self.send_presence()
            self.get_roster()


        def message(self, msg):
            print(msg)
            if msg['type'] in ('chat', 'normal'):
                msg.reply("Thanks for sending
%(body)s" % msg).send()
class MyTCPHandler(socketserver.BaseRequestHandler):
        xmpp = EchoBot('xxx@fcm.googleapis.com', 'xyz')
        def __init__(self,request, client_address,server):
            super().__init__(request, client_address,server)
            self.xmpp.connect(address=('fcm-xmpp.googleapis.com',5235),use_ssl=True,disable_starttls=True)
            self.xmpp.process(forever=True)

        def handle(self):
            self.data = self.request.recv(1024).strip()
            print("{} wrote:".format(self.client_address[0]))
            print(self.data)
            # just send back the same data, but upper-cased
            self.request.sendall(self.data.upper())


if __name__ == '__main__':

        logging.basicConfig(level=logging.DEBUG,format='%(levelname)-8s %(message)s')
        HOST, PORT = "localhost", 9999
        server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
        server.serve_forever()

Это работает впервые. MyTCPHandler дескриптора MyTCPHandler работает только первый раз, второй раз, она не возвращает никакого ответа. Я использую telnet localhost 9999 для проверки соединения. Что может быть не так? Есть ли лучший способ добиться результата, который я ищу?

если я прокомментирую эти три строки, TCPServer работает как положено.

# xmpp = EchoBot('xxx@fcm.googleapis.com', 'xyz')
        def __init__(self,request, client_address,server):
            super().__init__(request, client_address,server)
          #  self.xmpp.connect(address=('fcm-xmpp.googleapis.com',5235),use_ssl=True,disable_starttls=True)
          #  self.xmpp.process(forever=True)

Всего 1 ответ


Я решил проблему с помощью Asyncio

import logging

from slixmpp import ClientXMPP
from slixmpp.exceptions import IqError, IqTimeout

import logging
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
log = logging.getLogger(__name__)

import asyncio
import base64
import slixmpp
from aiohttp import web

XMPP = None

class EchoBot(ClientXMPP):

    def __init__(self, jid, password):
        ClientXMPP.__init__(self, jid, password)
        self.connected_future = asyncio.Future()
        self.add_event_handler("session_start", self.session_start)
        self.add_event_handler("message", self.message)

    def session_start(self, event):
        self.send_presence()
        self.get_roster()
    def message(self, msg):
        if msg['type'] in ('chat', 'normal'):
            msg.reply("Thanks for sending
%(body)s" % msg).send()
    def reset_future(self):
        "Reset the future in case of disconnection"
        self.connected_future = asyncio.Future()


async def handle(request):
    "Handle the HTTP request and block until the vcard is fetched"
    err_404 = web.Response(status=404, text='Not found')
    print(await request.json())



    try:
        XMPP.send_raw('<message id="gsgsfssdfds"> <gcm xmlns="google:mobile:data">{ "notification": {"title": "change","body": "body changed","sound":"default"},"to" : "efsfdsf","message_id":"flajlfdjlfdklajflda","priority":"high","delivery_receipt_requested":true}</gcm></message>')
    except Exception as e:
        print(e)
        log.warning("cannot send message")
        return err_404


    return web.Response(text="yes")

async def init(loop, host: str, port: str, avatar_prefix: str):
    "Initialize the HTTP server"
    app = web.Application(loop=loop)
    app.router.add_route('POST', '/', handle)
    srv = await loop.create_server(app.make_handler(), host, port)
    log.info("Server started at http://%s:%s", host, port)
    return srv

def main(namespace):
    "Start the xmpp client and delegate the main loop to asyncio"
    loop = asyncio.get_event_loop()
    global XMPP
    XMPP = EchoBot('xxx@gcm.googleapis.com', 'ysfafdafdsfa')
    XMPP.connect(use_ssl=True,disable_starttls=False)
    #XMPP.connect()
    loop.run_until_complete(init(loop, namespace.host, namespace.port,
                                 namespace.avatar_prefix))
    XMPP.reset_future()
    loop.run_until_complete(XMPP.connected_future)


    try:
        loop.run_forever()
    except KeyboardInterrupt:
        import sys

def parse_args():
    "Parse the command-line arguments"
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument('--jid', '-j', dest='jid', default=JID,
                        help='JID to use for fetching the vcards')
    parser.add_argument('--password', '-p', dest='password', default=PASSWORD,
                        help='Password linked to the JID')
    parser.add_argument('--host', dest='host', default=HOST,
                        help='Host on which the HTTP server will listen')
    parser.add_argument('--port', dest='port', default=PORT,
                        help='Port on which the HTTP server will listen')
    parser.add_argument('--avatar_prefix', dest='avatar_prefix',
                        default=AVATAR_PREFIX,
                        help='Prefix path for the avatar request')
    return parser.parse_args()

HOST = 飗.0.0.1'
PORT = 8765
JID = 'changeme@example.com'
PASSWORD = 'changemetoo'
AVATAR_PREFIX = 'avatar/'

if __name__ == "__main__":
    print(parse_args())
    main(parse_args())

Есть идеи?

10000