📄 gameserver.java
字号:
/*
* Created on 2005-4-20
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package com.swing.server.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import com.swing.server.common.GameEvent;
import com.swing.server.common.Globals;
import com.swing.server.common.Lifecycle;
import com.swing.server.common.LifecycleException;
import com.swing.server.cfg.Configure;
import com.swing.server.server.controller.DefaultGameController;
import com.swing.server.server.controller.GameController;
/**
* @author vampire_a
*
* 全局唯一的Server,负责初始化其他所有部件,一个Server可以挂接一个输入接口SelectAndRead、一个
* 输出接口EventWriter和1...N个事件处理模块GameController
*/
public class GameServer implements Runnable, Lifecycle {
/** log4j Logger */
private Logger log = Logger.getLogger("GameServer");
/** ServerSocketChannel for accepting client connections */
private ServerSocketChannel sSockChan;
/** selector for multiplexing ServerSocketChannels */
private Selector selector;
/** GameControllers keyed by GameName */
private Map gameControllers;
public GameController defaultController = new DefaultGameController();
/** players keyed by playerId */
private static Hashtable playersByPlayerId;
private boolean running;
private SelectAndRead selectAndRead;
private EventWriter eventWriter;
private static long nextSessionId = 0;
private boolean ifRun;
public void stop() throws LifecycleException {
log.info("-----Start Exiting GameServer-----");
selector.wakeup();
ifRun = false;
for (Iterator i = gameControllers.values().iterator(); i.hasNext();) {
((GameController) i.next()).stop();
i.remove();
}
playersByPlayerId.clear();
playersByPlayerId = null;
selectAndRead.stop();
selectAndRead = null;
eventWriter.stop();
eventWriter = null;
selector = null;
sSockChan = null;
}
public void start() throws LifecycleException {
ifRun = true;
Thread t = new Thread(this);
t.start();
}
/**
* main. setup log4j and fireup the GameServer
*/
public static void main(String args[]) {
PropertyConfigurator.configure(Globals.LOG4J_FILE);
GameServer gs = new GameServer();
try {
gs.start();
} catch (LifecycleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* constructor, just initialize our hashtables
*/
public GameServer() {
gameControllers = new Hashtable();
playersByPlayerId = new Hashtable();
defaultController.init(this);
}
/**
* init the GameServer, startup our workers, etc.
*/
public void init() {
log.info("GameServer initializing");
loadGameControllers();
initServerSocket();
selectAndRead = new SelectAndRead(this);
try {
selectAndRead.start();
} catch (LifecycleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int number = Integer.parseInt((String) Configure.getConfigure()
.getConfig("Server").get("Event_Writer_Workers"));
eventWriter = new EventWriter(this, number);
}
/**
* GameServer specific initialization, bind to the server port, setup the
* Selector, etc.
*/
private void initServerSocket() {
try {
// get a selector
selector = Selector.open();
Map serverConfig = Configure.getConfigure().getConfig("Server");
// 初始化游戏端口
int gamePort = Integer.parseInt((String) serverConfig
.get("GamePort"));
String ip = (String) serverConfig.get("IP");
sSockChan = ServerSocketChannel.open();
sSockChan.configureBlocking(false);
log.info("binding to address: " + ip + " port: "
+ gamePort);
sSockChan.socket().bind(new InetSocketAddress(ip, gamePort));
SelectionKey acceptKey = sSockChan.register(selector,
SelectionKey.OP_ACCEPT);
// 初始化管理端口
int adminPort = Integer.parseInt((String) serverConfig
.get("AdminPort"));
sSockChan = ServerSocketChannel.open();
sSockChan.configureBlocking(false);
log.info("binding to address: " + ip + " port: "
+ adminPort);
sSockChan.socket().bind(new InetSocketAddress(ip, adminPort));
acceptKey = sSockChan.register(selector, SelectionKey.OP_ACCEPT);
} catch (Exception e) {
log.error("error initializing ServerSocket", e);
System.exit(1);
}
}
/**
* Here's the meat, loop over the select() call to accept socket connections
* and hand them off to SelectAndRead
*/
public void run() {
init();
log.info("******** GameServer running ********");
running = true;
int numReady = 0;
while (running) {
// note, since we only have one ServerSocket to listen to,
// we don't need a Selector here, but we set it up for
// later additions such as listening on another port
// for administrative uses.
try {
// blocking select, will return when we get a new connection
selector.select();
// fetch the keys
Set readyKeys = selector.selectedKeys();
// run through the keys and process
Iterator i = readyKeys.iterator();
while (i.hasNext()) {
SelectionKey key = (SelectionKey) i.next();
i.remove();
ServerSocketChannel ssChannel = (ServerSocketChannel) key
.channel();
SocketChannel clientChannel = ssChannel.accept();
// add to the list in SelectAndRead for processing
selectAndRead.addNewClient(clientChannel);
log.info("got connection from: "
+ clientChannel.socket().getInetAddress());
}
} catch (IOException ioe) {
log.warn("error during serverSocket select(): "
+ ioe.getMessage());
} catch (Exception e) {
log.error("exception in run()", e);
}
}
}
public GameController getGameControllerByCode(String gameCode) {
GameController gc = (GameController) gameControllers.get(gameCode);
if (gc == null)
log.error("no gamecontroller for gameCode: " + gameCode);
return gc;
}
/**
* finds the GameController for a given GameName hash code
*/
public GameController getGameControllerByCode(int gameCode) {
return getGameControllerByCode(String.valueOf((char) gameCode));
}
/**
* Dynamically loads GameControllers
*/
private void loadGameControllers() {
log.info("loading GameControllers");
Map controllers = Configure.getConfigure().getConfig("Controller");
for (Iterator i = controllers.values().iterator(); i.hasNext();) {
String controllerClassName = (String) i.next();
log.info("loading class: " + controllerClassName);
try {
Class cl = Class.forName(controllerClassName);
if (!GameController.class.isAssignableFrom(cl)) {
log.warn("class file does not extend GameController: "
+ controllerClassName.substring(controllerClassName
.lastIndexOf(".")));
continue;
}
// get an instance and initialize
GameController gc = (GameController) cl.newInstance();
// 在这里面读取对应的配置文件,以得到跟自己相关的一些设置
gc.init(this);
String gameCode = gc.getGameCode();
// add to our controllers hash
gameControllers.put(gameCode, gc);
log.info("loaded controller for gameCode: " + gameCode);
} catch (Exception cne) {
log.error("Error instantiating GameController from file: "
+ controllerClassName, cne);
}
}
}
/**
* pass the event on to the EventWriter
*/
public void writeEvent(GameEvent e) {
eventWriter.handleEvent(e);
}
}// GameServer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -