美文网首页
Python版本Zinx——(10)链接启动/停止自定义钩子函数

Python版本Zinx——(10)链接启动/停止自定义钩子函数

作者: 爱折腾的胖子 | 来源:发表于2023-08-29 02:21 被阅读0次

  最近想研究一下关于长链接的相关内容,在B站上看到了Zinx框架的视频,是Golang语言的框架,本着更好的理解框架的内容,按照整个Zinx课程的进度,制作一个Python版本的Zinx框架。有关于Zinx框架的具体内容,可以看框架作者的介绍
  python版本的Zinx,基于Gevent 22.10.2,使用协程功能。

  golang版本的Zinx项目,项目中两个文件夹,ziface和znet。

  • ziface主要是存放一些Zinx框架的全部模块的抽象层接口类。
  • znet模块是zinx框架中网络相关功能的实现,所有网络相关模块都会定义在znet模块中。
    └── zinx
     ├── ziface
     │  └──
     └── znet
        ├──

  python中的关键字没有interface,但是可以使用抽象基类(abstract base class)和第三方库来实现类似于接口的功能。在实际开发中,我们可以根据具体需求选择合适的实现方式。
  暂时使用抽象基类的形式模拟接口的实现。


  本节开发在链接创建之后和链接关闭之前,可以执行用户自定义的函数。
  在IServer中添加四个函数。

    @abstractmethod
    def SetOnConnStart(self, cb):
        """
        设置该Server的连接创建时Hook函数
        :param cb:
        :return:
        """
        pass

    @abstractmethod
    def SetOnConnStop(self, cb):
        """
        设置该Server的连接断开时的Hook函数
        :param cb:
        :return:
        """
        pass

    @abstractmethod
    def CallOnConnStart(self, conn: IConnection):
        """
        调用连接OnConnStart Hook函数
        :param conn:
        :return:
        """
        pass

    @abstractmethod
    def CallOnConnStop(self, conn: IConnection):
        """
        调用连接OnConnStop Hook函数
        :param conn:
        :return:
        """
        pass

  在Server创建成员变量,将钩子函数定义一下。

class Server(IServer):
    def __init__(self, name: str, ip: str, port: int,
                 family: socket.AddressFamily = socket.AF_INET,
                 socket_kind: socket.SocketKind = socket.SOCK_STREAM):
        self.name: str = name
        self.family: socket.AddressFamily = family
        self.socket_kind: socket.SocketKind = socket_kind
        self.ip: str = ip
        self.port: int = port
        # self.Router: Optional[IRouter] = None
        self.msgHandler: IMsgHandler = NewMsgHandler()
        self.connManager: IConManager = NewConnManager()
        self.OnConnStart = None     # 函数类型  钩子函数
        self.OnConnStop = None      # 函数类型  钩子函数

  在Server创建函数,将钩子函数相关方法进行实现。

    def SetOnConnStart(self, cb):
        """
        设置该Server的连接创建时Hook函数
        :param cb: 函数类型
        :return:
        """
        self.OnConnStart = cb

    def SetOnConnStop(self, cb):
        """
        设置该Server的连接断开时的Hook函数
        :param cb:函数类型
        :return:
        """
        self.OnConnStop = cb

    def CallOnConnStart(self, conn: IConnection):
        """
        调用连接OnConnStart Hook函数
        :param conn:
        :return:
        """
        if self.OnConnStart:
            print("---> CallOnConnStart....")
            self.OnConnStart(conn)

    def CallOnConnStop(self, conn: IConnection):
        """
        调用连接OnConnStop Hook函数
        :param conn:
        :return:
        """
        if self.OnConnStop:
            print("---> CallOnConnStart....")
            self.OnConnStop(conn)

  在Connection中设置钩子函数的运行位置。也就是Start函数和Stop函数。

    def Start(self):
        """
        启动链接 让当前的链接准备开始工作
        :return:
        """
        print("链接开启,ID=", self.ConnID)
        # 开启写业务
        g1 = gevent.spawn(self.StartWriter)
        # 开启读业务
        g2 = gevent.spawn(self.StartReader)
        GlobalGevents.append(g1)
        GlobalGevents.append(g2)
        # 按照用户传递进来的创建连接时需要处理的业务,执行钩子方法
        self.TcpServer.CallOnConnStart(self)

    def Stop(self):
        """
        停止链接 结束当前链接的工作
        :return:
        """
        print("链接关闭,ID=", self.ConnID)
        if self.is_closed:
            return
        self.is_closed = True

        # 如果用户注册了该链接的关闭回调业务,那么在此刻应该显示调用
        self.TcpServer.CallOnConnStop(self)
        # 关闭socket链接,回收资源
        self.Conn.close()
        # 将链接从连接管理器中删除
        self.TcpServer.GetConnMgr().Remove(self)

  服务接口做完了。在demo\hook中做一个客户端和服务端测试一下。
  服务端代码。

