server模块说明¶
server模块提供了一个通用Web服务管理抽象框架(ServerBaseFW),支持实现类进行Web服务的启动、关闭,添加/移除服务函数等功能,支持快速实现一个新的Web服务;此外实现了一个基于Socket的TcpIpServer,可以通过简单的协议实现服务端的数据收发,可以作为ServerBaseFW的一个实现类参考示例。
遵循标准¶
hivenet_error_code_standards_v1.1.0
hivenet_log_standards_v1.0.0
基于ServerBaseFW实现自己的Web服务¶
1、实现类必须继承ServerBaseFW
class MyWebServer(ServerBaseFW):
...
2、按需要是否重载 __init__ 函数
def __init__(self, app_name: str, server_config: dict = {}, support_auths: dict = {},
before_server_start=None, after_server_start=None,
before_server_stop=None, after_server_stop=None, logger=None, log_level: int = logging.INFO,
load_i18n_para=None, **kwargs):
"""自己的注释"""
# 引用框架的构造函数
super().__init__(
app_name, server_config=server_config, support_auths=support_auths,
before_server_start=before_server_start,
after_server_start=after_server_start, before_server_stop=before_server_stop,
after_server_stop=after_server_stop, logger=logger, log_level=log_level,
load_i18n_para=load_i18n_para, **kwargs
)
# 自己的其他逻辑
...
注:一般来说,重载 __init__ 函数的目的更多是进行注释内容变更,便于进行代码的提示;如果需要进行参数初始化处理,也可以直接把逻辑放到 _std_init_config 函数内,并不一定要在 __init__ 函数内处理初始化逻辑。
3、重载 _std_init_config 函数,实现 __init__ 函数初始化的自定义逻辑:
def _std_init_config(self):
"""
标准化服务初始配置
"""
# 实现类可以通过该函数设置或修改内部参数
pass
4、重载真正的服务启动和停止相关的函数:
async def _real_server_initialize(self, tid) -> CResult:
"""
初始化真正的服务端处理对象
注: 可以在该函数中启动真正的服务, 例如绑定监听端口
@param {int} tid - 服务线程id
@returns {CResult} - 启动结果:
result.code: '00000'-成功, 其他值为失败
result.server_info: 启动成功后的服务信息, 用于传递到后续的服务处理函数
"""
_result = CResult(code='00000') # 成功
_result.server_info = NullObj()
with ExceptionTool.ignored_cresult(_result):
# 注: 重载该函数, 可在该部分实现自定义的服务初始化或启动逻辑
pass
# 返回处理结果
return _result
async def _real_server_accept_and_run(self, tid, server_info) -> CResult:
"""
真正的服务获取请求并运行
注: 支持同步或异步函数, 可以在该函数中获取请求, 并启动线程执行请求处理
@param {int} tid - 线程id
@param {Any} server_info - 启动成功后的服务信息
@returns {CResult} - 处理结果:
result.code: '00000'-成功, 其他值为失败, 如果为失败将停止服务
result.is_finished: 指示服务是否已完成, True - 已处理完成可停止服务, False - 未完成, 需循环处理下一个请求
"""
_result = CResult(code='00000') # 成功
_result.is_finished = False
with ExceptionTool.ignored_cresult(
_result, logger=self._logger,
self_log_msg='[SER][NAME:%s]%s: ' % (
self._app_name, _('server run error')),
force_log_level=logging.ERROR
):
# 注: 重载该函数, 可在该部分实现自定义的获取请求及处理逻辑
pass
# 返回处理结果
return _result
async def _real_server_prepare_stop(self, tid) -> CResult:
"""
服务关闭前的处理函数
注: 支持同步或异步函数, 可以在该函数中等待已接入的请求或线程完成处理
@param {int} tid - 线程id
@returns {CResult} - 处理结果:
result.code: '00000'-成功, 其他值为失败
result.is_finished: 指示停止前的预处理是否已完成, True - 已处理完成可停止服务, False - 未完成, 需循环继续调用本函数
"""
_result = CResult(code='00000') # 成功
_result.is_finished = True
with ExceptionTool.ignored_cresult(
_result, logger=self._logger,
self_log_msg='[SER-PRE-STOP][NAME:%s]%s: ' % (
self._app_name, _('stop net server error')),
force_log_level=logging.ERROR
):
# 注: 重载该函数, 可在该部分实现自定义的服务关闭前处理
pass
return _result
async def _real_server_stop(self, tid, server_info):
"""
真正服务的关闭处理
注: 支持同步或异步函数, 可以在该函数中清理处理线程并关闭监听
@param {int} tid - 线程id
@param {Any} server_info - 启动成功后的服务信息
"""
# 子类必须定义该功能
with ExceptionTool.ignored_all(
logger=self._logger,
self_log_msg='[SER-STOP][NAME:%s]%s error: ' % (
self._app_name, _('stop net server error')
)
):
# 注: 重载该函数, 可在该部分实现自定义的服务关闭处理
pass
注:在重载 _real_server_accept_and_run 函数时涉及到客户端请求的处理逻辑,处理逻辑中可以使用 self._service_router 字典获取到服务所添加的处理函数对象,来进行真正的业务处理。
5、根据需要重载其他函数
正常情况完成上述4个步骤就可以完成一个Web服务的实现,框架启动一个服务子线程,通过 _real_server_initialize 函数进行服务对象的初始化(例如绑定IP并启动监听),以及通过循环调用 _real_server_accept_and_run 函数从服务对象中获取客户端请求并进行对应的业务逻辑处理。
如果您的服务对象无法按照该流程进行初始化和获取请求处理,则需重载其他相关函数来实现具体逻辑,例如Sanic本身启动就是阻断式的方式,需要直接重载 start 函数实现相关功能。
ServerBaseFW服务的使用¶
1、基于ServerBaseFW实现的web服务使用
from HiveNetCore.utils.run_tool import AsyncTools
# 服务处理函数定义
def deal_fun_1(...):
...
def deal_fun_2(...):
...
# 初始化服务对象, 具体参数说明直接参考源码的注释定义
_server = MyWebServer(...)
# 添加处理函数,注意是异步调用方式, 如果是异步函数内部,可以使用await来处理
AsyncTools.sync_run_coroutine(
_server.add_service('/deal_fun/uri1', deal_fun_1, ...)
)
AsyncTools.sync_run_coroutine(
_server.add_service('/deal_fun/uri2', deal_fun_2, ...)
)
# 启动服务, 这里指定同步模式,也就是服务不停止就阻塞该线程
AsyncTools.sync_run_coroutine(
_server.start(is_asyn=True)
)
2、auth鉴权功能的使用
结合auth鉴权框架,可以在服务处理函数上增加修饰符,实现对客户端强求的鉴权,例如:
# 加载鉴权实现类
from xxx import IPAuthXXX
# 服务处理函数定义, 增加ip鉴权修饰符
@MyWebServer.auth_required_static(auth_name='IPAuth', app_name='MyAppName')
def deal_fun_1(...):
...
@MyWebServer.auth_required_static(auth_name='IPAuth', app_name='MyAppName')
def deal_fun_2(...):
...
# 实例化IPAuth鉴权对象, 增加访问白名单
_ip_auth = IPAuthXXX(init_whitelist=['10.1.43.*', '10.2.*, *'])
# 初始化服务对象, 指定修饰符中相同的app_name, support_auths参数与auth_name对应
_server = MyWebServer('MyAppName', ..., support_auths={'IPAuthXXX': _ip_auth}, ...)
# 添加处理函数
AsyncTools.sync_run_coroutine(
_server.add_service('/deal_fun/uri1', deal_fun_1, ...)
)
AsyncTools.sync_run_coroutine(
_server.add_service('/deal_fun/uri2', deal_fun_2, ...)
)
...