python - ping NewConnectionError(': 无法建立新连接:[Errno 110] Connection timed out'))
问题描述
我对 wsdl、asmx、client、zeep和其他与 SOAP API 相关的主题非常陌生,我必须修复一个由其他人用 Python 制作的“REST、SOAP APIs - 服务”系统。
目前我只在我的本地机器上工作。这是主要背景:
在我的项目主文件夹myservice
中有:
使用 Tornado 提供的服务
myservice > myserviceSrv.py
,和一组 API,其逻辑分为两个脚本:
myservice > handlers > myservice_api.py
: 包含继承自 的类tornado.web.RequestHandler
,其中包含post
调用externalcompany_myservice_api.py
脚本中 SOAP API 的 s 方法。myservice > handlers > externalcompany_myservice_api.py
:包含单个类,其中包含将调用外部公司服务 SOAP API 的 SOAP API 方法。其中一种方法是
ping
,我的目标是让它发挥作用,也就是说,我希望它在我使用 Postman 发布帖子时得到正确的响应。特别是,来自 Postman 的 POST 请求应该触发ping
我的服务的方法,该方法应该触发ping
应该触发外部公司服务的相应 SOAP API 的 SOAP API,它应该回复并最终给我发布响应。
包含一些配置的模块
myservice > config.py
,主要是绑定到的配置、tornado.options
wsdl 文件路径和 API url。
这就是问题:
我启动我的服务器(/服务),然后用 Postman 启动 POST http://localhost:30205/service/ping
(没有输入),但这是我得到的日志和回溯:
[I 2021-11-15 10:37:20.964 myserviceSrv:76] **************************************************
[I 2021-11-15 10:37:20.964 myserviceSrv:77] Starting externalcompany service 2021-11-15 10:37:20 on port 30205 for destination externalcompany
[I 2021-11-15 10:37:20.964 myserviceSrv:78] **************************************************
[I 2021-11-15 10:33:21.354 myserver_api:154] S - post Ping Handler
[I 2021-11-15 10:33:21.354 myserver_api:158] Destination Ping Handler: externalcompany
[I 2021-11-15 10:33:21.354 externalcompany_myserver_api:23] S - initialise wsdl
[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
[I 2021-11-15 10:33:22.834 externalcompany_myserver_api:26] Created wsdl externalcompany connection
[I 2021-11-15 10:33:22.834 externalcompany_myserver_api:27] E - initialise wsdl
[E 2021-11-15 10:35:33.348 externalcompany_myserver_api:216] Exception error ping: HTTPSConnectionPool(host='10.90.XXX.YY', port=8080): Max retries exceeded with url: /WebServices/Api/SalesApi.asmx (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f3a5dfc4cd0>: Failed to establish a new connection: [Errno 110] Connection timed out'))
[I 2021-11-15 10:35:33.348 web:2239] 200 POST /service/ping (::1) 131994.51ms
这是我的问题:
- 我不明白 IP 地址 10.90.XXX.YY 是从哪里来的。我在整个项目文件夹中找不到对它的引用。
- 看起来代码设法初始化 wsdl,但随后无法建立连接。但为什么?我做错了什么,我该如何解决?
以下是以下内容:
myservice_api.py:
import tornado.web
from tornado import gen
import json
import logging
import config as config
class Ping(tornado.web.RequestHandler):
def initialize(self, **kwargs):
self.destination = kwargs["destination"]
@gen.coroutine
def post(self):
logging.info('S - post Ping Handler')
response = {}
# Data received
logging.info("Destination Ping Handler: {}".format(self.destination))
# Init module with correct destination - start specific method ping()
try:
# calls the class associated to key "destination" -> the class ("externalcompanymyserviceApi") is initialized
# init_wsdl is passed the wsdl sales file for settings
destination_object_init = config.destination_schema[self.destination]()
response = yield destination_object_init.ping()
except Exception as e:
logging.error("Error Ping Handler: {}".format(e))
raise gen.Return(self.write(response))
externalcompany_myservice_api.py:
import logging
import config as config
import json
import os
from tornado import gen
from zeep import Client, Settings, helpers
from zeep.exceptions import Fault, Error
from utils import utilities as utils
class externalcompanymyserviceApi:
def __init__(self):
# Init wsdl object for all methods in class externalcompany - utilities object
self.wsdl_object_sales = self.init_wsdl(config.WSDL_SALES)
# wsdl object
@staticmethod
def init_wsdl(type_wsdl):
logging.info("S - initialise wsdl")
settings = Settings(strict=False, xml_huge_tree=True)
wsdl_externalcompany = Client(wsdl=type_wsdl, settings=settings)
logging.info("Created wsdl externalcompany connection")
logging.info("E - initialise wsdl")
return wsdl_externalcompany
配置文件
from tornado.options import define, parse_command_line
import logging
from handlers.externalcompany_myservice_api import externalcompanymyserviceApi
# LOGGING
logging.basicConfig(format='[%(levelname)1.1s %(asctime)s.%(msecs)03d %(module)s:%(lineno)d] %(message)s',
datefmt='%F %T')
# OPTIONS
# default: ip address of externalcompany (alias of externalcompany)
define("destination", default="externalcompany", help="destination of service", type=str)
# default: port of cash service intermediating with externalcompany
define("http_port", default=30205, help="run on the given port", type=int)
parse_command_line()
# SERVICE SETTINGS
DEBUG = True
######
# WSDL
######
# links to externalcompany test server
WSDL_PRODUCTS = "https://externalcompanyapi.vendorcompany.com/webservices/productservice_v1.asmx?WSDL"
WSDL_SALES = "https://externalcompanyapi.vendorcompany.com/WebServices/Api/SalesApi.asmx?WSDL"
# HANDLERS
PING = r"/service/ping"
# ...
destination_schema = {
"externalcompany": externalcompanymyserviceApi,
"John": "init class John"
}
myserviceSrv.py:
import config as cf
from config import PING
import logging
import tornado.web
from datetime import datetime
from tornado.log import enable_pretty_logging
from tornado.options import options
from tornado.ioloop import IOLoop
from tornado import httpserver
from handlers.myservice_api import Ping
#...
enable_pretty_logging()
class Destination_Service_Srv:
def __init__(self):
app = self.make_app()
self.http_server = self.make_server(app)
@staticmethod
def make_app():
settings = {
"debug": cf.DEBUG
}
return tornado.web.Application([
# ...
(PING, Ping, {"destination": options.destination})
], **settings)
@staticmethod
def make_server(app):
http_server = httpserver.HTTPServer(app, decompress_request=True)
http_server.listen(options.http_port)
return http_server
def start(self):
io_loop = IOLoop.current()
io_loop.start()
def stop(self):
io_loop = IOLoop.current()
io_loop.stop()
if __name__ == "__main__":
today = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
myservice_server = Destination_Service_Srv()
try:
logging.info('**************************************************')
logging.info('Starting myservice service {} on port {} for destination {}'.format(today, options.http_port,
options.destination))
logging.info('**************************************************')
myservice_server.start()
except KeyboardInterrupt:
myservice_server.stop()
解决方案
解决了
原来存储在变量中的 URLWSDL_PRODUCTS
是 WSDL_SALES
错误的,因为我无法从浏览器访问相应的 wsdl 文件。
所以我发现正确的 URL 是HTTP://
而不是HTTPS://
WSDL_PRODUCTS = "http://externalcompanyapi.vendorcompany.com/webservices/productservice_v1.asmx?WSDL"
WSDL_SALES = "http://externalcompanyapi.vendorcompany.com/WebServices/Api/SalesApi.asmx?WSDL"
现在我的帖子得到了正确的回应:
{"ping": {"MessageNo": 1001, "MessageText": "Ping Response", "MessageInfo": "Response from 'START' on '16/11/2021
10:20:31'", "IsSuccess": true, "Content": null}}
所以,回答我自己的问题:
IP 地址 10.90.XXX.YY 来自 wsdl 文件,其 URL 保存在
WSDL_SALES
.如果我做对了,
zeep 初始化了 wsdl,但它是按照 HTTPS 协议进行的,因此回溯指示[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
[W 2021-11-15 10:33:22.833 soap:218] Forcing soap:address location to HTTPS
因此为无效的 wsdl URL 配置了连接。
这是线路失败zeep_response = helpers.serialize_object(self.wsdl_object_sales.service.Ping())
因为 POST 无法得到响应,所以 zeep 序列化程序无法处理空响应。
推荐阅读
- c# - 玩家传送而不是平稳移动
- javascript - 使用文件 onLoad 设置状态
- javascript - 如何在不创建新的单独文件的情况下在页面链接上添加密码保护?
- random - 当碰撞可能且昂贵时,如何生成不重复的随机值?
- swift - 打开 UIPickerView 时出现的项目不被视为“已选择”
- rest - 在设计 REST API 时,是否可以要求在允许创建资源之前完成对资源的搜索?
- texmacs - TeXmacs 条件独立符号
- rust - 如何迭代使用 RwLock 构建的并发哈希映射的可变值?
- firebase - 如何使用 Flutter 更新云 Firestore 上文档的字段?
- c++ - Visual Studio 不运行我的代码,而其他 IDE 运行