示例#1
0
class NetworkServerBase:
    def __init__(self, port):
        self.host = "0.0.0.0"
        self.port = port
        self.server_fd = None
        self.state = config.SERVER_STOP
        self.logger = Log()

    def _close_fd(self):
        try:
            self.server_fd.shutdown(socket.SHUT_RDWR)
            self.server_fd.close()
        except IOError as e:
            self.logger.error("net socket close fail err: " + str(e.errno) +
                              " " + e.strerror)

    def _network_start(self):
        self.server_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_fd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        try:
            self.server_fd.bind((self.host, self.port))
        except IOError as e:
            self._close_fd()
            self.logger.error("server bind fail. msg: " + str(e.errno) + " " +
                              e.strerror)
            return

        self.server_fd.listen(config.MAX_LISTEN_QUEUE_SIZE)
        self.server_fd.setblocking(False)
        self.port = self.server_fd.getsockname()[1]
        self.state = config.SERVER_ESTABLISHED
        self.logger.info("server established. port:" + str(self.port))
示例#2
0
class WorkerPool:
    def __init__(self, mode=None):
        self.mode = mode  # 默认使用单进程单线程模式
        self.logger = Log()
        self.conn_pool = None

        # key = id, value = FunctionHandler. int 到函数的映射
        self.handler_dict = {}
        # 通用工具集
        self.common_tools = CommonTools()

        # 多进程 删掉了 并没有什么用
        self.process_count = 1
        self.process_pool = None
        # 单进程模式下处理完的事件丢到这里,后面主循环处理发回客户端
        self.response_queue = []
        self.auto_incr = 0

    def init(self, conn_pool, process_count=4):
        self.conn_pool = conn_pool
        if process_count < 1 or process_count > 10:
            process_count = 1
        self.process_count = process_count

    def start(self):
        self.common_tools.init(self.handler_dict)
        self.logger.info("worker pool. light mode")
        self.logger.info("work process start success")

    def stop(self):
        pass

    def add_handler(self, handler, controller):
        if isinstance(handler, int) and isinstance(controller,
                                                   FunctionHandler):
            self.handler_dict[handler] = controller

    def del_handler(self, handler):
        if handler in self.handler_dict.keys():
            del self.handler_dict[handler]

    # 在框架IO层,处理好 [消息] 后调用.
    # 需要路由到具体逻辑代码
    # 最后调用 self.conn_pool.send_event(conn_id, res), res 会在合适的时候发给客户端
    def message_handler(self, conn_id, msg):
        req = Request(conn_id, msg)
        res = Response(conn_id)
        handler = req.get_handler()
        if handler in self.handler_dict.keys():  # 根据 request 哈希到具体函数
            self.handler_dict[handler].run(self.common_tools, req, res)
            for v in res.msg_queue:
                if isinstance(v, Response):
                    v.pack_buffer(req.msg.get_handler())
                    v.msg.encryption()
                    self.response_queue.append(v)
            res.msg_queue = []
            self.response_queue.append(res)

    def update(self):
        self.common_tools.update()
        self.message_consumer()

    # 消费处理好的 response,发向客户端
    def message_consumer(self):
        if len(self.response_queue):
            res = self.response_queue[0]
            self.response_queue = self.response_queue[1:]
            self.conn_pool.send_handler(res.conn_id, res.msg)
示例#3
0
class Server:
    def __init__(self, name, uuid):
        self.os_name = platform.system()
        self.python_version = platform.python_version().split(".")[0]

        self.server_name = name
        self.server_id = uuid

        self.network_server = None
        self.work_process = None
        self.logger = Log()
        self.conf_loader = ConfigLoader()

    def add_handler(self, handler_func):
        try:
            self.work_process.add_handler(handler_func.handler_id,
                                          handler_func)
            self.logger.info("add handler " + str(handler_func.handler_id))
        except Exception as e:
            self.logger.error("work process not init." + e.message)

    # 预选择服务器IO模式 epoll有bug,连接无法安全断开. select实测没light快 囧。。。
    def pre_bind_io_mode(self, port, mode):
        if not isinstance(mode, str):
            return False
        if mode.__eq__("epoll") and hasattr(select, 'epoll'):
            self.network_server = Epoll(port)
            self.logger.info("network mode epoll")
            return True
        if mode.__eq__("epoll_et") and hasattr(select, 'epoll'):
            self.network_server = Epoll(port, use_et=True)
            self.logger.info("network mode epoll et")
            return True
        if mode.__eq__("select") and hasattr(select, 'select'):
            self.network_server = Select(port)
            self.logger.info("network mode select")
            return True
        if mode.__eq__("light"):
            self.network_server = LightServer(port)
            self.logger.info("network mode light server")
            return True
        return False

    def start(self, port=None, mode=None):

        if port is None:
            port = self.conf_loader.get_int("port", 0)

        if not self.pre_bind_io_mode(port, mode):
            if hasattr(select, 'epoll'):
                self.network_server = Epoll(port)
                self.logger.info("network mode epoll lt")
            elif hasattr(select, 'select'):
                self.network_server = Select(port)
                self.logger.info("network mode select")
            else:
                self.network_server = LightServer(port)
                self.logger.info("network mode light server")

        self.work_process = WorkerPool(mode="light")  # light, multi

        self.network_server.init(self.work_process)
        self.work_process.init(self.network_server.conn_pool, 4)

        self.network_server.start()

    def run(self):
        if self.network_server is None:
            self.logger.error("server instance is None")
            return
        if self.network_server.state == SERVER_ESTABLISHED:
            self.work_process.start()
            self.network_server.run()

    def stop(self):
        self.work_process.stop()