Git Product home page Git Product logo

menacher / java-game-server Goto Github PK

View Code? Open in Web Editor NEW
1.3K 1.3K 558.0 39.85 MB

Jetserver is a high speed nio socket based multiplayer java game server written using Netty and Mike Rettig's Jetlang.It is specifically tuned for network based multiplayer games and supports TCP and UDP network protocols.

License: MIT License

Java 90.79% ActionScript 6.94% JavaScript 1.72% HTML 0.49% AngelScript 0.07%

java-game-server's People

Contributors

endercool39 avatar menacher avatar mumulean avatar omijagtap avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-game-server's Issues

JetEvent deserialization under AMF3 protocol on flash client. messageBuffer is null.

Hello, menacher.
Thank you for your jet server.

I have next trouble. If I use MessageBufferProtocol on Jet Server and on flash client then all fine, I can send and receive message in both ways.

But if I try use the AMF3 protocol on flash client:
in SessionFactory.as:
public function createAndConnectSession():Session {
var session:Session = createSession();
connectSession(session, new AMF3Protocol(), new LoginInOutCodecs());
return session;
}

and on jet server in ZombieSpringConfig.java:
@Autowired
@qualifier("amf3Protocol")
private Protocol messageBufferProtocol;

in debug mode I get next exception on flash client on incoming message in Main.as:
private function traceData(event:Event):void{
var jetEvent:JetEvent = event as JetEvent;
var messageBuffer:MessageBuffer = jetEvent.getSource() as MessageBuffer;
var buffer:ByteArray = messageBuffer.getBuffer();
trace("Remaining Human Population: " + buffer.readInt());

[Fault] exception, information=TypeError: Error #1009: messageBuffer is null here.
jetEventType = 28 [0x1c], source = Object ( @ 4e92fb9 ), timestamp = 1356590891591 [0x13bdb1e4247] , but messageBuffer is null after jetEvent.getSource() as MessageBuffer operation, and I not can read received buffer.

How to solve this trouble?

AnnotationConfigApplicationContext fails

I have rebuild jetserver.jar and jetclient.jar and put new libraries in my project.
Now I keep getting this error at server, so client cannot connect. My beans.xml was not updated.

AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

Can you advice what is wrong?

2012-12-30 01:27:28,169 [SimpleSaxErrorHandler.java:47][WARN]:Ignored XML validation warning
org.xml.sax.SAXParseException: SchemaLocation: schemaLocation value = 'http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util/spring-util-3.0.xsd' must have even number of URI's.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.warning(ErrorHandlerWrapper.java:96)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:380)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:423)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.storeLocations(XMLSchemaValidator.java:2365)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1776)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:711)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:400)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:626)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3104)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:921)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:647)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:232)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)
    at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:255)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:196)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:181)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:140)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:111)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:239)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:196)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:181)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:140)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:111)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromImportedResources(ConfigurationClassBeanDefinitionReader.java:293)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:118)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:105)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:261)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:178)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:617)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:446)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
    at org.server.Server.main(Server.java:23)

onLogin playerSession.getPlayer() is null

public class ConnectGameRoom extends GameRoomSession {

    @Override
public void onLogin(PlayerSession playerSession)
{
    System.out.println(playerSession.getPlayer() == null);
    }

}

prints true. Why is it so?

Make inter-session messaging synchronous.

The event dispatch is now very fine grained. Inter session messages run on the same thread are placed on the queue un-necessarily. Dispatch in this scenario should be via normal method calls i.e coarse grained.

The resolution is to write a Lane feature which will detect if the publishing thread is the on the same "lane" as the current session's lane. If so, it will do synchronous dispatch.

In intial micro benchmarking performance of jetlang dispatcher has shown a tripling in performance! A branch has been created for this feature https://github.com/menacher/java-game-server/tree/Lane

Refactor "I" from interface names