# -*- coding: utf-8 -*-
import sys

sys.path.append("../../")
from znet.server import NewServer
from znet.router import BaseRouter
from ziface.irequest import IRequest


class PingRouter(BaseRouter):
    """
    用户自定义路由
    """

    def __init__(self):
        super().__init__()

    def Handle(self, request: IRequest):
        """
        处理conn业务的方法
        :param request:
        :return:
        """
        try:
            print("调用Handle")
            # request.GetConnection().GetTCPConnection().send("ping\n".encode("GB2312"))
            print(request.GetData())
            request.GetConnection().SendMsg(1, "ping\n".encode("GB2312"))
            request.GetConnection().SendMsg(1, request.GetData())
        except Exception as e:
            print("ping异常", e)


def ConnectionStart(con):
    print("======Start========", con.GetConnID())


def ConnectionStop(con):
    print("======Stop========", con.GetConnID())


if __name__ == '__main__':
    server = NewServer()
    server.AddRouter(1, PingRouter())
    server.SetOnConnStart(ConnectionStart)
    server.SetOnConnStop(ConnectionStop)
    server.Serve()

  客户端代码与demo\msghandler一样即可。
  此时发送和接收都正常。钩子模块完成。

相关文章

  • Python网络爬虫

    Python开发简单爬虫(Python2.X版本,Eclipse工具) 一、爬虫介绍 爬虫调度端:启动、停止爬虫,...

  • Vue 基础 - 自定义指令和 render 函数

    自定义指令 类似组件可以全局注册和局部注册,使用derective注册。 钩子函数 指令定义函数提供了几个钩子函数...

  • 动画钩子函数

    如果想要实现自定义动画,此时就要用到 动画钩子函数 利用钩子函数实现了一个小球的动画:

  • 今日流程图

    问:自定义指令(v‐check、v‐focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?答:全局定义...

  • 五、自定义指令directive,插件的封装以及混合mixins

    一.自定义指令directive 钩子函数 一个指令定义对象可以提供如下几个钩子函数 (均为可选):bind:只调...

  • vue自定义指令,包装函数节流。

    自定义指令的钩子函数 Vue 提供了自定义指令的5个钩子函数: bind:指令第一次绑定到元素时调用,只执行一次。...

  • 理解什么是钩子函数

    在一个有序的步骤中的特殊位置(挂载点),插入自定义的内容。这就叫"钩子"。钩子函数:钩子函数是在一个事件触发的时候...

  • 在你的应用中添加关闭钩子

    概述 启动一个服务通常很容易. 但是, 有时我们需要在停止应用之前执行一个钩子函数,以便优雅的关闭我们的应用. 本...

  • 自定义指令、计算属性、侦听器

    四、自定义指令 钩子函数 一个指令定义对象可以提供如下几个钩子函数 (均为可选): bind:只调用一次,指令第一...

  • centos 7 安装coding的cci-agent服务

    前提 安装jdk 安装python3.6+yum 安装 或者自定义版本下载 安装cci-agent 创建开机启动服...

网友评论

      本文标题:Python版本Zinx——(10)链接启动/停止自定义钩子函数

      本文链接:https://www.haomeiwen.com/subject/uodmmdtx.html