⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gameserver.java

📁 一套MMORPG手机网络游戏的服务端
💻 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 + -