The leading letter "I" in interfaces is really annoying when you program against interfaces, which you almost always do, when dealing with Spring Framework powered applications.
I'm evaluating JetServer as a core for a game I'm planning to develop, but I'll have to fork it and refactor each I[InterfaceName] to [InterfaceName] myself and then sync changes from the original project every time a bug is fixed or an interesting feature is added. This isn't a deal-breaker of course, but a nuisance I'm not looking forward to :(
I do understand that such kind of change would break the API, and I also understand that prepending or not interface names with a letter "I" is a bit holywar-ish, but I just had to try :)

param charSet ignored in NettyUtils.writeStrings(Charset charSet, String... msgs)

When I read the source code of method writeStrings(..) of class NettyUtils in jetserver, it seems to me that this line

ChannelBuffer theBuffer = writeString(msg);

should be

ChannelBuffer theBuffer = writeString(msg, charSet);

because the param charSet is not used otherwise.

Here is the original code:

public static ChannelBuffer writeStrings(Charset charSet, String... msgs)
{
    ChannelBuffer buffer = null;
    for (String msg : msgs)
    {
        if (null == buffer)
        {
            buffer = writeString(msg,charSet);
        }
        else
        {
            ChannelBuffer theBuffer = writeString(msg); // <--------- line in question
            if(null != theBuffer)
            {
                buffer = ChannelBuffers.wrappedBuffer(buffer,theBuffer);
            }
        }
    }
    return buffer;
}

Excuse me I have another question:
How and where to ask question like "what is the recommended way to add signup, password changing etc. features when using jetserver"?

Thanks a lot for this great open source project!

How to use ProxySelector?

I am trying to use standard ProxySelector described here at client side:
http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html

Even though I register it in main

public static void main(String[] args) {
        MyProxySelector ps = new MyProxySelector(ProxySelector.getDefault());
        ProxySelector.setDefault(ps);

select and connectFail methods are never got called, instead it is processed by netty I guess.

The goal is to handle connection fail event, ask user for a proxy details and request next connection via proxy. How can I achieve that?

Exception caught: 
java.nio.channels.ClosedChannelException
    at org.jboss.netty.channel.socket.nio.NioWorker.cleanUpWriteBuffer(NioWorker.java:645)
    at org.jboss.netty.channel.socket.nio.NioWorker.writeFromUserCode(NioWorker.java:372)
    at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventSunk(NioClientSocketPipelineSink.java:127)
    at org.jboss.netty.channel.Channels.write(Channels.java:632)
    at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:70)
    at org.jboss.netty.channel.Channels.write(Channels.java:611)
    at org.jboss.netty.channel.Channels.write(Channels.java:578)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:251)

Exception caught: 
java.net.ConnectException: connection timed out
    at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.processConnectTimeout(NioClientSocketPipelineSink.java:388)
    at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.run(NioClientSocketPipelineSink.java:299)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

NPE at MessageBufferProtocol.java:40

Sometimes (not always) I see this error in log

Exception in thread "Lane[45]" java.lang.NullPointerException at org.menacheri.jetserver.protocols.impl.MessageBufferProtocol.applyProtocol(MessageBufferProtocol.java:40)
        at org.menacheri.jetserver.protocols.AbstractNettyProtocol.applyProtocol (AbstractNettyProtocol.java:50)

Line 40 is
pipeline.addLast("lengthDecoder", createLengthBasedFrameDecoder());

gameRoom is an instance of extended GameRoomSession, connectSession was not overriden.

//issue 9 at github
NettyUtils.clearPipeline(NettyUtils.getPipeLineOfConnection(request));

gameRoom.connectSession(request); //error in here

request is instance of PlayerSession. Do you need to delete NettyUtils.clearPipeline to avoid this error happening?

Null pointer exception in ObjectEncoderWrapper

public static class ObjectEncoderWrapper extends ObjectEncoder {
protected ChannelBuffer encode(Object msg) throws Exception {
ChannelBuffer objBuffer = (ChannelBuffer) super.encode(null, null, msg);
return objBuffer;
}
}

According to the ObjectEncoder's source, the first argument must not be null, otherwise it will throw a null point exception.

gameRoom.sendBroadcast(networkEvent) duplicates the message

At server side I create a new GameRoomSession, add existing session there

