Go语言爱好者周刊笔记-tcpserver & graceful

2020-05-08  本文已影响0人  路人爱早茶

什么是框架

把变化交给用户,把不变留给自己,面向接口编程

案例

tcpsever实现
监听类型
监听地址
客户端连接处理

将三部分作为参数传递

srv := tcpserver.NewServer(
    tcpserver.Network("tcp"),
    tcpserver.Address(":8080"),
    tcpserver.Handler(MyHandler),
)

tcpsever.handler传入是函数对象,如此定义

type connectionHandler func(context.context,net.conect)error

函数签名中最重要是net.conn参数,作为独立参数直接定义,上下文参数context,上下文可以传递各种变量信号与上层中断信号。
最后是启动与关闭函数

func (srv *Server) Serve(ctx context.Context) error {
    //TODO
    return nil
}

func (srv *Server) Close() {
    //TODO
}

graceful shutdown功能实现

//Close tcpserver waiting all connections finished
func (srv *Server) Close() {
    //触发关闭信号
    close(srv.closed)
    //等待客户端连完成
    srv.wgroup.Wait()
}

//Serve tcpserver serving
func (srv *Server) Serve(ctx context.Context) error {
    ln, err := net.Listen(srv.network, srv.address)//开启监听
    ...
    for {
        select {
        case <-ctx.Done():
            return ctx.Err()
        case <-srv.closed: //收到关闭信号
            log.Println("tcpserver is closing ...")
            return ln.Close()//关闭监听
        ...
    }
    ...
}

由于serve.Serve函数在for循环中一直阻塞在Accept()函数处,所以原代码中使用close chan的方式触发关闭过程失败。新版本直接通过关闭Listener的方式触发关闭。

//Close tcpserver waiting all connections finished
func (srv *Server) Close() {
    //关闭监听,触发关闭信号
    srv.Listener.Close()
    //等待客户端连完成
    srv.wgroup.Wait()
}
上一篇 下一篇

猜你喜欢

热点阅读