# 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, ...) ) ... ```