NettyMessageBuffer outBuf = new NettyMessageBuffer();
outBuf.writeBytes(outHeader.toByteArray());
NetworkEvent networkEvent = Events.networkEvent(outBuf);
gameRoom.sendBroadcast(networkEvent);

executed at server only once. gameRoom has only 1 session.

At client:
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
ChannelBuffer buffer = (ChannelBuffer) event.getSource();
System.out.println("NETWORK_MESSAGE received!");

appears twice and content is identical.
NETWORK_MESSAGE received!
MESSAGE_TYPE Fri Sep 07 17:29:14 KST 2012

Any idea?

org.springframework.beans.factory.BeanDefinitionStoreException

The project has been configured by your tutorial http://github.com/menacher/java-game-server#steps
I am trying to export example-games as Runnable Jar, and on execute (java -jar example-games.jar) I get an exception:

Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: org.menacheri.zombie.game.ZombieSpringConf
ig; nested exception is java.io.FileNotFoundException: class path resource [org/menacheri/zombie/game/ZombieSpringConfig.class] cannot be opened because it does
 not exist
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:240)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:178)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:617)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:446)
        at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
        at org.menacheri.GameServer.main(GameServer.java:27)
Caused by: java.io.FileNotFoundException: class path resource [org/menacheri/zombie/game/ZombieSpringConfig.class] cannot be opened because it does not exist
        at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:158)
        at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:45)
        at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:80)
        at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:101)
        at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:76)
        at org.springframework.context.annotation.ConfigurationClassParser.findAllAnnotationAttributes(ConfigurationClassParser.java:248)
        at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:206)
        at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:138)
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:126)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:233)
        ... 5 more 

How to disable log4j for applet?

There is line in the code

PropertyConfigurator.configure(properties);

If run my app as applet it generates this error/warning in Java Plugin Console. This is normal behavior because applet is not supposed to perform external io operations. But how I can disable log with out any warnings?

java.security.AccessControlException: access denied ("java.io.FilePermission" "log\GameClient.log" "write")
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkWrite(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
    at org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:207)
    at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
    at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:307)
    at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:172)
    at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:104)
    at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:809)
    at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:735)
    at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:615)
    at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:502)
    at org.apache.log4j.PropertyConfigurator.configure(PropertyConfigurator.java:428)
log4j:WARN No appenders could be found for logger (org.evogame.client.swing.AppletApp).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more 

If I comment the code line still

AppletApp.init()
log4j:WARN No appenders could be found for logger (org.evogame.client.swing.AppletApp).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
basic: Applet initialized

interaction of GameRoom and SessionHandler

Currently I have GameRoom extended from GameRoomSession, several PlayerSession attached and for each session there is a SessionHandler as listener.

Now where should I implement logic for the GameRoom?

Once SessionHandler.onDataIn receives a packet from the client I need to apply the message according to the GameRoom state. Should I keep the state inside the GameRoom object, then pass reference to GameRoom inside SessionHandler and call methods of GameRoom from SessionHandler?

Is this expected design? Thanks

onException/onDisconnect/onClose are not delivered to DefaultSessionEventHandler

I have following scenario. There are 3 players in the game room, so there are 3 SessionHandlers. I shutdown one of the players. So it is SessionHandler detects that and prints onException. Then I have a code inside ServerGameManager that sends a NETWORK_MESSAGE to other clients of the same game to shutdown also.
But for two other clients handlers of their SessionHandlers are never called.

public class SessionHandler extends DefaultSessionEventHandler {

    //example

    @Override
    protected void onException(Event event) {
         System.out.println("onException");
    } 

    @Override
    protected void onDisconnect(Event event) {
         System.out.println("onDisconnect");
    } 

