void CDaemonServer::process_server_info(const ServerInfoJson& json_obj, CConnection* connection) { //结果校验 if(json_obj.result != 0) { DAEMON_WARNING("query server info failed! stype = " << GetServerName(json_obj.type) << ", peer addr = " << connection->get_remote_addr()); element_map_.erase(json_obj.sid); return; } Inet_Addr tel_addr, cnc_addr; ServerElementMap::iterator it = element_map_.find(json_obj.sid); if(it != element_map_.end() && it->second.is_null() && json_obj.type == it->second.server_type_) //判断是否是重连 { it->second.null_ = false; it->second.tel_addr_.set_ip(json_obj.ip_ct); it->second.cnc_addr_.set_ip(json_obj.ip_un); it->second.net_type_ = json_obj.net_type; it->second.server_type_ = json_obj.type; tel_addr = it->second.tel_addr_; cnc_addr = it->second.cnc_addr_; } else //刚启动的SERVER { CDaemonElement element; uint16_t port = get_port(json_obj.type); tel_addr.set_ip(json_obj.ip_ct); tel_addr.set_port(port); cnc_addr.set_ip(json_obj.ip_un); cnc_addr.set_port(port); element.set_server_info(json_obj.type, json_obj.sid, json_obj.net_type, tel_addr, cnc_addr); element_map_[json_obj.sid] = element; } //建立节点关联关系 CONN_MANAGER()->add_server(json_obj.sid, json_obj.type, json_obj.net_type, tel_addr, cnc_addr); connection->set_server_id(json_obj.sid); CONN_MANAGER()->on_add_connection(connection); //发送响应 send_register_res(json_obj.type, json_obj.sid, json_obj.net_type, tel_addr, cnc_addr, connection); //发送通告 for(ServerElementMap::iterator eit = element_map_.begin(); eit != element_map_.end(); ++ eit) { if(json_obj.sid != eit->second.server_id_ && !eit->second.is_null()) //只发除自己以外激活的服务器 { eit->second.start_notify(json_obj.sid, json_obj.type, json_obj.net_type, tel_addr, cnc_addr); } } DAEMON_INFO("on add server, sid = " << json_obj.sid << ", stype = " <<GetServerName(json_obj.type) << ", net type = " << json_obj.net_type << ", tel_addr = " << tel_addr << ",cnc_addr = " << cnc_addr); }
int32_t CConnection::handle_close(BASE_HANDLER handle, ReactorMask close_mask) { CORE_DEBUG("handle_close"); if(state_ != CONN_IDLE) { //通知服务器节点管理模块 CONN_MANAGER()->on_del_connection(this); //通知上层连接断开 MSG_PROCESSOR()->on_disconnect(server_id_, this); sock_stream_.close(); reset(); //将连接对象返回给连接池 CONNECTION_POOL.push_obj(this); CORE_DEBUG("push conn = " << this); } else { sock_stream_.close(); } return 0; }
//类似STUN的消息,可以判断服务器的使用的外网地址,在core框架中可以选择性的开启 int32_t CDaemonServer::on_daemon_ping(CBasePacket *packet, uint32_t sid, const Inet_Addr &remote_addr) { Daemon_Stun_Ping *ping = (Daemon_Stun_Ping *)packet; INIT_CORE_REQUEST(msg, DAEMON_STUN_PONG); Daemon_Stun_Pong pong; pong.wan_addr_ = remote_addr; msg.set_data(pong); CONN_MANAGER()->send_udp(msg, remote_addr); DAEMON_INFO("on daemon ping from " << remote_addr); return 0; }
int32_t CConnection::handle_timeout(const void *act, uint32_t timer_id) { if(timer_id_ != timer_id) return -1; timer_id_ = 0; STCPTimerParam* param = (STCPTimerParam *)act; switch(param->timer_type_) { case eConnect_Timer: { delete param; if(state_ == CONN_CONNECTING) { CONN_MANAGER()->on_del_connection(this); //通知上层连接断开 MSG_PROCESSOR()->on_disconnect(server_id_, this); state_ = CONN_IDLE; CORE_DEBUG("CConnection, state = CONN_IDLE"); this->close(); } } break; case eTCP_Hearbeat: //心跳,PING保持 { if(heartbeat() == 0) { timer_id_ = REACTOR_INSTANCE()->set_timer(this, param, 60000); } else { delete param; } } break; } return 0; }
uint32_t CCoreDCClient::post_dc_request(uint32_t dc_sid, CoreDCParam* param, const string& php, const string& php_param, bool read_flag, bool ack /* = true */) { PHPExcRequst *body = new PHPExcRequst; if(param == NULL) { param = new CoreDCParam(); param->release_flag_ = true; param->event_ = NULL; } else param->release_flag_ = false; uint32_t exc_id = set_timer(param, body, read_flag ? DCENTERDELAY : 15000); body->exc_id = exc_id; body->exc_ret = ack ? 1 : 0; body->php_file = php; body->php_param = Base64::encode(php_param); body->time_delay = PHP_DELAY; body->exc_type = read_flag ? 1 : 2; Server_Node_t server_node = CONN_MANAGER()->find_server_info(dc_sid); if(server_node.server_id != 0) { ShortConnection* conn = SHORTCONN_POOL.pop_obj(); if(conn != NULL) { Inet_Addr src_addr, dst_addr; CONN_MANAGER()->get_address_pair(server_node, src_addr, dst_addr); src_addr.set_port(0); //随机一个端口作为客户机端口 if(src_addr.get_ip() != INADDR_ANY) { src_addr.set_port(30000 + rand() % 20000); } conn->set_proc(this); if(conn->connect(src_addr, dst_addr) != 0) { cancel_timer(exc_id); conn->reset(); SHORTCONN_POOL.push_obj(conn); return 0; } else { conn->set_conn_id(exc_id); if(param != NULL) { param->conn_ = conn; } } } } return exc_id; }