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

📄 selectandread.java

📁 利用java实现的多人游戏的服务器系统
💻 JAVA
字号:
package com.hypefiend.javagamebook.server;import com.hypefiend.javagamebook.common.GameEvent;import com.hypefiend.javagamebook.common.Player;import com.hypefiend.javagamebook.common.Attachment;import com.hypefiend.javagamebook.server.controller.GameController;import java.nio.*;import java.nio.channels.*;import java.io.*;import java.util.*;import java.net.Socket;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:bret@hypefiend.com">bret barker</a> * @version 1.0 */public class SelectAndRead extends Thread {    /** log4j logger */    private static Logger log = Logger.getLogger("SelectAndRead");    /** pending connections */    private LinkedList newClients;    //    /** timeout for the selector's select() call */    //    private static final long SELECT_TIMEOUT = 250;    /** the selector, multiplexes access to client channels */    private Selector selector;    /** reference to the GameServer */    private GameServer gameServer;    /**     * Constructor.     */    public SelectAndRead (GameServer gameServer){	this.gameServer = gameServer;	newClients = new LinkedList();    }        /**      * adds to the list of pending clients     */    public void addNewClient(SocketChannel clientChannel) {	synchronized (newClients) {	    newClients.addLast(clientChannel);	}	// force selector to return	// so our new client can get in the loop right away	selector.wakeup();    }        /**      * loop forever, first doing our select()      * then check for new connections     */    public void run () {	try {	    selector = Selector.open();	    while (true) {		select();		checkNewConnections();		// sleep just a bit		try { Thread.sleep(30); } catch (InterruptedException e) {}	    }	}	catch (IOException e) {	    log.fatal("exception while opening Selector", e);      	}    }        /**     * check for new connections     * and register them with the selector     */    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);		}	    }	}    }    /**      * do our select, read from the channels     * and hand off events to GameControllers     */    private void select() {	try {	    // this is a blocking select call but will 	    // be interrupted when new clients come in	    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 from the channel		    long nbytes = channel.read(attachment.readBuff);		    // check for end-of-stream condition		    if (nbytes == -1) {			log.info("disconnect: " + channel.socket().getInetAddress() + 				 ", end-of-stream");			channel.close();		    }		    // check for a complete event		    try {			if (attachment.readBuff.position() >= attachment.HEADER_SIZE) {			    attachment.readBuff.flip();			    			    // read as many events as are available in the buffer			    while(attachment.eventReady()) {				GameEvent event = getEvent(attachment);				delegateEvent(event, channel);				attachment.reset();			    }			    // prepare for more channel reading			    attachment.readBuff.compact();			}		    }		    catch (IllegalArgumentException e) {			log.error("illegal argument exception", e);		    }		}		catch (IOException ioe) {		    log.warn("IOException during read(), closing channel:" + channel.socket().getInetAddress());		    channel.close();		}	    }	}	catch (IOException ioe2) {	    log.warn("IOException during select(): " + ioe2.getMessage());	} 	catch (Exception e) { 	    log.error("exception during select()", e); 	}    }    /**     * read an event from the attachment's payload     */    private GameEvent getEvent(Attachment attachment) {	GameEvent event = null;	ByteBuffer bb = ByteBuffer.wrap(attachment.payload);	// get the controller and tell it to instantiate an event for us	GameController gc = gameServer.getGameControllerByHash(attachment.gameNameHash);	if (gc == null) {	    return null;	}	event = gc.createGameEvent();		// read the event from the payload	event.read(bb);		return event;    }      /**     * pass off an event to the appropriate GameController     * based on the GameName of the event     */    private void delegateEvent(GameEvent event, SocketChannel channel) {	if (event != null && event.getGameName() == null) {	    log.error("GameServer.handleEvent() : gameName is null");	    return;	}	GameController gc = gameServer.getGameController(event.getGameName());	if (gc == null) {	    log.error("No GameController for gameName: " + event.getGameName());	    return;	}	Player p = gameServer.getPlayerById(event.getPlayerId());	if (p != null) {	    if (p.getChannel() != channel) {		log.warn("player is on a new channel, must be reconnect.");		p.setChannel(channel);	    }	}	else {	    // first time we see a playerId, create the Player object	    // and populate the channel, and also add to our lists	    p = gc.createPlayer();	    p.setPlayerId(event.getPlayerId());	    p.setChannel(channel);	    gameServer.addPlayer(p);	    log.debug("delegate event, new player created and channel set, player:" + 		      p.getPlayerId() + ", channel: " + channel);	}			gc.handleEvent(event);    }}// SelectAndRead

⌨️ 快捷键说明

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