    @Override
    protected void onClose(Event event) {
         System.out.println("onClose");
    } 
2013-04-23 15:22:07,841 [DefaultToServerHandler.java:49][ERROR]:Exception in DefaultToServerHandler class: [id: 0x03ecf7ad, /10.254.215.116:60277 => /10.254.215.116:81] EXCEPTION: java.io.IOException: An existing connection was forcibly closed by the remote host.
2013-04-23 15:22:07,842 [DefaultToServerHandler.java:60][DEBUG]:Channel 65861549 is disconnected, raising the event to session
2013-04-23 15:22:07,842 [SessionHandler.java:60][ERROR]:GAMEROOM1 PLAYER[0] onException
2013-04-23 15:22:07,842 [DefaultToServerHandler.java:78][DEBUG]:Channel 65861549 is closed and resources released
2013-04-23 15:22:07,842 [NettyTCPMessageSender.java:57][INFO]:Going to close tcp connection in class: org.menacheri.jetserver.communication.NettyTCPMessageSender
2013-04-23 15:22:07,842 [NettyTCPMessageSender.java:66][WARN]:Unable to write the Event Event [type=34, source=null, timeStamp=1366698127842] with type 34 to socket
2013-04-23 15:22:07,843 [JetlangEventDispatcher.java:260][TRACE]:Entered removeHandlersForSession for session PlayerSession [id=1player=org.menacheri.jetserver.app.impl.DefaultPlayer@d5904c89, parentGameRoom=org.evogame.server.RealGameRoom@50, protocol=null, isShuttingDown=true]
2013-04-23 15:22:07,843 [JetlangEventDispatcher.java:272][TRACE]:Going to remove 1 handlers for session: PlayerSession [id=1player=org.menacheri.jetserver.app.impl.DefaultPlayer@d5904c89, parentGameRoom=org.evogame.server.RealGameRoom@50, protocol=null, isShuttingDown=true]
2013-04-23 15:22:07,843 [JetlangEventDispatcher.java:284][TRACE]:Going to clear handlers on dispatcher org.menacheri.jetserver.event.impl.JetlangEventDispatcher@925c95
2013-04-23 15:22:07,843 [ServerGameManager.java:145][INFO]:GAMEROOM1 PLAYER[0] has disconnected!
2013-04-23 15:22:07,854 [DefaultToServerHandler.java:60][DEBUG]:Channel 476923117 is disconnected, raising the event to session
2013-04-23 15:22:07,854 [DefaultToServerHandler.java:78][DEBUG]:Channel 476923117 is closed and resources released
2013-04-23 15:22:07,854 [DefaultSessionEventHandler.java:179][DEBUG]:Received disconnect event in session. Going to close session
2013-04-23 15:22:07,854 [NettyTCPMessageSender.java:57][INFO]:Going to close tcp connection in class: org.menacheri.jetserver.communication.NettyTCPMessageSender
2013-04-23 15:22:07,854 [NettyTCPMessageSender.java:66][WARN]:Unable to write the Event Event [type=34, source=null, timeStamp=1366698127854] with type 34 to socket
2013-04-23 15:22:07,855 [JetlangEventDispatcher.java:260][TRACE]:Entered removeHandlersForSession for session PlayerSession [id=2player=org.menacheri.jetserver.app.impl.DefaultPlayer@3c452253, parentGameRoom=org.evogame.server.RealGameRoom@50, protocol=null, isShuttingDown=true]
2013-04-23 15:22:07,855 [JetlangEventDispatcher.java:272][TRACE]:Going to remove 1 handlers for session: PlayerSession [id=2player=org.menacheri.jetserver.app.impl.DefaultPlayer@3c452253, parentGameRoom=org.evogame.server.RealGameRoom@50, protocol=null, isShuttingDown=true]
2013-04-23 15:22:07,855 [JetlangEventDispatcher.java:284][TRACE]:Going to clear handlers on dispatcher org.menacheri.jetserver.event.impl.JetlangEventDispatcher@18309b0
2013-04-23 15:22:07,855 [DefaultSessionEventHandler.java:179][DEBUG]:Received disconnect event in session. Going to close session
2013-04-23 15:22:07,856 [DefaultToServerHandler.java:60][DEBUG]:Channel -395629090 is disconnected, raising the event to session
2013-04-23 15:22:07,856 [DefaultToServerHandler.java:78][DEBUG]:Channel -395629090 is closed and resources released
2013-04-23 15:22:07,856 [DefaultSessionEventHandler.java:179][DEBUG]:Received disconnect event in session. Going to close session
2013-04-23 15:22:07,856 [NettyTCPMessageSender.java:57][INFO]:Going to close tcp connection in class: org.menacheri.jetserver.communication.NettyTCPMessageSender
2013-04-23 15:22:07,856 [NettyTCPMessageSender.java:66][WARN]:Unable to write the Event Event [type=34, source=null, timeStamp=1366698127856] with type 34 to socket
2013-04-23 15:22:07,856 [JetlangEventDispatcher.java:260][TRACE]:Entered removeHandlersForSession for session PlayerSession [id=3player=org.menacheri.jetserver.app.impl.DefaultPlayer@4536c9ea, parentGameRoom=org.evogame.server.RealGameRoom@50, protocol=null, isShuttingDown=true]
2013-04-23 15:22:07,857 [JetlangEventDispatcher.java:272][TRACE]:Going to remove 1 handlers for session: PlayerSession [id=3player=org.menacheri.jetserver.app.impl.DefaultPlayer@4536c9ea, parentGameRoom=org.evogame.server.RealGameRoom@50, protocol=null, isShuttingDown=true]
2013-04-23 15:22:07,857 [JetlangEventDispatcher.java:284][TRACE]:Going to clear handlers on dispatcher org.menacheri.jetserver.event.impl.JetlangEventDispatcher@c6824e
2013-04-23 15:22:07,857 [DefaultSessionEventHandler.java:179][DEBUG]:Received disconnect event in session. Going to close session

Support re-connection logic.

In case of exception or disconnect, currently the session is closed by default. Reconnection logic will allow the client to re-connect even after the session is close for a configured amount of time.

Null point exception in StringEncoder of Netty 3.5.1

Netty StringEncoder:

...
@OverRide
protected Object encode(
ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
if (!(msg instanceof String)) {
return msg;
}
return copiedBuffer(ctx.getChannel().getConfig().getBufferFactory().getDefaultOrder(), (String) msg, charset);
}
...

NettyUtils:
ChannelBuffer strBuffer = (ChannelBuffer) super.encode(null, null, msg);

The ChannelHandlerContext can not be null.

My version of writeString():

public static ChannelBuffer writeString(String msg) {
    ChannelBuffer buffer = null;
    try {
        ChannelBuffer stringBuffer = ChannelBuffers.dynamicBuffer();
        stringBuffer.writeBytes(msg.getBytes(CharsetUtil.UTF_8));
        int length = stringBuffer.readableBytes();
        ChannelBuffer lengthBuffer = ChannelBuffers.buffer(2);
        lengthBuffer.writeShort(length);
        buffer = ChannelBuffers.wrappedBuffer(lengthBuffer, stringBuffer);
    } catch (Exception e) {
        LOG.error("Error occurred while trying to write string to buffer: {}", e);
    }
    return buffer;
}

OR, which version of netty does not have this problem?...

org.jboss.netty.handler.codec.frame.TooLongFrameException: Adjusted frame length exceeds 256:

I have started getting these kind of exceptions at client side. (Connection is as in original Zombie example).

Since stacktrace does not have any indication of my code, seems like problem is in netty 3.5.1? Any idea?

Thank you

org.jboss.netty.handler.codec.frame.TooLongFrameException: Adjusted frame length exceeds 256: 267 - discarded
at org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:441)
at org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:407)
at org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:322)
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:422)
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:471)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:332)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Exception caught

