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

📄 selectandread.java

📁 一个MMORPG手机游戏的服务器端程序源代码
💻 JAVA
字号:
package zsw_mmorpg.server;import zsw_mmorpg.common.*;import zsw_mmorpg.server.controller.GameController;import zsw_mmorpg.server.controller.ShenzhouController;import zsw_mmorpg.log.zsw_out;import java.nio.*;import java.nio.channels.*;import java.io.*;import java.util.*;import org.apache.log4j.Logger;/** * SelectAndRead.java * * handles reading from all clients using a Selector * and hands off events to the appropriatae GameControllers * * @author <a href="mailto:shiwei@raymobile.com">朱世伟</a> * @version 1.0 */public class SelectAndRead extends Thread {    /** log4j 日志 */    private static Logger log = Logger.getLogger("SelectAndRead");    private LinkedList newClients;    private Selector selector;    private GameServer gameServer;    public SelectAndRead (GameServer gameServer){	this.gameServer = gameServer;	newClients = new LinkedList();    }    /**      * 添加新连接     */    public void addNewClient(SocketChannel clientChannel) {	synchronized (newClients) {	    newClients.addLast(clientChannel);	}	selector.wakeup();    }     /**     * 一直循环并检查新连接     */    public void run () {	try {	    selector = Selector.open();	    while (true) {		select();		checkNewConnections();		try { Thread.sleep(30); } catch (InterruptedException e) {}	    }	}	catch (IOException e) {	    log.fatal("exception while opening Selector", e);      	}    }     /**     * 检查新连接     */    private void checkNewConnections() {	synchronized(newClients) {	    while (newClients.size() > 0) {		try {		    SocketChannel clientChannel = (SocketChannel)newClients.removeFirst();		    clientChannel.configureBlocking( false);		    clientChannel.register( selector, SelectionKey.OP_READ, new Attachment());		}		catch (ClosedChannelException cce) {		    log.error("channel closed", cce);		}		catch (IOException ioe) {		    log.error("ioexception on clientChannel", ioe);		}	    }	}    }    /**     * 主要函数之一,用来读通道数据,     * 读到缓存里面,并把游戏事     * 件从数据包中解析出来     */    private void select() {	try {	    selector.select();	    Set readyKeys = selector.selectedKeys();	    Iterator i = readyKeys.iterator();	    while (i.hasNext()) {		SelectionKey key = (SelectionKey) i.next();		i.remove();		SocketChannel channel = (SocketChannel) key.channel();		Attachment attachment = (Attachment) key.attachment();		try {		// read		    long nbytes = channel.read(attachment.readBuff);		    // check for end		    if (nbytes == -1) {                System.out.println("disconnect: " + channel.socket().getInetAddress() +				 ", end-of-stream");			channel.close();//                System.out.println("channel.close();");            }        byte[] array = new byte[0];        int start = 0, end = 0;        if (attachment.readBuff.hasArray()) {            array = attachment.readBuff.array();            end = attachment.readBuff.position();        }        System.out.println("read  array:");     //zsw        NIOUtils.printHexValue(array, start, end);            // 检查完整事件		    try {			if (attachment.readBuff.position() >= attachment.HEADER_SIZE) {			    attachment.readBuff.flip();			    			    // 读缓存里,多个事件			    while(attachment.eventReady()) {				GameEvent event = getEvent(attachment);				delegateEvent(event, channel);				attachment.reset();			    }			    // 准备再读			    attachment.readBuff.compact();			}		    }		    catch (IllegalArgumentException e) {			log.error("illegal argument exception", e);		    }		}		catch (IOException ioe) {            System.out.println("IOException during read(), closing channel:" + channel.socket().getInetAddress());		    channel.close();//                System.out.println("channel.close();");        }	    }	}	catch (IOException ioe2) {	   System.out.println("IOException during select(): " + ioe2.getMessage());	} 	catch (Exception e) { 	    log.error("exception during select()", e); 	}    }     /**     * 从缓存里读事件     */    private GameEvent getEvent(Attachment attachment) {	GameEvent event = null;	ByteBuffer bb = ByteBuffer.wrap(attachment.payload);    bb.order(ByteOrder.LITTLE_ENDIAN);    GameController gc = gameServer.getGameController("RPS");    if (gc == null) {	    return null;	}	event = gc.createGameEvent();		event.read(bb);	return event;    }        /**     * 处理事件     */    private void delegateEvent(GameEvent event, SocketChannel channel) {	if (event == null) {	    log.error("delegateEvent error ,GameServer.handleEvent() : game event is null");	    return;	}	GameController gc = gameServer.getGameController("RPS");    if (gc == null) {	    log.error("delegateEvent error ,No GameController for gameName: " + event.getGameName());        return;    }        String pid =  event.getPlayerId();    Player p = GameServer.getPlayerById(pid);    if ((p != null)) {      //当前玩家在线        if (p.getChannel() != channel) {     //通道还不一样//		log.warn("player is on a new channel, must be reconnect.");          GameServer.getPlayerById("GM").setChannel(channel);     //用GM帐号保存该连接          p.setPlayer_logged(true);        }    }	else {	    // first time	    p = gc.createPlayer();	    p.setPlayerId(event.getPlayerId());	    p.setChannel(channel);        p.setPlayer_logged(false);        GameServer.addPlayer(p);	    log.debug("delegate event, new player created and channel set, player:" +		      p.getPlayerId() + ", channel: " + channel);    }        gc.handleEvent(event);        p.setPlayer_online_flag(true);      //在线      }}// SelectAndRead

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -