[英]Maintaining another persistent TCP connection with TCPServer
I am connecting to a XMPP server using slixmpp, I need access to this connection while serving a HTTP protocol, I am trying to maintain a persistent connection, rather than connecting connecting to XMPP server for each HTTP request. 我使用slixmpp连接到XMPP服务器,我需要在提供HTTP协议时访问此连接,我正在尝试维护持久连接,而不是为每个HTTP请求连接到XMPP服务器。 I am using TCPServer to get the functionality of HTTP.
我正在使用TCPServer来获取HTTP的功能。 I wrote this code.
我写了这段代码。
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\n%(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()
This works for first time. 这是第一次工作。
MyTCPHandler
handle function works only first time, second time, it doesn't return any response. MyTCPHandler
句柄功能只能在第一次工作,第二次,它不会返回任何响应。 I am using telnet localhost 9999
to test the connection. 我使用
telnet localhost 9999
来测试连接。 What might be going wrong here? 这里可能出了什么问题? Is there a better way to achieve the result I'm looking for?
有没有更好的方法来实现我正在寻找的结果?
if I comment these three lines TCPServer works as expected. 如果我评论这三行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)
I solved the problem using asyncio 我使用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\n%(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 = '127.0.0.1'
PORT = 8765
JID = 'changeme@example.com'
PASSWORD = 'changemetoo'
AVATAR_PREFIX = 'avatar/'
if __name__ == "__main__":
print(parse_args())
main(parse_args())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.