java.lang.IndexOutOfBoundsException: Invalid index of -59, maximum is 66
at org.jboss.netty.buffer.SlicedChannelBuffer.<init>(SlicedChannelBuffer.java:41)
at org.jboss.netty.buffer.HeapChannelBuffer.slice(HeapChannelBuffer.java:200)
at org.jboss.netty.buffer.AbstractChannelBuffer.slice(AbstractChannelBuffer.java:526)
at org.jboss.netty.handler.codec.frame.FrameDecoder.updateCumulation(FrameDecoder.java:352)
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:305)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:471)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:332)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Changing game room

Hi menacher,

Thanks man for that great job you've done.
But I little confused with changing room without closing current PlayerSession. How can I implement this? I tried:

        oldRoom.disconnectSession(playerSession);
        newRoom.onLogin(playerSession);
        newRoom.connectSession(playerSession);

But after this I have two NetworkEventHandlers for one player session. Hence I have duplication of events processing.

Are you sure that JetlangEventDispatcher.removeHandlersForSession works properly?
I think it should be like that:

public synchronized boolean removeHandlersForSession(Session session)
{
    LOG.trace("Entered removeHandlersForSession for session {}", session);
    List<EventHandler> removeList = new ArrayList<EventHandler>();

    Collection<List<EventHandler>> eventHandlersList = new ArrayList<List<EventHandler>>(
            handlersByEventType.values());
    eventHandlersList.add(anyHandler);

    for (List<EventHandler> handlerList : eventHandlersList)
    {
        removeList.addAll(getHandlersToRemoveForSession(handlerList,session));
    }

    LOG.trace("Going to remove {} handlers for session: {}",
            removeList.size(), session);
    for (EventHandler handler : removeList)
    {
        removeHandler(handler);
    }

    return (removeList.size() > 0);
}

