游戏服务器之长连接服务器实现tcp连接的数据异步收发。
特点如下:
(1)一个服务器进程含一个服务器对象
(2)服务器对象包含被动连接工厂和主动连接工厂
(3)两个工厂分别处理被动连接和主动连接
(4)被动连接和主动连接的网络收发都在在reactor的网络线程池里处理
(5)每个连接对应一个会话对象,接受的数据缓存在会话,在会话里反序列化和派送到具体的逻辑服务;会话发送数据时压入reactor网络线程池的队列里处理
1、服务器对象
在配置里配置服务器对象,是自己的名字就建立被动连接接收工厂,是其他的服务器对象,就连接过去。
class Server:
u"""
.服务器对象,各个服务都通过服务器对象,可进行
1)服务之间通讯
2)读取配置
.服务器对象主要的功能包括
1) 初始化
2)读取配置
3)装载服务
4)实现通讯机制
.服务器维护以下关键数据结构
1)路由表:当收到事件后需要查询路由表寻找事件的接收服务器
2)服务表:该表保存服务数据,服务和网络的关系
3)通讯频道表:该表保存当前的通道数据信息
"""
def __init__(self, conf):
self.conf = conf
self.channels = {}
self.route = {} # service_id: ServiceItem
self.services = {} # service_id: service object
self.lock = Lock()
self.name = conf.myself.name
log.info("temp forbid init server data")
self.init_server_data()
# create route table
for s in conf.servers:
for svcId, svc in s.services.items():
self.route[svcId] = ServiceItem(svcId, s.name)#路由表存储所有的服务器对象
set_server(self)
def init_server_data(self):
log.info("init system")
ServerData.init_system()
#log.info("begin init data")
#ServerData.init_load()
def getServerConfig(self, serverName):
u"""获得指定服务器的配置信息"""
for server in self.conf.servers:
if server.name == serverName:
return server
return None
def getServiceConfig(self, serviceId):
u"""获得指定服务的配置信息"""
return self.conf.myself.services[serviceId]
# ----- channel & service ------------------------------------------------
def requestCreateChannel(self, target, transport):
u"""
. 网络层在网络协议建立后,请求服务器对象建立和对端Server的通讯频道
1)服务器对象创建Channel对象
2)服务器对象为每个服务设置通讯Channel"""
channel = Channel(transport)
self.channels[target] = channel
for k, v in self.route.items():
if v.serverName == target:
v.channel = channel
log.info(u"service (%d) is in the server(%s)", k, target)
log.info(u"[%s] : server(%s) is connected", self.name, target)
channel.setListener(self)
return channel
def requestDestroyChannel(self, target):
u"""
.网络层在网络协议断连后,请求服务器对象销毁和对端Server的通讯频道
1)服务器对象销毁Channel对象
2)服务器对象设置相应服务Channel=None,后续发给该服务的消息将无法送达
"""
del self.channels[target]
for k, v in self.route.items():
if v.serverName == target:
v.channel = None
log.info(u"server(%s) is disconnected", target)
def getChannel(self, serviceId):
item = self.route[serviceId]
if item != None:
return item.channel
return None
def registeService(self, service):
u"""服务注册函数,服务注册成功后,则可以收发消息"""
self.services[service.serviceId] = service
def unregisteService(self, service):