And GameRoomSession.disconnectSession should be like that:

public synchronized boolean disconnectSession(PlayerSession playerSession)
{
    final boolean removeHandlers = this.eventDispatcher.removeHandlersForSession(playerSession);
    return (removeHandlers & sessions.remove(playerSession));
}

For removing player session from room even if no handlers were removed.

How to send events from player's session to game room's session?

Hi Abraham,

Could you please explain how to send events from player's session to game room's session?
You wrote:
The player session's listen on the Game Room session for any outgoing network data using event handlers.
The player sessions have a reference to their Game Room using a parentGameRoom variable and can send data to it using onEvent.

Do I understand correct that I have to do next steps in player's handler:

  1. Call getSession() to get player's session.
  2. Cast this session to PlayerSession.
  3. Call getParentGameRoom of this PlayerSession.
  4. Cast room to GameRoomSession.
  5. Call onEvent() of this GameRoomSession.

I think this should be a little easier:

  1. Call getSession() to get player's session.
  2. Call onEvent() of this session.
  3. GameRoomSession catches raised event and handles it.

In this case I have to add a custom handler to GameRoomSession.

Perhaps such a mechanism is already provided and I'm just inattentive?

compile failed

Results :

Failed tests:
sessionDisconnectValidation(org.menacheri.jetserver.JetlangEventDispatcherTest)

Tests run: 13, Failures: 1, Errors: 0, Skipped: 0


Test set: org.menacheri.jetserver.JetlangEventDispatcherTest

Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 2.882 sec <<< FAILURE!
sessionDisconnectValidation(org.menacheri.jetserver.JetlangEventDispatcherTest) Time elapsed: 0.003 sec <<< FAILURE!
java.lang.AssertionError: expected:<0> but was:<1>
at org.junit.Assert.fail(Assert.java:91)
at org.junit.Assert.failNotEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:126)
at org.junit.Assert.assertEquals(Assert.java:470)
at org.junit.Assert.assertEquals(Assert.java:454)
at org.menacheri.jetserver.JetlangEventDispatcherTest.assertNoListeners(JetlangEventDispatcherTest.java:194)
at org.menacheri.jetserver.JetlangEventDispatcherTest.sessionDisconnectValidation(JetlangEventDispatcherTest.java:165)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:146)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
at com.sun.proxy.$Proxy0.invoke(Unknown Source)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:145)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:87)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)

Log4j usage

This is not really an issue but I have of question to ask here.

  1. How can I disable all the logs of the inner code (wrote by you)? I assume it works okay, and in the logs file I want to see only entries generated by my code to debug it.

  2. I would like to make separate log files for every gameRoom at the server, is there an easy solution for this?

  3. You might now some tools to watch the log by Log4j with applying various filters very fast.

Thank you

room.sendBroadcast(networkEvent) is not working

Option 1 is not working
NettyMessageBuffer outBuf = new NettyMessageBuffer();
outBuf.writeInt(GameRoomCommands.MY_EVENT.getCommand());
NetworkEvent networkEvent = Events.networkEvent(outBuf);
gameRoom.sendBroadcast(networkEvent);

Option 2 is working!
NettyMessageBuffer outBuf = new NettyMessageBuffer();
outBuf.writeInt(GameRoomCommands.MY_EVENT.getCommand());
NetworkEvent networkEvent = Events.networkEvent(outBuf);

Iterator itr = gameRoom.getSessions().iterator();
while (itr.hasNext()) {
PlayerSession playerSession = (PlayerSession) itr.next();
playerSession.getTcpSender().sendMessage(networkEvent);
}

This gameRoom is not is not registered in lookupService. Initially I have only one connectGameRoom which accepts all the incoming connection.
(refKeyGameRoomMap.put("CONNECT_ROOM_REF_KEY", game.getConnectGameRoom());)

After enough players are connect, another gameRoom is created and sessions are added to it.

Jetclient at android

Please, let us know whether it is possible to use jetclient for android app, and if not what kind of modifications would be necessary. Thank

beans.xml parsing exception

I run my Server from Eclipse and it works okay. Then I have create jar file using Elipse -> Create Executable Jar, Log4j configuration file is hardcoded. So this kind of error is shown

C:\Users\Nikolay\workspace\EvolutionServer\bin>java -jar Server.jar

main() function starts
Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefiniti
onStoreException: Line 6 in XML document from class path resource [beans/beans.x
ml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 6
; columnNumber: 120; cvc-elt.1: Cannot find the declaration of element 'beans'.
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadB
eanDefinitions(XmlBeanDefinitionReader.java:396)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBea
nDefinitions(XmlBeanDefinitionReader.java:334)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBea
nDefinitions(XmlBeanDefinitionReader.java:302)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReade
r.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReade
r.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
        at org.springframework.beans.factory.support.AbstractBeanDefinitionReade
r.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
        at org.springframework.context.annotation.ConfigurationClassBeanDefiniti
onReader.loadBeanDefinitionsFromImportedResources(ConfigurationClassBeanDefiniti
onReader.java:293)
        at org.springframework.context.annotation.ConfigurationClassBeanDefiniti
onReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefiniti
onReader.java:118)
        at org.springframework.context.annotation.ConfigurationClassBeanDefiniti
onReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:105)
        at org.springframework.context.annotation.ConfigurationClassPostProcesso
r.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:261)
        at org.springframework.context.annotation.ConfigurationClassPostProcesso
r.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:178)
        at org.springframework.context.support.AbstractApplicationContext.invoke
BeanFactoryPostProcessors(AbstractApplicationContext.java:617)
        at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:446)
        at org.springframework.context.annotation.AnnotationConfigApplicationCon
text.<init>(AnnotationConfigApplicationContext.java:73)
        at org.evogame.server.Server.main(Server.java:23)
Caused by: org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 120; cvc-
elt.1: Cannot find the declaration of element 'beans'.
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAX
ParseException(ErrorHandlerWrapper.java:198)
        at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Err
orHandlerWrapper.java:134)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(
XMLErrorReporter.java:437)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(
XMLErrorReporter.java:368)
        at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(
XMLErrorReporter.java:325)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleS
tartElement(XMLSchemaValidator.java:1897)
        at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startEl
ement(XMLSchemaValidator.java:737)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scan
StartElement(XMLNSDocumentScannerImpl.java:376)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSCo
ntentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:602)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImp
l$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3063)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$Prolog
Driver.next(XMLDocumentScannerImpl.java:881)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(X
MLDocumentScannerImpl.java:607)
        at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next
(XMLNSDocumentScannerImpl.java:116)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImp
l.scanDocument(XMLDocumentFragmentScannerImpl.java:488)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(X
ML11Configuration.java:835)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(X
ML11Configuration.java:764)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.
java:123)
        at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.
java:240)
        at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Doc
umentBuilderImpl.java:300)
        at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocum
ent(DefaultDocumentLoader.java:75)
        at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadB
eanDefinitions(XmlBeanDefinitionReader.java:388)
    ... 14 more

beans.xml has following contents

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <import resource="classpath:/jetserver/beans/server-beans.xml"></import>
    <context:annotation-config />
</beans>

EventDecoder only in jetserver?

In the client I don't want to include jetserver.jar but it seems that EventDecoder class used in PipelineFactory at ZombieClient is located only in jetserver.jar, so it is kind of client size waste.

accept or reject an user at server side

Hello again,

I am back to implement authentication of client at server.
At client side I use this code

Where userId, accessToken, firstName and lastName come from Facebook authentication of the client. So then client provides this data to server who will check validity of the data and then accept or the reject the user.

public static void connect (String userId, String accessToken, String firstName, String lastName) {
        //disable previous listener
        if (future != null) {
            future.cancel();
            future.removeListener(futureListener);
        }

        //connect to server
        future = bootstrap.connect(new InetSocketAddress(host, port));

        final ChannelBuffer loginBuffer = getLoginBuffer("CONNECT_ROOM_REF_KEY", userId, accessToken, firstName, lastName);
        futureListener = new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception
            {
                Channel channel = future.getChannel();
                channel.write(loginBuffer);
            }
        };

        future.addListener(futureListener);
    }

    private static ChannelBuffer getLoginBuffer(String refKey, String userId, String accessToken, String firstName, String lastName) {
        //1 stands for capacity - number of bytes, big Endian
        ChannelBuffer opCode = ChannelBuffers.buffer(1);

        opCode.writeByte(Events.LOG_IN);
        //Creates a new composite buffer which wraps the readable bytes of the specified buffers without copying them. A modification on the content of the specified buffers will be visible to the returned buffer.
        ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(opCode, NettyUtils.writeStrings(refKey, userId, accessToken, firstName, lastName));

        return buffer;
    }

The problem is that at server side I see LOG_IN event only inside compiled library jetserver-0.1.jar.

So how am I supposed to implement this kind of feature without touching the library?

PlayerSession addHandler removeHandler

Hello menacher,

I use your source code for implementation of multiroom server. So once connected every PlayerSession gets default handler so players can send CREATE_ROOM, JOIN_ROOM and so on messages.

public class ConnectGameRoom extends GameRoomSession
{
@OverRide
public void onLogin(PlayerSession playerSession)
{
ConnectSessionHandler listener = new ConnectSessionHandler(playerSession);
playerSession.addHandler(listener);
}
}

Once room has enough players the real game starts for them.
So in some other class I have playerSession class and I want to do something like:
playerSession.resetHandlers();
playerSession.addHandler(realGameListener);

but I can see only removeHandler(EventHandler eventHandler) method, however there I do not have reference to listener.

public List getEventHandlers(int eventType) requires eventType which strange because I set handler without specifing eventType.

GameRoomSession does not keep the order of added sessions

Hello menacher,

This is not a big issue but rather discussion.

In my code assuming strict order I was iterating through GameRoomSession.getSessions() but Java Set and HashSet do not guarantee the order of elements.
http://stackoverflow.com/questions/10752753/java-set-retain-order

From there
"In addition to the SortedSet interface, there is also the LinkedHashSet class. It remembers the order in which the elements were inserted into the set, and returns its elements in that order."

So I want do that. I need to keep the order of sessions according to time of insertion.

And so far I see only one way is to modify GameRoomSession which changing all Set to SortedSet and HashSet to LinkedHashSet for sessions, accordingly and then rebuilding the lib.

Any comment on this?

Thanks

gameRoom.sendBroadcast does not send immediately

I have this snippet of code and message is delivered to a client only after 5 seconds, which surprises me.

public class ConnectSessionHandler extends DefaultSessionEventHandler
{   
        public void onDataIn(Event event)
    {
               RealGameRoom gameRoom = new RealGameRoom();
                //connect sessions

                gameRoom.sendBroadcast(networkEvent);

                Thread.sleep(5000);

If I change "gameRoom.sendBroadcast(networkEvent);" to

Iterator<PlayerSession> itr = gameRoom.getSessions().iterator();
while (itr.hasNext()) {
    itr.next().getTcpSender().sendMessage(networkEvent);
}

then it works as I expect.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.