diff --git a/README.md b/README.md index f6a67688..d8f8ebe1 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,43 @@ -JetServer is a java nio based server specifically designed for mutliplayer games. It supports UDP and TCP transports. It uses [Netty](http://netty.io/) for high speed network transmission and [Jetlang](http://code.google.com/p/jetlang/ "jetlang") for extremely fast in-vm message passing between player sessions and game rooms. The project also uses spring for its dependency injection. This way, it is highly configurable and you can swap out any part of the server with your own implementations. - -Wiki -==== -The [wiki](https://github.com/menacher/java-game-server/wiki) provides implementation level details and answers to general questions that a developer starting to use jetserver might have about it. -Support Group -============= -For general discussion please use the [jetserver google group](https://groups.google.com/forum/#!forum/jetserver). Issues and bugs can be raised directly in github. -Installation -============ -Using pre-built jar files -------------------------- -The pre-built jar files of this project are located in the jetserver/binaries directory. All dependant jars are located in the jetserver/lib directory. You can just add them to your classpath in your favorite IDE and start coding. If you want to compile from source, then follow steps below. - -With Maven and using Eclipse ----------------------------- -**Pre-requisites**: Please have maven 3+ and [Spring source tool suite](http://www.springsource.com/developer/sts "STS") or eclipse installed. If you are using plain vanilla eclipse, then M2Eclipse and EGit plugins though not required will be helpful. If you are using another IDE then the maven-eclipse plugin part in the pom.xml needs to be modified. - -Steps ------ -1. git clone git@github.com:menacher/java-game-server.git -2. cd java-game-server -3. cd jetserver -4. mvn eclipse:eclipse - **Takes time, the first time!** If you want to reduce this time, then comment out include sources/jars option from the maven pom.xml eclipse plugin part. -5. eclipse -> file -> import -> git -> select repository and import jetserver project. -6. jetserver project in eclipse -> right click on pom.xml -> run as -> maven test - **Takes time the first time!** - -If everything works as expected you should see some test cases executed successfully! - -With Ant --------- -If you are using ant, then the lib folder within the jetserver project contains all the dependent libraries. Just right click and run ant build and it will create the jetserver jar. - -*Happy coding!* +Nadron is a java nio based server specifically designed for mutliplayer games. It supports UDP and TCP transports. It uses [Netty](http://netty.io/) for high speed network transmission and [Jetlang](http://code.google.com/p/jetlang/ "jetlang") for extremely fast in-vm message passing between player sessions and game rooms. The project also uses spring for its dependency injection. This way, it is highly configurable and you can swap out any part of the server with your own implementations. + +Wiki +==== +The [wiki](https://github.com/menacher/java-game-server/wiki) provides implementation level details and answers to general questions that a developer starting to use Nadron server might have about it. This [blog post](http://nerdronix.blogspot.com/2013/06/creating-multiplayer-game-using-html-5.html) contains a decent tutorial on creating a multiplayer game using this server. +Support Group +============= +For general discussion please use the [Nadron server google group](https://groups.google.com/forum/#!forum/jetserver). Issues and bugs can be raised directly in github. +Installation +============ +Maven +----- +```xml + + com.github.menacher + nadron + 0.5 + +``` +Using pre-built jar files +------------------------- +The pre-built jar files of this project are located in the nadron/binaries directory. All dependant jars are located in the nadron/lib directory. You can just add them to your classpath in your favorite IDE and start coding. If you want to compile from source, then follow steps below. + +With Maven and using Eclipse +---------------------------- +**Pre-requisites**: Please have maven 3+ and [Spring source tool suite](http://www.springsource.com/developer/sts "STS") or eclipse installed. If you are using plain vanilla eclipse, then M2Eclipse and EGit plugins though not required will be helpful. If you are using another IDE then the maven-eclipse plugin part in the pom.xml needs to be modified. + +Steps +----- +1. git clone git@github.com:menacher/java-game-server.git +2. cd java-game-server +3. cd nadron +4. mvn eclipse:eclipse - **Takes time, the first time!** If you want to reduce this time, then comment out include sources/jars option from the maven pom.xml eclipse plugin part. +5. eclipse -> file -> import -> git -> select repository and import Nadron project. +6. Nadron project in eclipse -> right click on pom.xml -> run as -> maven test - **Takes time the first time!** + +If everything works as expected you should see some test cases executed successfully! + +With Ant +-------- +If you are using ant, then the lib folder within the Nadron project contains all the dependent libraries. Just right click and run ant build and it will create the Nadron jar. + +*Happy coding!* diff --git a/example-games/.classpath b/example-games/.classpath index b495fb62..d1e18460 100644 --- a/example-games/.classpath +++ b/example-games/.classpath @@ -11,19 +11,24 @@ - + - + - + - + + + + + + - + - + @@ -31,9 +36,9 @@ - + - + @@ -46,9 +51,24 @@ - + + + + + + + + + + + + + + + + - + diff --git a/example-games/.project b/example-games/.project index cebea972..b802dc5f 100644 --- a/example-games/.project +++ b/example-games/.project @@ -1,6 +1,6 @@ example-games - This project holds some example multiplayer games that uses the jetserver library. The server part is in src/main/java and the client part of the game is in src/test/java. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. + This project holds some example multiplayer games that uses the Nadron library. The server part is in src/main/java and the client part of the game is in src/test/java. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. diff --git a/example-games/.springBeans b/example-games/.springBeans index ee5ff7d5..0b8f6948 100644 --- a/example-games/.springBeans +++ b/example-games/.springBeans @@ -1,14 +1,14 @@ - - - 1 - - - - - - - src/main/resources/beans/beans.xml - - - - + + + 1 + + + + + + + src/main/resources/beans/beans.xml + + + + diff --git a/example-games/GameServerLog4j.properties b/example-games/GameServerLog4j.properties index ec6c9030..045400d1 100644 --- a/example-games/GameServerLog4j.properties +++ b/example-games/GameServerLog4j.properties @@ -1,14 +1,15 @@ -# Set root logger level to DEBUG and its only appender to A1. - -log4j.rootLogger=DEBUG, toLogFile - -log4j.category.org.menacheri=TRACE - -# Create appender 'toFile' to send log to 'GameServer.log' file -log4j.appender.toLogFile=org.apache.log4j.RollingFileAppender -log4j.appender.toLogFile.File=GameServer.log -log4j.appender.toLogFile.MaxFileSize=10MB -log4j.appender.toLogFile.MaxBackupIndex=10 -log4j.appender.toLogFile.layout=org.apache.log4j.PatternLayout -#log4j.appender.toLogFile.layout.ConversionPattern=%d [%t:%X{LOG_ID},%X{LOG_REQNO},%X{LOG_BEAN}:N%x][%F:%L][%p]:%m%n -log4j.appender.toLogFile.layout.ConversionPattern= %d [%F:%L][%p]:%m%n \ No newline at end of file +# Set root logger level to DEBUG and its only appender to A1. + +log4j.rootLogger=DEBUG, toLogFile +log4j.category.org.springframework=WARN +log4j.category.io.netty=INFO +log4j.category.io.nadron=TRACE + +# Create appender 'toFile' to send log to 'GameServer.log' file +log4j.appender.toLogFile=org.apache.log4j.RollingFileAppender +log4j.appender.toLogFile.File=GameServer.log +log4j.appender.toLogFile.MaxFileSize=10MB +log4j.appender.toLogFile.MaxBackupIndex=10 +log4j.appender.toLogFile.layout=org.apache.log4j.PatternLayout +#log4j.appender.toLogFile.layout.ConversionPattern=%d [%t:%X{LOG_ID},%X{LOG_REQNO},%X{LOG_BEAN}:N%x][%F:%L][%p]:%m%n +log4j.appender.toLogFile.layout.ConversionPattern= %d{ISO8601} [%c{1}:%L][%p]:%m%n \ No newline at end of file diff --git a/example-games/README.md b/example-games/README.md index 122761b3..99bd3a4a 100644 --- a/example-games/README.md +++ b/example-games/README.md @@ -1,56 +1,59 @@ -This project holds some example multi-player games that uses the [jetserver](https://github.com/menacher/java-game-server/tree/master/jetserver) library. The server part is in src/main/java and the client part of the games are in src/test/java. - -Starting the Server -================== -The main class is org.menacheri.GameServer in the src/main/java folder. The game clients are coded in the src/test/java folder. The main class for the zombie game is org.menacheri.zombie.ZombieClient. -Execution ---------- -Pointers on main classes, classpaths and command line flags. - -**To start the game server** -Set the classpath and provide the log4jconfiguration flag. -set serverclasspath = ./jetserver-0.1.jar;./.... -java -cp $serverclasspath -Dlog4j.configuration=GameServerLog4j.properties org.menacheri.GameServer -**To start the zombie client** -set clientclasspath = ./jetserver-0.1.jar;./netty-3.2.4.Final.jar.... -java -cp clientclasspath org.menacheri.ZombieClient - -Jar Dependencies ----------------- -The jar dependencies of this project are provided explicitly. Since maven is used these are all down loaded automatically. -aopalliance-1.0.jar -backport-util-concurrent-3.1.jar -blazeds-core-3.2.0.3978.jar -cglib-nodep-2.1_3.jar -commons-logging-1.1.1.jar -jetlang-0.2.9.jar -jetserver-0.1.jar -log4j-1.2.16.jar -netty-3.3.1.Final.jar -slf4j-api-1.6.1.jar -slf4j-log4j12-1.6.1.jar -spring-aop-3.1.0.RELEASE.jar -spring-asm-3.1.0.RELEASE.jar -spring-beans-3.1.0.RELEASE.jar -spring-context-3.1.0.RELEASE.jar -spring-core-3.1.0.RELEASE.jar -spring-expression-3.1.0.RELEASE.jar - -## Trouble Shooting - -If you get the following property access exception - PropertyAccessException 2: org.springframework.beans.MethodInvocationException: - Property 'undead' threw exception; nested exception is java.lang.NoSuchMethodError: - org.menacheri.aspect.AppManagedAspect.ajc$if$ac5(Lorg/menacheri/aspect/AppManaged;)Z -This is mostly because of the eclipse project not having proper binaries compiled to its target. Just goto Project->clean for both the jetserver as well as client project **without** doing a maven clean and it should -work the second time. - -If you get the following log4j configuration error, then it is mostly probably because you have not set -the -Dlog4j.configuration=GameServerLog4j.properties as a flag in your vm path. - log4j:ERROR Could not read configuration file [null]. - java.lang.NullPointerException - at java.io.FileInputStream.(FileInputStream.java:116) - at java.io.FileInputStream.(FileInputStream.java:79) - at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:372) - at org.apache.log4j.PropertyConfigurator.configure(PropertyConfigurator.java:403) - at org.menacheri.GameServer.main(GameServer.java:22) \ No newline at end of file +This project holds some example multi-player games that uses the [nadron](https://github.com/menacher/java-game-server/tree/master/nadron) library. The server part is in src/main/java and the client part of the games are in src/test/java. + +Starting the Server +================== +The main class is io.nadron.GameServer in the src/main/java folder. The game clients are coded in the src/test/java folder. The main class for the zombie game is io.nadron.zombie.ZombieClient. +Execution +--------- +Pointers on main classes, classpaths and command line flags. + +**To start the game server** +Set the classpath and provide the log4jconfiguration flag. +set serverclasspath = ./nadron-0.5.jar;./.... +java -cp $serverclasspath -Dlog4j.configuration=GameServerLog4j.properties io.nadron.GameServer +**To start the zombie client** +set clientclasspath = ./nadclient-0.5.jar;./netty-all-4.0.10.Final.jar.... +java -cp clientclasspath io.nadron.ZombieClient + +Jar Dependencies +---------------- +The jar dependencies of this project are provided explicitly. Since maven is used these are all down loaded automatically. +aopalliance-1.0.jar +backport-util-concurrent-3.1.jar +blazeds-core-3.2.0.3978.jar +cglib-nodep-2.1_3.jar +commons-logging-1.1.1.jar +jetlang-0.2.9.jar +nadron-0.5.jar +nadclient-0.5.jar +log4j-1.2.16.jar +netty-all-4.0.10.Final.jar +msgpack-0.6.8.jar +json-simple-1.1.1.jar +slf4j-api-1.6.1.jar +slf4j-log4j12-1.6.1.jar +spring-aop-3.1.0.RELEASE.jar +spring-asm-3.1.0.RELEASE.jar +spring-beans-3.1.0.RELEASE.jar +spring-context-3.1.0.RELEASE.jar +spring-core-3.1.0.RELEASE.jar +spring-expression-3.1.0.RELEASE.jar + +## Trouble Shooting + +If you get the following property access exception + PropertyAccessException 2: org.springframework.beans.MethodInvocationException: + Property 'undead' threw exception; nested exception is java.lang.NoSuchMethodError: + io.nadron.aspect.AppManagedAspect.ajc$if$ac5(Lorg/menacheri/aspect/AppManaged;)Z +This is mostly because of the eclipse project not having proper binaries compiled to its target. Just goto Project->clean for both the nadron as well as client project **without** doing a maven clean and it should +work the second time. + +If you get the following log4j configuration error, then it is mostly probably because you have not set +the -Dlog4j.configuration=GameServerLog4j.properties as a flag in your vm path. + log4j:ERROR Could not read configuration file [null]. + java.lang.NullPointerException + at java.io.FileInputStream.(FileInputStream.java:116) + at java.io.FileInputStream.(FileInputStream.java:79) + at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:372) + at org.apache.log4j.PropertyConfigurator.configure(PropertyConfigurator.java:403) + at io.nadron.GameServer.main(GameServer.java:22) \ No newline at end of file diff --git a/example-games/build.xml b/example-games/build.xml index b022466c..10331be5 100644 --- a/example-games/build.xml +++ b/example-games/build.xml @@ -1,108 +1,108 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example-games/pom.xml b/example-games/pom.xml index fa982686..038f2838 100644 --- a/example-games/pom.xml +++ b/example-games/pom.xml @@ -1,137 +1,76 @@ - - 4.0.0 - org.menacheri - example-games - jar - 0.1 - example-games - http://maven.apache.org - This project holds some example multiplayer games that uses the jetserver library. The server part is in src/main/java and the client part of the game is in src/test/java - - - - UTF-8 - - - - - junit - junit - 4.8.2 - test - - - - - org.menacheri - jetserver - 0.1 - jar - - - - - org.menacheri - jetclient - 0.1 - jar - - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - - - - - - org.apache.maven.plugins - maven-eclipse-plugin - 2.8 - - - - - - - org.springframework.ide.eclipse.core.springnature - org.eclipse.wst.common.project.facet.core.nature - - - - - true - true - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.3.2 - - 1.6 - - - - - - - - + + 4.0.0 + com.github.menacher + example-games + jar + 0.4-SNAPSHOT + example-games + https://github.com/menacher/java-game-server/tree/netty4/example-games + This project holds some example multiplayer games that uses the Nadron library. The server part is in src/main/java and the client part of the game is in src/test/java + + + + UTF-8 + + + + + junit + junit + 4.8.2 + test + + + + + com.github.menacher + nadron + 0.5 + + + + + com.github.menacher + nadclient + 0.5 + + + + + org.slf4j + slf4j-log4j12 + 1.6.1 + + + + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.8 + + + org.springframework.ide.eclipse.core.springnature + org.eclipse.wst.common.project.facet.core.nature + + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + + + + + + + diff --git a/example-games/src/main/java/org/menacheri/GameServer.java b/example-games/src/main/java/io/nadron/example/GameServer.java similarity index 53% rename from example-games/src/main/java/org/menacheri/GameServer.java rename to example-games/src/main/java/io/nadron/example/GameServer.java index df2cd481..064d450d 100644 --- a/example-games/src/main/java/org/menacheri/GameServer.java +++ b/example-games/src/main/java/io/nadron/example/GameServer.java @@ -1,16 +1,16 @@ -package org.menacheri; +package io.nadron.example; + +import io.nadron.app.GameRoom; +import io.nadron.app.Task; +import io.nadron.example.zombie.domain.World; +import io.nadron.example.zombie.domain.WorldMonitor; +import io.nadron.example.zombie.game.ZombieRoom; +import io.nadron.server.ServerManager; +import io.nadron.service.TaskManagerService; import java.util.concurrent.TimeUnit; import org.apache.log4j.PropertyConfigurator; -import org.menacheri.jetserver.app.GameRoom; -import org.menacheri.jetserver.app.Task; -import org.menacheri.jetserver.server.ServerManager; -import org.menacheri.jetserver.service.TaskManagerService; -import org.menacheri.zombie.domain.World; -import org.menacheri.zombie.domain.WorldMonitor; -import org.menacheri.zombie.game.ZombieRoom; -import org.menacheri.zombie.game.ZombieSpringConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -25,7 +25,7 @@ public static void main(String[] args) { PropertyConfigurator.configure(System .getProperty("log4j.configuration")); - AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(ZombieSpringConfig.class); + AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); // For the destroy method to work. ctx.registerShutdownHook(); @@ -46,14 +46,14 @@ public static void main(String[] args) public static void startGames(AbstractApplicationContext ctx) { - World world = ctx.getBean(World.class); - GameRoom room1 = (GameRoom)ctx.getBean("Zombie_ROOM_1"); - GameRoom room2 = (GameRoom)ctx.getBean("Zombie_ROOM_2"); - Task monitor1 = new WorldMonitor(world,room1); - Task monitor2 = new WorldMonitor(world,room2); - TaskManagerService taskManager = ctx.getBean(TaskManagerService.class); - taskManager.scheduleWithFixedDelay(monitor1, 1000, 5000, TimeUnit.MILLISECONDS); - taskManager.scheduleWithFixedDelay(monitor2, 2000, 5000, TimeUnit.MILLISECONDS); +// World world = ctx.getBean(World.class); +// GameRoom room1 = (GameRoom)ctx.getBean("Zombie_ROOM_1"); +// GameRoom room2 = (GameRoom)ctx.getBean("Zombie_ROOM_2"); +// Task monitor1 = new WorldMonitor(world,room1); +// Task monitor2 = new WorldMonitor(world,room2); +// TaskManagerService taskManager = ctx.getBean(TaskManagerService.class); +// taskManager.scheduleWithFixedDelay(monitor1, 1000, 5000, TimeUnit.MILLISECONDS); +// taskManager.scheduleWithFixedDelay(monitor2, 2000, 5000, TimeUnit.MILLISECONDS); } } diff --git a/example-games/src/main/java/io/nadron/example/SpringConfig.java b/example-games/src/main/java/io/nadron/example/SpringConfig.java new file mode 100644 index 00000000..d2118bcf --- /dev/null +++ b/example-games/src/main/java/io/nadron/example/SpringConfig.java @@ -0,0 +1,164 @@ +package io.nadron.example; + +import io.nadron.app.Game; +import io.nadron.app.GameRoom; +import io.nadron.app.impl.SimpleGame; +import io.nadron.app.impl.GameRoomSession.GameRoomSessionBuilder; +import io.nadron.example.lostdecade.LDRoom; +import io.nadron.example.zombie.domain.Defender; +import io.nadron.example.zombie.domain.World; +import io.nadron.example.zombie.domain.Zombie; +import io.nadron.example.zombie.game.ZombieRoom; +import io.nadron.handlers.netty.TextWebsocketEncoder; +import io.nadron.protocols.Protocol; +import io.nadron.protocols.impl.NettyObjectProtocol; +import io.nadron.service.LookupService; +import io.nadron.service.impl.SimpleLookupService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + +/** + * This class contains the spring configuration for the nadron library user. + * The only bean that is compulsory to be declared is lookupService bean. + * Otherwise the program will terminate with a context load error from spring + * framework. The other beans declared can also be created using **new** + * operator as per programmer convenience. + * + * @author Abraham Menacherry. + * + */ +@Configuration +@ImportResource("classpath:/beans/beans.xml") +public class SpringConfig +{ + @Autowired + @Qualifier("messageBufferProtocol") + private Protocol messageBufferProtocol; + + @Autowired + @Qualifier("webSocketProtocol") + private Protocol webSocketProtocol; + + @Autowired + @Qualifier("textWebsocketEncoder") + private TextWebsocketEncoder textWebsocketEncoder; + + @Autowired + @Qualifier("nettyObjectProtocol") + private NettyObjectProtocol nettyObjectProtocol; + + public @Bean + Game zombieGame() + { + Game game = new SimpleGame(1, "Zombie"); + return game; + } + + public @Bean(name = "Zombie_Rooms") + List zombieRooms() + { + List roomList = new ArrayList(500); + for (int i = 1; i <= 500; i++) + { + GameRoomSessionBuilder sessionBuilder = new GameRoomSessionBuilder(); + sessionBuilder.parentGame(zombieGame()) + .gameRoomName("Zombie_ROOM_" + i) + .protocol(messageBufferProtocol); + ZombieRoom room = new ZombieRoom(sessionBuilder); + room.setDefender(defender()); + room.setZombie(zombie()); + roomList.add(room); + } + return roomList; + } + + public @Bean(name = "Zombie_Room_Websocket") + GameRoom zombieRoom2() + { + GameRoomSessionBuilder sessionBuilder = new GameRoomSessionBuilder(); + sessionBuilder.parentGame(zombieGame()) + .gameRoomName("Zombie_Room_Websocket") + .protocol(webSocketProtocol); + ZombieRoom room = new ZombieRoom(sessionBuilder); + room.setDefender(defender()); + room.setZombie(zombie()); + + return room; + } + + public @Bean + World world() + { + World world = new World(); + world.setAlive(2000000000); + world.setUndead(1); + return world; + } + + public @Bean + Defender defender() + { + Defender defender = new Defender(); + defender.setWorld(world()); + return defender; + } + + public @Bean + Zombie zombie() + { + Zombie zombie = new Zombie(); + zombie.setWorld(world()); + return zombie; + } + + public @Bean(name = "LDGame") + Game ldGame() + { + return new SimpleGame(2, "LDGame"); + } + + public @Bean(name = "LDGameRoom") + GameRoom ldGameRoom() + { + GameRoomSessionBuilder sessionBuilder = new GameRoomSessionBuilder(); + sessionBuilder.parentGame(ldGame()).gameRoomName("LDGameRoom") + .protocol(webSocketProtocol); + LDRoom room = new LDRoom(sessionBuilder); + return room; + } + + public @Bean(name = "LDGameRoomForNettyClient") + GameRoom ldGameRoomForNettyClient() + { + GameRoomSessionBuilder sessionBuilder = new GameRoomSessionBuilder(); + sessionBuilder.parentGame(ldGame()).gameRoomName("LDGameRoomForNettyClient") + .protocol(nettyObjectProtocol); + LDRoom room = new LDRoom(sessionBuilder); + return room; + } + + public @Bean(name = "lookupService") + LookupService lookupService() + { + Map refKeyGameRoomMap = new HashMap(); + List zombieRooms = zombieRooms(); + for (GameRoom room : zombieRooms) + { + refKeyGameRoomMap.put(room.getGameRoomName(), room); + } + refKeyGameRoomMap.put("Zombie_ROOM_1_REF_KEY_2", zombieRoom2()); + refKeyGameRoomMap.put("LDGameRoom", ldGameRoom()); + refKeyGameRoomMap.put("LDGameRoomForNettyClient", ldGameRoomForNettyClient()); + LookupService service = new SimpleLookupService(refKeyGameRoomMap); + return service; + } +} diff --git a/example-games/src/main/java/io/nadron/example/lostdecade/Entity.java b/example-games/src/main/java/io/nadron/example/lostdecade/Entity.java new file mode 100644 index 00000000..c3ccd0ed --- /dev/null +++ b/example-games/src/main/java/io/nadron/example/lostdecade/Entity.java @@ -0,0 +1,155 @@ +package io.nadron.example.lostdecade; + +import java.io.Serializable; + +/** + * A hero, monster or any other "living" character on the gameboard. + * + * @author Abraham Menacherry + * + */ +public class Entity implements Serializable +{ + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Entity other = (Entity) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + public static final String MONSTER = "MONSTER"; + public static final String HERO = "HERO"; + + private String id; + + private int x, y, speed, key; + + private boolean press; + + /** + * Is it a monster or hero? + */ + private String type; + + /** + * Only heroes will have it. + */ + int score; + + public Entity() + { + + } + + public Entity(String id, String type, int score) + { + super(); + this.id = id; + this.type = type; + this.score = score; + } + + public int getX() + { + return x; + } + + public void setX(int x) + { + this.x = x; + } + + public int getY() + { + return y; + } + + public void setY(int y) + { + this.y = y; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } + + public int getScore() + { + return score; + } + + public void setScore(int score) + { + this.score = score; + } + + public String getId() + { + return id; + } + + public void setId(String string) + { + this.id = string; + } + + public int getSpeed() + { + return speed; + } + + public void setSpeed(int speed) + { + this.speed = speed; + } + + public int getKey() + { + return key; + } + + public void setKey(int key) + { + this.key = key; + } + + public boolean isPress() + { + return press; + } + + public void setPress(boolean press) + { + this.press = press; + } + + +} diff --git a/example-games/src/main/java/io/nadron/example/lostdecade/LDEvent.java b/example-games/src/main/java/io/nadron/example/lostdecade/LDEvent.java new file mode 100644 index 00000000..62a7c7f4 --- /dev/null +++ b/example-games/src/main/java/io/nadron/example/lostdecade/LDEvent.java @@ -0,0 +1,21 @@ +package io.nadron.example.lostdecade; + +import io.nadron.event.impl.DefaultEvent; + +public class LDEvent extends DefaultEvent +{ + private static final long serialVersionUID = 1L; + + private LDGameState source; + + @Override + public LDGameState getSource() + { + return source; + } + + public void setSource(LDGameState source) + { + this.source = source; + } +} diff --git a/example-games/src/main/java/io/nadron/example/lostdecade/LDGameState.java b/example-games/src/main/java/io/nadron/example/lostdecade/LDGameState.java new file mode 100644 index 00000000..94c5380a --- /dev/null +++ b/example-games/src/main/java/io/nadron/example/lostdecade/LDGameState.java @@ -0,0 +1,89 @@ +package io.nadron.example.lostdecade; + +import io.nadron.app.GameRoom; + +import java.io.Serializable; +import java.util.Set; + + + +/** + * The state of a game room is held in this object. Multiple remote client + * connections to a {@link GameRoom} will share this state. + * + * @author Abraham Menacherry + * + */ +public class LDGameState implements Serializable +{ + /** + * + */ + private static final long serialVersionUID = 1L; + private Set entities; + private Entity monster; + private Entity hero; + private boolean reset; + + public LDGameState() + { + + } + + public LDGameState(Set entities, Entity monster, Entity hero) + { + super(); + this.entities = entities; + this.monster = monster; + this.hero = hero; + } + + public Entity getMonster() + { + return monster; + } + + public void setMonster(Entity monster) + { + this.monster = monster; + } + + public void addEntitiy(Entity hero) + { + // only the id will match, but other values maybe different. + entities.remove(hero); + entities.add(hero); + } + + public Entity getHero() + { + return hero; + } + + public void setHero(Entity hero) + { + this.hero = hero; + } + + public boolean isReset() + { + return reset; + } + + public void setReset(boolean reset) + { + this.reset = reset; + } + + public Set getEntities() + { + return entities; + } + + public void setEntities(Set entities) + { + this.entities = entities; + } + +} + \ No newline at end of file diff --git a/example-games/src/main/java/io/nadron/example/lostdecade/LDRoom.java b/example-games/src/main/java/io/nadron/example/lostdecade/LDRoom.java new file mode 100644 index 00000000..374a209c --- /dev/null +++ b/example-games/src/main/java/io/nadron/example/lostdecade/LDRoom.java @@ -0,0 +1,173 @@ +package io.nadron.example.lostdecade; + +import io.nadron.app.GameRoom; +import io.nadron.app.PlayerSession; +import io.nadron.app.Session; +import io.nadron.app.impl.GameRoomSession; +import io.nadron.event.Event; +import io.nadron.event.Events; +import io.nadron.event.impl.DefaultEventContext; +import io.nadron.event.impl.DefaultSessionEventHandler; +import io.nadron.event.impl.SessionMessageHandler; +import io.nadron.service.GameStateManagerService; + +import java.util.HashSet; +import java.util.Set; + + +/** + * The onLogin method is overriden so that incoming player sessions can be + * initialzied with event handlers to do user logic. In this scenario, the only + * thing the handler does is to patch incoming messages to the GameRoom which in + * turn has the game logic and state. In more real-world scenarios, the session + * handler can have its own logic, for e.g. say validation to prevent cheating, + * filtering, pre-processing of event etc. + * + * @author Abraham Menacherry + * + */ +public class LDRoom extends GameRoomSession { + private static final int canvasWidth = 512; + private static final int canvasHeight = 480; + + public LDRoom(GameRoomSessionBuilder builder) { + super(builder); + addHandler(new GameSessionHandler(this)); + } + + @Override + public void onLogin(final PlayerSession playerSession) { + // Add a session handler to player session. So that it can receive + // events. + playerSession.addHandler(new DefaultSessionEventHandler(playerSession) { + @Override + protected void onDataIn(Event event) { + if (null != event.getSource()) { + // Pass the player session in the event context so that the + // game room knows which player session send the message. + event.setEventContext(new DefaultEventContext( + playerSession, null)); + // pass the event to the game room + playerSession.getGameRoom().send(event); + } + } + + }); + + // Now add the hero to the set of entities managed by LDGameState + Entity hero = createHero(playerSession); + LDGameState state = (LDGameState) getStateManager().getState(); + state.getEntities().add(hero); + // We do broadcast instead of send since all connected players need to + // know about the new players arrival so that this hero can be drawn on + // their screens. + sendBroadcast(Events.networkEvent(new LDGameState(state.getEntities(), + state.getMonster(), hero))); + } + + private Entity createHero(final PlayerSession playerSession) { + Entity hero = new Entity(); + hero.setId((String) playerSession.getId()); + hero.score = 0; + hero.setType(Entity.HERO); + hero.setY(canvasHeight / 2); + hero.setX(canvasWidth / 2); + hero.setSpeed(256);// speed in pixels per second + return hero; + } + + private static Entity createMonster() { + Entity monster = new Entity(); + monster.setType(Entity.MONSTER); + monster.setX(getRandomPos(canvasWidth)); + monster.setY(getRandomPos(canvasHeight)); + return monster; + } + + private static int getRandomPos(int axisVal) { + long round = Math.round(32 + (Math.random() * (axisVal - 64))); + return (int) round; + } + + /** + * This handler is attached to the GameRoom and all game related logic is + * embedded in it. Its a SESSION_MESSAGE handler and does not take care of + * other events which are sent to the room. + * + * @author Abraham Menacherry + * + */ + public static class GameSessionHandler extends SessionMessageHandler { + Entity monster; + GameRoom room;// not really required. It can be accessed as getSession() + // also. + + public GameSessionHandler(GameRoomSession session) { + super(session); + this.room = session; + GameStateManagerService manager = room.getStateManager(); + LDGameState state = (LDGameState) manager.getState(); + // Initialize the room state. + state = new LDGameState(); + state.setEntities(new HashSet()); + state.setMonster(createMonster()); + manager.setState(state); // set it back on the room + this.monster = state.getMonster(); + } + + @Override + public void onEvent(Event event) { + Entity hero = ((LDGameState) event.getSource()).getHero(); + Session session = event.getEventContext().getSession(); + update(hero, session); + } + + private void update(Entity hero, Session session) { + boolean isTouching = (hero.getX() <= monster.getX() + 32) + && (hero.getY() <= monster.getY() + 32) + && (monster.getX() <= hero.getX() + 32) + && (monster.getY() <= hero.getY() + 32); + + LDGameState state = (LDGameState) room.getStateManager().getState(); + hero.setId((String) session.getId()); + if (isTouching) { + hero.score += 1; + state.addEntitiy(hero); + reset(); + } else { + state.addEntitiy(hero); + } + + // The state of only one hero is updated, no need to send every + // hero's state. + // A possible optimization here is not to broadcast state in case + // the hero has not moved. + room.sendBroadcast(Events.networkEvent(new LDGameState(null, + monster, hero))); + } + + /** + * When the hero and monster are touching each other it means hero + * caught the monster, the game board needs to be reset. This method + * will put the monster in a random position and all the heroes at the + * center of the board. Also, it will send reset flag as + * true to clients so that they can reset their own + * screens. + */ + private void reset() { + Set entities = ((LDGameState) room.getStateManager() + .getState()).getEntities(); + for (Entity entity : entities) { + entity.setY(canvasHeight / 2); + entity.setX(canvasWidth / 2); + } + monster.setX(getRandomPos(canvasWidth)); + monster.setY(getRandomPos(canvasHeight)); + // no need to send the entities here since client will do resetting on its own. + LDGameState ldGameState = new LDGameState(null, monster, null); + ldGameState.setReset(true); + room.sendBroadcast(Events.networkEvent(ldGameState)); + } + + } +} diff --git a/example-games/src/main/java/org/menacheri/zombie/domain/Defender.java b/example-games/src/main/java/io/nadron/example/zombie/domain/Defender.java similarity index 78% rename from example-games/src/main/java/org/menacheri/zombie/domain/Defender.java rename to example-games/src/main/java/io/nadron/example/zombie/domain/Defender.java index 8589d25f..aa428c1b 100644 --- a/example-games/src/main/java/org/menacheri/zombie/domain/Defender.java +++ b/example-games/src/main/java/io/nadron/example/zombie/domain/Defender.java @@ -1,23 +1,23 @@ -package org.menacheri.zombie.domain; - - -public class Defender -{ - private World world; - - public void shotgun() - { - world.shotgun(); - } - - public World getWorld() - { - return world; - } - - public void setWorld(World world) - { - this.world = world; - } - -} +package io.nadron.example.zombie.domain; + + +public class Defender +{ + private World world; + + public void shotgun() + { + world.shotgun(); + } + + public World getWorld() + { + return world; + } + + public void setWorld(World world) + { + this.world = world; + } + +} diff --git a/example-games/src/main/java/org/menacheri/zombie/domain/IAM.java b/example-games/src/main/java/io/nadron/example/zombie/domain/IAM.java similarity index 83% rename from example-games/src/main/java/org/menacheri/zombie/domain/IAM.java rename to example-games/src/main/java/io/nadron/example/zombie/domain/IAM.java index 7650c225..9ce27664 100644 --- a/example-games/src/main/java/org/menacheri/zombie/domain/IAM.java +++ b/example-games/src/main/java/io/nadron/example/zombie/domain/IAM.java @@ -1,35 +1,35 @@ -package org.menacheri.zombie.domain; - -public enum IAM -{ - ZOMBIE(1),DEFENDER(2); - IAM(int who){ - - } - - public static IAM getWho(int who) - { - switch (who) - { - case 1: - return ZOMBIE; - case 2: - return DEFENDER; - default: - return ZOMBIE; - } - } - - public static int getInt(IAM iam) - { - switch (iam) - { - case ZOMBIE: - return 1; - case DEFENDER: - return 2; - default: - return 1; - } - } -} +package io.nadron.example.zombie.domain; + +public enum IAM +{ + ZOMBIE(1),DEFENDER(2); + IAM(int who){ + + } + + public static IAM getWho(int who) + { + switch (who) + { + case 1: + return ZOMBIE; + case 2: + return DEFENDER; + default: + return ZOMBIE; + } + } + + public static int getInt(IAM iam) + { + switch (iam) + { + case ZOMBIE: + return 1; + case DEFENDER: + return 2; + default: + return 1; + } + } +} diff --git a/example-games/src/main/java/org/menacheri/zombie/domain/World.java b/example-games/src/main/java/io/nadron/example/zombie/domain/World.java similarity index 90% rename from example-games/src/main/java/org/menacheri/zombie/domain/World.java rename to example-games/src/main/java/io/nadron/example/zombie/domain/World.java index 190307c0..26fe9c60 100644 --- a/example-games/src/main/java/org/menacheri/zombie/domain/World.java +++ b/example-games/src/main/java/io/nadron/example/zombie/domain/World.java @@ -1,62 +1,62 @@ -package org.menacheri.zombie.domain; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class World -{ - private static final Logger LOG = LoggerFactory.getLogger(World.class); - private volatile int alive; - private volatile int undead; - - public boolean apocalypse() { - if(alive <= 0) - { - return true; - } - return false; - } - - public void report() { - if(alive > 0) { - LOG.trace("alive= {} undead= {}",alive, undead); - } - } - - public int getAlive() - { - return alive; - } - - public void setAlive(int alive) - { - this.alive = alive; - } - - public int getUndead() - { - return undead; - } - - public void setUndead(int undead) - { - this.undead = undead; - } - - public void shotgun() - { - int newUndead = undead - 1; - LOG.trace("Defender update, undead = " + undead + " new undead: " + newUndead); - undead = newUndead; - } - - public void eatBrains() - { - LOG.trace("In eatBrains Alive: {} Undead: {}",alive,undead); - alive--; - undead += 2 ; - LOG.trace("New Alive: {} Undead: {}",alive,undead); - } - -} +package io.nadron.example.zombie.domain; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class World +{ + private static final Logger LOG = LoggerFactory.getLogger(World.class); + private volatile int alive; + private volatile int undead; + + public boolean apocalypse() { + if(alive <= 0) + { + return true; + } + return false; + } + + public void report() { + if(alive > 0) { + LOG.trace("alive= {} undead= {}",alive, undead); + } + } + + public int getAlive() + { + return alive; + } + + public void setAlive(int alive) + { + this.alive = alive; + } + + public int getUndead() + { + return undead; + } + + public void setUndead(int undead) + { + this.undead = undead; + } + + public void shotgun() + { + int newUndead = undead - 1; + LOG.trace("Defender update, undead = " + undead + " new undead: " + newUndead); + undead = newUndead; + } + + public void eatBrains() + { + LOG.trace("In eatBrains Alive: {} Undead: {}",alive,undead); + alive--; + undead += 2 ; + LOG.trace("New Alive: {} Undead: {}",alive,undead); + } + +} diff --git a/example-games/src/main/java/org/menacheri/zombie/domain/WorldMonitor.java b/example-games/src/main/java/io/nadron/example/zombie/domain/WorldMonitor.java similarity index 72% rename from example-games/src/main/java/org/menacheri/zombie/domain/WorldMonitor.java rename to example-games/src/main/java/io/nadron/example/zombie/domain/WorldMonitor.java index aa72973d..e6f56a8d 100644 --- a/example-games/src/main/java/org/menacheri/zombie/domain/WorldMonitor.java +++ b/example-games/src/main/java/io/nadron/example/zombie/domain/WorldMonitor.java @@ -1,13 +1,14 @@ -package org.menacheri.zombie.domain; +package io.nadron.example.zombie.domain; + +import io.nadron.app.GameRoom; +import io.nadron.app.Task; +import io.nadron.communication.NettyMessageBuffer; +import io.nadron.communication.DeliveryGuaranty.DeliveryGuarantyOptions; +import io.nadron.event.Events; +import io.nadron.event.NetworkEvent; +import io.nadron.example.zombie.game.Messages; +import io.nadron.protocols.impl.WebSocketProtocol; -import org.menacheri.jetserver.app.GameRoom; -import org.menacheri.jetserver.app.Task; -import org.menacheri.jetserver.communication.DeliveryGuaranty.DeliveryGuarantyOptions; -import org.menacheri.jetserver.communication.NettyMessageBuffer; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.NetworkEvent; -import org.menacheri.jetserver.protocols.impl.WebSocketProtocol; -import org.menacheri.zombie.game.Messages; public class WorldMonitor implements Task { diff --git a/example-games/src/main/java/org/menacheri/zombie/domain/Zombie.java b/example-games/src/main/java/io/nadron/example/zombie/domain/Zombie.java similarity index 78% rename from example-games/src/main/java/org/menacheri/zombie/domain/Zombie.java rename to example-games/src/main/java/io/nadron/example/zombie/domain/Zombie.java index 79fc36d7..0699bea3 100644 --- a/example-games/src/main/java/org/menacheri/zombie/domain/Zombie.java +++ b/example-games/src/main/java/io/nadron/example/zombie/domain/Zombie.java @@ -1,22 +1,22 @@ -package org.menacheri.zombie.domain; - - -public class Zombie -{ - private World world; - - public void eatBrains() - { - world.eatBrains(); - } - - public World getWorld() - { - return world; - } - - public void setWorld(World world) - { - this.world = world; - } -} +package io.nadron.example.zombie.domain; + + +public class Zombie +{ + private World world; + + public void eatBrains() + { + world.eatBrains(); + } + + public World getWorld() + { + return world; + } + + public void setWorld(World world) + { + this.world = world; + } +} diff --git a/example-games/src/main/java/org/menacheri/zombie/domain/ZombieCommands.java b/example-games/src/main/java/io/nadron/example/zombie/domain/ZombieCommands.java similarity index 94% rename from example-games/src/main/java/org/menacheri/zombie/domain/ZombieCommands.java rename to example-games/src/main/java/io/nadron/example/zombie/domain/ZombieCommands.java index 797c107e..89ae62fa 100644 --- a/example-games/src/main/java/org/menacheri/zombie/domain/ZombieCommands.java +++ b/example-games/src/main/java/io/nadron/example/zombie/domain/ZombieCommands.java @@ -1,4 +1,4 @@ -package org.menacheri.zombie.domain; +package io.nadron.example.zombie.domain; import java.util.HashMap; import java.util.Map; diff --git a/example-games/src/main/java/io/nadron/example/zombie/game/Messages.java b/example-games/src/main/java/io/nadron/example/zombie/game/Messages.java new file mode 100644 index 00000000..6d29c56f --- /dev/null +++ b/example-games/src/main/java/io/nadron/example/zombie/game/Messages.java @@ -0,0 +1,23 @@ +package io.nadron.example.zombie.game; + +import io.nadron.example.zombie.domain.ZombieCommands; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + + + +/** + * This class acts like a message factory for creating game specific messages. + * @author Abraham Menacherry + * + */ +public class Messages +{ + public static ByteBuf apocalypse() + { + ByteBuf buffer = Unpooled.buffer(4); + int cmd = ZombieCommands.APOCALYPSE.getCommand(); + buffer.writeInt(cmd); + return buffer; + } +} diff --git a/example-games/src/main/java/org/menacheri/zombie/game/SessionHandler.java b/example-games/src/main/java/io/nadron/example/zombie/game/SessionHandler.java similarity index 67% rename from example-games/src/main/java/org/menacheri/zombie/game/SessionHandler.java rename to example-games/src/main/java/io/nadron/example/zombie/game/SessionHandler.java index 406f8f4a..caec6b4d 100644 --- a/example-games/src/main/java/org/menacheri/zombie/game/SessionHandler.java +++ b/example-games/src/main/java/io/nadron/example/zombie/game/SessionHandler.java @@ -1,21 +1,22 @@ -package org.menacheri.zombie.game; +package io.nadron.example.zombie.game; + +import io.nadron.app.GameCommandInterpreter; +import io.nadron.app.Session; +import io.nadron.app.impl.InvalidCommandException; +import io.nadron.communication.MessageBuffer; +import io.nadron.communication.NettyMessageBuffer; +import io.nadron.communication.DeliveryGuaranty.DeliveryGuarantyOptions; +import io.nadron.event.Event; +import io.nadron.event.Events; +import io.nadron.event.NetworkEvent; +import io.nadron.event.impl.DefaultSessionEventHandler; +import io.nadron.example.zombie.domain.Defender; +import io.nadron.example.zombie.domain.IAM; +import io.nadron.example.zombie.domain.Zombie; +import io.nadron.example.zombie.domain.ZombieCommands; import java.util.List; -import org.menacheri.jetserver.app.GameCommandInterpreter; -import org.menacheri.jetserver.app.Session; -import org.menacheri.jetserver.app.impl.InvalidCommandException; -import org.menacheri.jetserver.communication.DeliveryGuaranty.DeliveryGuarantyOptions; -import org.menacheri.jetserver.communication.MessageBuffer; -import org.menacheri.jetserver.communication.NettyMessageBuffer; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.NetworkEvent; -import org.menacheri.jetserver.event.impl.DefaultSessionEventHandler; -import org.menacheri.zombie.domain.Defender; -import org.menacheri.zombie.domain.IAM; -import org.menacheri.zombie.domain.Zombie; -import org.menacheri.zombie.domain.ZombieCommands; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,18 +59,18 @@ public void interpretCommand(Object command) throws InvalidCommandException cmdCount++; int type; int operation; - boolean isDefaultProtocol = true; + boolean isWebSocketProtocol = false; if(command instanceof MessageBuffer) { MessageBuffer buf = (MessageBuffer) command; type = buf.readInt(); operation = buf.readInt(); }else{ // websocket - isDefaultProtocol = false; - List data = (List)command; + isWebSocketProtocol = true; + List data = (List)command; - type = data.get(0).intValue(); - operation = data.get(1).intValue(); + type = data.get(0); + operation = data.get(1); } IAM iam = IAM.getWho(type); ZombieCommands cmd = ZombieCommands.CommandsEnum.fromInt(operation); @@ -106,19 +107,18 @@ public void interpretCommand(Object command) throws InvalidCommandException throw new InvalidCommandException("Received invalid command" + cmd); } - if((cmdCount % 10000) == 0) + if(isWebSocketProtocol){ + getSession().onEvent(Events.networkEvent(cmdCount)); + } + else if((cmdCount % 10000) == 0) { NettyMessageBuffer buffer = new NettyMessageBuffer(); - System.out.println("Command No: " + cmdCount); + //System.out.println("Command No: " + cmdCount); buffer.writeInt(cmdCount); // Event tcpEvent = Events.dataOutTcpEvent(buffer); // getSession().onEvent(tcpEvent); NetworkEvent udpEvent = null; - if(isDefaultProtocol){ - udpEvent = Events.networkEvent(buffer, DeliveryGuarantyOptions.FAST); - }else{ - udpEvent = Events.networkEvent(cmdCount);// for websocket protocol. - } + udpEvent = Events.networkEvent(buffer, DeliveryGuarantyOptions.FAST); getSession().onEvent(udpEvent); } } diff --git a/example-games/src/main/java/org/menacheri/zombie/game/ZombieRoom.java b/example-games/src/main/java/io/nadron/example/zombie/game/ZombieRoom.java similarity index 73% rename from example-games/src/main/java/org/menacheri/zombie/game/ZombieRoom.java rename to example-games/src/main/java/io/nadron/example/zombie/game/ZombieRoom.java index e25db442..6e1b45fd 100644 --- a/example-games/src/main/java/org/menacheri/zombie/game/ZombieRoom.java +++ b/example-games/src/main/java/io/nadron/example/zombie/game/ZombieRoom.java @@ -1,60 +1,61 @@ -package org.menacheri.zombie.game; - -import org.menacheri.jetserver.app.PlayerSession; -import org.menacheri.jetserver.app.impl.GameRoomSession; -import org.menacheri.zombie.domain.Defender; -import org.menacheri.zombie.domain.IAM; -import org.menacheri.zombie.domain.World; -import org.menacheri.zombie.domain.Zombie; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class ZombieRoom extends GameRoomSession -{ - private static final Logger LOG = LoggerFactory.getLogger(ZombieRoom.class); - - private Defender defender; - private Zombie zombie; - - public ZombieRoom(GameRoomSessionBuilder sessionBuilder) - { - super(sessionBuilder); - } - - public ZombieRoom(GameRoomSessionBuilder sessionBuilder, World world, Defender defender, Zombie zombie) - { - super(sessionBuilder); - this.defender = defender; - this.zombie = zombie; - } - - @Override - public void onLogin(PlayerSession playerSession) - { - SessionHandler listener = new SessionHandler(playerSession,defender, zombie, - IAM.ZOMBIE); - playerSession.addHandler(listener); - LOG.trace("Added event listener in Zombie Room"); - } - - public Defender getDefender() - { - return defender; - } - - public void setDefender(Defender defender) - { - this.defender = defender; - } - - public Zombie getZombie() - { - return zombie; - } - - public void setZombie(Zombie zombie) - { - this.zombie = zombie; - } -} +package io.nadron.example.zombie.game; + +import io.nadron.app.PlayerSession; +import io.nadron.app.impl.GameRoomSession; +import io.nadron.example.zombie.domain.Defender; +import io.nadron.example.zombie.domain.IAM; +import io.nadron.example.zombie.domain.World; +import io.nadron.example.zombie.domain.Zombie; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class ZombieRoom extends GameRoomSession +{ + private static final Logger LOG = LoggerFactory.getLogger(ZombieRoom.class); + + private Defender defender; + private Zombie zombie; + + public ZombieRoom(GameRoomSessionBuilder sessionBuilder) + { + super(sessionBuilder); + } + + public ZombieRoom(GameRoomSessionBuilder sessionBuilder, World world, Defender defender, Zombie zombie) + { + super(sessionBuilder); + this.defender = defender; + this.zombie = zombie; + } + + @Override + public void onLogin(PlayerSession playerSession) + { + SessionHandler listener = new SessionHandler(playerSession,defender, zombie, + IAM.ZOMBIE); + playerSession.addHandler(listener); + LOG.trace("Added event listener in Zombie Room"); + } + + public Defender getDefender() + { + return defender; + } + + public void setDefender(Defender defender) + { + this.defender = defender; + } + + public Zombie getZombie() + { + return zombie; + } + + public void setZombie(Zombie zombie) + { + this.zombie = zombie; + } +} diff --git a/example-games/src/main/java/org/menacheri/zombie/game/Messages.java b/example-games/src/main/java/org/menacheri/zombie/game/Messages.java deleted file mode 100644 index 023e491e..00000000 --- a/example-games/src/main/java/org/menacheri/zombie/game/Messages.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.menacheri.zombie.game; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.menacheri.zombie.domain.ZombieCommands; - - -/** - * This class acts like a message factory for creating game specific messages. - * @author Abraham Menacherry - * - */ -public class Messages -{ - public static ChannelBuffer apocalypse() - { - ChannelBuffer buffer = ChannelBuffers.buffer(4); - int cmd = ZombieCommands.APOCALYPSE.getCommand(); - buffer.writeInt(cmd); - return buffer; - } -} diff --git a/example-games/src/main/java/org/menacheri/zombie/game/ZombieSpringConfig.java b/example-games/src/main/java/org/menacheri/zombie/game/ZombieSpringConfig.java deleted file mode 100644 index e18821a2..00000000 --- a/example-games/src/main/java/org/menacheri/zombie/game/ZombieSpringConfig.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.menacheri.zombie.game; - -import java.util.HashMap; -import java.util.Map; - -import org.menacheri.jetserver.app.Game; -import org.menacheri.jetserver.app.GameRoom; -import org.menacheri.jetserver.app.impl.SimpleGame; -import org.menacheri.jetserver.app.impl.GameRoomSession.GameRoomSessionBuilder; -import org.menacheri.jetserver.protocols.Protocol; -import org.menacheri.jetserver.service.LookupService; -import org.menacheri.jetserver.service.impl.SimpleLookupService; -import org.menacheri.zombie.domain.Defender; -import org.menacheri.zombie.domain.World; -import org.menacheri.zombie.domain.Zombie; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; - -/** - * This class contains the spring configuration for the jetserver library user. - * The only bean that should compulsorily be declared is lookupService bean. - * Otherwise the program will terminate with a context load error from spring - * framework. The other beans declared can also be created using **new** - * operator as per programmer convenience. - * - * @author Abraham Menacherry. - * - */ -@Configuration -@ImportResource("classpath:/beans/beans.xml") -public class ZombieSpringConfig -{ - @Autowired - @Qualifier("messageBufferProtocol") - private Protocol messageBufferProtocol; - - @Autowired - @Qualifier("webSocketProtocol") - private Protocol webSocketProtocol; - - public @Bean Game zombieGame() - { - Game game = new SimpleGame(1,"Zombie"); - return game; - } - - public @Bean(name="Zombie_ROOM_1") GameRoom zombieRoom1() - { - GameRoomSessionBuilder sessionBuilder = new GameRoomSessionBuilder(); - sessionBuilder.parentGame(zombieGame()).gameRoomName("Zombie_ROOM_1").protocol(messageBufferProtocol); - ZombieRoom room = new ZombieRoom(sessionBuilder); - room.setDefender(defender()); - room.setZombie(zombie()); - - return room; - } - - public @Bean(name="Zombie_ROOM_2") GameRoom zombieRoom2() - { - GameRoomSessionBuilder sessionBuilder = new GameRoomSessionBuilder(); - sessionBuilder.parentGame(zombieGame()).gameRoomName("Zombie_ROOM_2").protocol(webSocketProtocol); - ZombieRoom room = new ZombieRoom(sessionBuilder); - room.setDefender(defender()); - room.setZombie(zombie()); - - return room; - } - - public @Bean World world() - { - World world = new World(); - world.setAlive(2000000000); - world.setUndead(1); - return world; - } - - public @Bean Defender defender() - { - Defender defender = new Defender(); - defender.setWorld(world()); - return defender; - } - - public @Bean Zombie zombie() - { - Zombie zombie = new Zombie(); - zombie.setWorld(world()); - return zombie; - } - - - public @Bean(name="lookupService") LookupService lookupService() - { - Map refKeyGameRoomMap = new HashMap(); - refKeyGameRoomMap.put("Zombie_ROOM_1_REF_KEY_1", zombieRoom1()); - refKeyGameRoomMap.put("Zombie_ROOM_1_REF_KEY_2", zombieRoom2()); - LookupService service = new SimpleLookupService(refKeyGameRoomMap); - return service; - } -} diff --git a/example-games/src/main/resources/beans/beans.xml b/example-games/src/main/resources/beans/beans.xml index db55945e..444baf42 100644 --- a/example-games/src/main/resources/beans/beans.xml +++ b/example-games/src/main/resources/beans/beans.xml @@ -1,13 +1,13 @@ - - - - - - - - - + + + + + + + + + diff --git a/example-games/src/test/java/io/nadron/example/lostdecade/LDClient.java b/example-games/src/test/java/io/nadron/example/lostdecade/LDClient.java new file mode 100644 index 00000000..5339bddc --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/lostdecade/LDClient.java @@ -0,0 +1,72 @@ +package io.nadron.example.lostdecade; + +import io.nadron.client.app.Session; +import io.nadron.client.app.impl.SessionFactory; +import io.nadron.client.event.Event; +import io.nadron.client.event.Events; +import io.nadron.client.event.NetworkEvent; +import io.nadron.client.event.impl.AbstractSessionEventHandler; +import io.nadron.client.event.impl.StartEventHandler; +import io.nadron.client.protocol.impl.NettyObjectProtocol; +import io.nadron.client.util.LoginHelper; +import io.nadron.client.util.LoginHelper.LoginBuilder; + +import java.net.UnknownHostException; +import java.util.HashSet; + +public class LDClient { + + /** + * @param args + * @throws Exception + * @throws UnknownHostException + */ + public static void main(String[] args) throws UnknownHostException, Exception { + LoginBuilder builder = new LoginBuilder().username("user") + .password("pass").connectionKey("LDGameRoomForNettyClient") + .nadronTcpHostName("localhost").tcpPort(18090); + LoginHelper loginHelper = builder.build(); + SessionFactory sessionFactory = new SessionFactory(loginHelper); + sessionFactory.setLoginHelper(loginHelper); + final Session session = sessionFactory.createSession(); + + // add handler for start event, and continue rest of game logic from there. + session.addHandler(new StartEventHandler(session) { + + @Override + public void onEvent(Event event) { + System.out.println("Received start event, going to change protocol"); + session.resetProtocol(NettyObjectProtocol.INSTANCE); + // create LDState objects send it to server. + Entity heroEntity = new Entity(); + heroEntity.setId("1"); + heroEntity.setType(Entity.HERO); + heroEntity.setScore(100); + heroEntity.setX(0); + heroEntity.setY(0); + LDGameState state = new LDGameState(new HashSet(),null, heroEntity); + NetworkEvent networkEvent = Events.networkEvent(state); + session.removeHandler(this); + addDefaultHandlerToSession(session); + session.onEvent(networkEvent); + } + }); + + // Connect the session, so that the above start event will be sent by server. + sessionFactory.connectSession(session); + } + + private static void addDefaultHandlerToSession(Session session) + { + // we are only interested in data in, so override only that method. + AbstractSessionEventHandler handler = new AbstractSessionEventHandler(session) + { + @Override + public void onDataIn(Event event) + { + System.out.println("Received data from server"); + } + }; + session.addHandler(handler); + } +} diff --git a/example-games/src/test/java/io/nadron/example/zombie/DefenderHandler.java b/example-games/src/test/java/io/nadron/example/zombie/DefenderHandler.java new file mode 100644 index 00000000..c82f7094 --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/zombie/DefenderHandler.java @@ -0,0 +1,101 @@ +package io.nadron.example.zombie; + +import io.nadron.event.Event; +import io.nadron.event.Events; +import io.nadron.example.zombie.domain.IAM; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannel; + +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + + +public class DefenderHandler extends SimpleChannelInboundHandler +{ + private static final IAM I_AM = IAM.DEFENDER; + private static final Map CLIENTS = new HashMap(); + private final UDPClient udpClient; + + @Override + public void channelRead0(ChannelHandlerContext ctx, + Event event) throws Exception + { + if (Events.START == event.getType()) + { + // TCP write to server + WriteByte write = new WriteByte(ctx.channel(), null, + IAM.DEFENDER); + ZombieClient.SERVICE.scheduleAtFixedRate(write, 10000l, 500, + TimeUnit.MILLISECONDS); + // For UDP write to server + connectUDP(ctx.channel()); + } + else if (Events.NETWORK_MESSAGE == event.getType()) + { + ByteBuf buffer = (ByteBuf) event.getSource(); + if (buffer.readableBytes() >= 4) + { + System.out + .println("UDP event from server in DefenderHandler: " + + buffer.readInt()); + } + else + { + System.out + .println("UDP Event does not have expected data in DefenderHandler"); + } + } + } + + public DefenderHandler() throws UnknownHostException, InterruptedException + { + this.udpClient = new UDPClient(this, I_AM, "255.255.255.255", 18090, + new NioEventLoopGroup()); + } + + public InetSocketAddress connectLocal() throws UnknownHostException, InterruptedException + { + DatagramChannel c = udpClient.createDatagramChannel(); + InetSocketAddress localAddress = udpClient.getLocalAddress(c); + CLIENTS.put(localAddress, c); + return localAddress; + } + + public void connectUDP(Channel channel) + { + InetSocketAddress address = ZombieClient.CHANNEL_ID_ADDRESS_MAP.get(channel); + System.out.println("UDP address for connect UDP: " + address); + final DatagramChannel c = CLIENTS.get(address); + if ((udpClient != null) && (c != null)) + { + System.out.println("Going to connect UDP in DefenderHandler"); + // Connect the UDP + Runnable runnable = new Runnable() + { + @Override + public void run() + { + udpClient.start(c); + } + }; + ZombieClient.SERVICE.submit(runnable); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) + throws Exception { + System.out.println("\nException caught in class DefenderHandler"); + cause.printStackTrace(); + ctx.channel().close(); + ZombieClient.SERVICE.shutdown(); + } + +} diff --git a/example-games/src/test/java/org/menacheri/zombie/PipelineFactory.java b/example-games/src/test/java/io/nadron/example/zombie/PipelineFactory.java similarity index 55% rename from example-games/src/test/java/org/menacheri/zombie/PipelineFactory.java rename to example-games/src/test/java/io/nadron/example/zombie/PipelineFactory.java index fe95ab9f..e48d8cac 100644 --- a/example-games/src/test/java/org/menacheri/zombie/PipelineFactory.java +++ b/example-games/src/test/java/io/nadron/example/zombie/PipelineFactory.java @@ -1,70 +1,73 @@ -package org.menacheri.zombie; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandler; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; -import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.handlers.netty.EventDecoder; - - -public class PipelineFactory implements ChannelPipelineFactory -{ - private static final LengthFieldPrepender LENGTH_FIELD_PREPENDER = new LengthFieldPrepender(2); - private static final TimerCanceller CANCELLER = new TimerCanceller("Zombie",ZombieClient.SERVICE); - private static final EventDecoder EVENT_DECODER = new EventDecoder(); - private static final StartEventCounter COUNTER = new StartEventCounter(); - private final ChannelHandler businessHandler; - private static final AtomicInteger INTEGER = new AtomicInteger(0); - public PipelineFactory(ChannelHandler handler) - { - this.businessHandler = handler; - } - - @Override - public ChannelPipeline getPipeline() throws Exception - { - ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("lengthDecoder", new LengthFieldBasedFrameDecoder(256, 0, 2,0,2)); - pipeline.addLast("lengthFieldPrepender", LENGTH_FIELD_PREPENDER); - pipeline.addLast("eventDecoder", EVENT_DECODER); - pipeline.addLast("counter", COUNTER); - pipeline.addLast("businessHandler",businessHandler); - pipeline.addLast("canceller",CANCELLER); - - return pipeline; - } - - public static class StartEventCounter extends OneToOneDecoder - { - private final AtomicInteger counter = new AtomicInteger(0); - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - Event event = (Event)msg; - if(Events.START == event.getType()) - { - int started = counter.incrementAndGet(); - System.out.println("Started: " + started); - } - else if(Events.NETWORK_MESSAGE == event.getType()) - { - System.out.println("Client Recieved Data No: " + INTEGER.addAndGet(5000)); - } - else - { - System.out.println("Recieved eventType: " + event.getType()); - } - return msg; - } - } -} +package io.nadron.example.zombie; + +import io.nadron.event.Event; +import io.nadron.event.Events; +import io.nadron.handlers.netty.EventDecoder; +import io.nadron.handlers.netty.MessageBufferEventEncoder; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import io.netty.handler.codec.LengthFieldPrepender; +import io.netty.handler.codec.MessageToMessageDecoder; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + + + +public class PipelineFactory extends ChannelInitializer +{ + private static final LengthFieldPrepender LENGTH_FIELD_PREPENDER = new LengthFieldPrepender(2); + private static final TimerCanceller CANCELLER = new TimerCanceller("Zombie",ZombieClient.SERVICE); + private static final EventDecoder EVENT_DECODER = new EventDecoder(); + private static final MessageBufferEventEncoder EVENT_ENCODER= new MessageBufferEventEncoder(); + private static final StartEventCounter COUNTER = new StartEventCounter(); + private final ChannelHandler businessHandler; + private static final AtomicInteger INTEGER = new AtomicInteger(0); + public PipelineFactory(ChannelHandler handler) + { + this.businessHandler = handler; + } + + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + pipeline.addLast("lengthDecoder", new LengthFieldBasedFrameDecoder(256, 0, 2,0,2)); + pipeline.addLast("lengthFieldPrepender", LENGTH_FIELD_PREPENDER); + pipeline.addLast("eventDecoder", EVENT_DECODER); + //pipeline.addLast("eventEncoder" , EVENT_ENCODER); + pipeline.addLast("counter", COUNTER); + pipeline.addLast("businessHandler",businessHandler); + pipeline.addLast("canceller",CANCELLER); + } + + public static class StartEventCounter extends MessageToMessageDecoder + { + private final AtomicInteger counter = new AtomicInteger(0); + + @Override + protected void decode(ChannelHandlerContext ctx, Event event, + List out) throws Exception + { + if(Events.START == event.getType()) + { + int started = counter.incrementAndGet(); + System.out.println("Started: " + started); + } + else if(Events.NETWORK_MESSAGE == event.getType()) + { + System.out.println("Client Recieved Data No: " + INTEGER.addAndGet(5000)); + } + else + { + System.out.println("Recieved eventType: " + event.getType()); + } + out.add(event); + } + + } + +} diff --git a/example-games/src/test/java/io/nadron/example/zombie/TimerCanceller.java b/example-games/src/test/java/io/nadron/example/zombie/TimerCanceller.java new file mode 100644 index 00000000..fa115180 --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/zombie/TimerCanceller.java @@ -0,0 +1,51 @@ +package io.nadron.example.zombie; + +import io.nadron.event.Event; +import io.nadron.event.Events; +import io.nadron.example.zombie.domain.ZombieCommands; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +import java.util.concurrent.ScheduledExecutorService; + + + +public class TimerCanceller extends SimpleChannelInboundHandler +{ + String type = null; + ScheduledExecutorService service = null; + public TimerCanceller(String type,ScheduledExecutorService service) + { + this.type = type; + this.service = service; + } + + @Override + public void channelRead0(ChannelHandlerContext ctx, + Event event) throws Exception + { + if(Events.NETWORK_MESSAGE == event.getType()) + { + ByteBuf apocalypse = (ByteBuf) event.getSource(); + if(apocalypse.readableBytes()>=4) + { + int cmd = apocalypse.readInt(); + ZombieCommands command = ZombieCommands.CommandsEnum.fromInt(cmd); + if(command == ZombieCommands.APOCALYPSE) + { + System.out.println("Cancelling " + type + " timer due to apocalypse"); + service.shutdown(); + ctx.channel().close(); + } + } + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) + throws Exception { + cause.printStackTrace(); + ctx.channel().close(); + } +} diff --git a/example-games/src/test/java/io/nadron/example/zombie/UDPClient.java b/example-games/src/test/java/io/nadron/example/zombie/UDPClient.java new file mode 100644 index 00000000..c2aba182 --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/zombie/UDPClient.java @@ -0,0 +1,111 @@ +package io.nadron.example.zombie; + +import io.nadron.event.Events; +import io.nadron.example.zombie.domain.IAM; +import io.nadron.handlers.netty.EventDecoder; +import io.nadron.util.NettyUtils; +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.socket.DatagramChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.UnknownHostException; +import java.util.concurrent.TimeUnit; + + + +public class UDPClient +{ + private static final EventDecoder EVENT_DECODER = new EventDecoder(); + private final Bootstrap b; + private final IAM iam; + private final SocketAddress serverAddress; + + public UDPClient( + final ChannelInboundHandlerAdapter businessHandler, + IAM iam, String remoteHost, int remotePort, EventLoopGroup boss) + throws UnknownHostException, InterruptedException + { + this.iam = iam; + this.serverAddress = new InetSocketAddress(remoteHost,remotePort); + // Create only one bootstrap per instance. But use it to make multiple udp channels. + b = new Bootstrap(); + b.group(boss).channel(NioDatagramChannel.class) + .option(ChannelOption.SO_BROADCAST, true) + .handler(new ChannelInitializer() { + + @Override + protected void initChannel(Channel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast("eventDecoder", EVENT_DECODER); + p.addLast("businessHandler", businessHandler); + } + + }); + + } + + /** + * Method used to create a datagram channel from the bootstrap instance. + * @return + * @throws UnknownHostException + */ + public DatagramChannel createDatagramChannel() throws UnknownHostException, InterruptedException + { + String localHost = InetAddress.getLocalHost().getHostAddress(); + DatagramChannel c = (DatagramChannel) b.bind( new InetSocketAddress(localHost,0)).sync().channel(); + return c; + } + + public InetSocketAddress getLocalAddress(DatagramChannel c) + { + InetSocketAddress add = (InetSocketAddress)c.localAddress(); + return add; + } + + public void start(DatagramChannel c) + { + try{ + if(c.isActive()) + { + // Write the connect statement. TODO repeat till we get start. + System.out.println("Events.CONNECT: " + Events.CONNECT); + ByteBuf buf = NettyUtils.createBufferForOpcode(Events.CONNECT); + + ChannelFuture future = c.write(buf); + future.addListener(new ChannelFutureListener() + { + @Override + public void operationComplete(ChannelFuture future) throws Exception + { + if(!future.isSuccess()) + { + System.out.println("CONNECT_UDP write to server unsuccessful: " + future.cause().getMessage()); + } + } + }); + + future.awaitUninterruptibly(); + WriteByte write = new WriteByte(c, serverAddress, iam); + ZombieClient.SERVICE.scheduleAtFixedRate(write,10000l,5000l, TimeUnit.MILLISECONDS); + } + else + { + System.out.println("Error: datagram channel is not bound"); + } + }catch(Exception e){ + e.printStackTrace(); + } + } +} diff --git a/example-games/src/test/java/org/menacheri/zombie/WriteByte.java b/example-games/src/test/java/io/nadron/example/zombie/WriteByte.java similarity index 60% rename from example-games/src/test/java/org/menacheri/zombie/WriteByte.java rename to example-games/src/test/java/io/nadron/example/zombie/WriteByte.java index 9e39b7ed..d9484833 100644 --- a/example-games/src/test/java/org/menacheri/zombie/WriteByte.java +++ b/example-games/src/test/java/io/nadron/example/zombie/WriteByte.java @@ -1,68 +1,69 @@ -package org.menacheri.zombie; - -import java.net.SocketAddress; -import java.util.TimerTask; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.socket.DatagramChannel; -import org.menacheri.jetserver.event.Events; -import org.menacheri.zombie.domain.IAM; -import org.menacheri.zombie.domain.ZombieCommands; - - -public class WriteByte extends TimerTask -{ - - Channel channel; - IAM iam; - SocketAddress remoteAddress; - - public WriteByte(Channel channel,SocketAddress remoteAddress,IAM iam) - { - this.channel = channel; - this.remoteAddress = remoteAddress; - this.iam = iam; - } - - @Override - public void run() - { - int type = IAM.getInt(iam); - int operation = 0; - switch(iam) - { - case DEFENDER: - operation = ZombieCommands.SHOT_GUN.getCommand(); - break; - case ZOMBIE: - operation = ZombieCommands.EAT_BRAINS.getCommand(); - break; - } - ChannelBuffer buf = null; - if(null == remoteAddress){ - //TCP - for(int i =0; i < 10;i++){ - buf = ChannelBuffers.buffer(1 + 8); - buf.writeByte(Events.SESSION_MESSAGE); - buf.writeInt(type); - buf.writeInt(operation); - channel.write(buf); - } - } - else - { - //UDP - DatagramChannel udpChannel = (DatagramChannel)channel; - buf = ChannelBuffers.buffer(1 + 8); - buf.writeByte(Events.SESSION_MESSAGE); - buf.writeInt(type); - buf.writeInt(operation); - for(int i =0; i < 10;i++){ - udpChannel.write(buf, remoteAddress); - } - } - - } -} +package io.nadron.example.zombie; + +import io.nadron.event.Events; +import io.nadron.example.zombie.domain.IAM; +import io.nadron.example.zombie.domain.ZombieCommands; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.socket.DatagramChannel; + +import java.net.SocketAddress; +import java.util.TimerTask; + + + +public class WriteByte extends TimerTask +{ + + Channel channel; + IAM iam; + SocketAddress remoteAddress; + + public WriteByte(Channel channel,SocketAddress remoteAddress,IAM iam) + { + this.channel = channel; + this.remoteAddress = remoteAddress; + this.iam = iam; + } + + @Override + public void run() + { + int type = IAM.getInt(iam); + int operation = 0; + switch(iam) + { + case DEFENDER: + operation = ZombieCommands.SHOT_GUN.getCommand(); + break; + case ZOMBIE: + operation = ZombieCommands.EAT_BRAINS.getCommand(); + break; + } + ByteBuf buf = null; + if(null == remoteAddress){ + //TCP + for(int i =0; i < 1;i++){ + buf = Unpooled.buffer(1 + 8); + buf.writeByte(Events.SESSION_MESSAGE); + buf.writeInt(type); + buf.writeInt(operation); + channel.write(buf); + } + } + else + { + //UDP + DatagramChannel udpChannel = (DatagramChannel)channel; + buf = Unpooled.buffer(1 + 8); + buf.writeByte(Events.SESSION_MESSAGE); + buf.writeInt(type); + buf.writeInt(operation); + for(int i =0; i < 1;i++){ + udpChannel.write(buf); + } + } + + } +} diff --git a/example-games/src/test/java/io/nadron/example/zombie/ZombieClient.java b/example-games/src/test/java/io/nadron/example/zombie/ZombieClient.java new file mode 100644 index 00000000..6ab6e9de --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/zombie/ZombieClient.java @@ -0,0 +1,124 @@ +package io.nadron.example.zombie; + +import io.nadron.event.Events; +import io.nadron.util.NettyUtils; +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; + +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + + +public class ZombieClient +{ + public static final ScheduledExecutorService SERVICE; + public static final Map CHANNEL_ID_ADDRESS_MAP; + + static { + SERVICE = Executors.newSingleThreadScheduledExecutor(); + CHANNEL_ID_ADDRESS_MAP = new HashMap(); + Runtime.getRuntime().addShutdownHook(new Thread(){ + @Override + public void run() + { + SERVICE.shutdown(); + } + }); + } + + public static void main(String[] args) throws UnknownHostException, InterruptedException + { + String host = "localhost"; + int port = 18090; + final DefenderHandler defHandler = new DefenderHandler(); + PipelineFactory defFactory = new PipelineFactory(defHandler); + final ZombieHandler zomHandler = new ZombieHandler(); + PipelineFactory zomFactory = new PipelineFactory(zomHandler); + EventLoopGroup boss = new NioEventLoopGroup(); + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(boss).channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY, true) + .option(ChannelOption.SO_KEEPALIVE, true); + for (int i = 1; i<=1;i++){ + final InetSocketAddress udpLocalAddress = null; + if(i%2==0){ + bootstrap.handler(defFactory); + //udpLocalAddress = defHandler.connectLocal(); + }else{ + bootstrap.handler(zomFactory); + //udpLocalAddress = zomHandler.connectLocal(); + } + InetSocketAddress remoteAddress = new InetSocketAddress(host, + port); + ChannelFuture future = bootstrap.connect(remoteAddress); + + future.addListener(new ChannelFutureListener() + { + @Override + public void operationComplete(ChannelFuture future) throws Exception + { + if (future.isSuccess()) + { + ByteBuf loginBuffer = getLoginBuffer("Zombie_ROOM_1", + writeSocketAddressToBuffer(udpLocalAddress)); + Channel channel = future.channel(); + CHANNEL_ID_ADDRESS_MAP.put(channel, + udpLocalAddress); + ChannelFuture writeFuture = channel.write(loginBuffer); + writeFuture.addListener(new ChannelFutureListener() + { + @Override + public void operationComplete(ChannelFuture future) + throws Exception + { + if (!future.isSuccess()) + { + future.cause().printStackTrace(); + } + } + }); + } + else + { + future.cause().printStackTrace(); + } + } + }); + } + } + + public static ByteBuf getLoginBuffer(String refKey, ByteBuf udpAddress) + { + ByteBuf header = Unpooled.buffer(2); + header.writeByte(Events.LOG_IN); + header.writeByte(Events.PROTCOL_VERSION); + String username = "user"; + String password = "pass"; + // write username,password and ref key. + ByteBuf buffer = Unpooled.wrappedBuffer(header, + NettyUtils.writeStrings(username,password,refKey),udpAddress); + return buffer; + } + + public static ByteBuf writeSocketAddressToBuffer(InetSocketAddress localAddress){ + ByteBuf hostName = NettyUtils.writeString(localAddress + .getHostName()); + ByteBuf portNum = Unpooled.buffer(4); + portNum.writeInt(localAddress.getPort()); + ByteBuf socketAddress = Unpooled.wrappedBuffer(hostName, + portNum); + return socketAddress; + } +} diff --git a/example-games/src/test/java/io/nadron/example/zombie/ZombieHandler.java b/example-games/src/test/java/io/nadron/example/zombie/ZombieHandler.java new file mode 100644 index 00000000..460857f1 --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/zombie/ZombieHandler.java @@ -0,0 +1,99 @@ +package io.nadron.example.zombie; + +import io.nadron.event.Event; +import io.nadron.event.Events; +import io.nadron.example.zombie.domain.IAM; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannel; + +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + + +public class ZombieHandler extends SimpleChannelInboundHandler +{ + private static final IAM I_AM = IAM.ZOMBIE; + private static final Map CLIENTS = new HashMap(); + private final UDPClient udpClient; + + public ZombieHandler() throws UnknownHostException, InterruptedException + { + udpClient = new UDPClient(this, I_AM, "255.255.255.255", 18090, + new NioEventLoopGroup()); + } + + public InetSocketAddress connectLocal() throws UnknownHostException, InterruptedException + { + DatagramChannel c = udpClient.createDatagramChannel(); + InetSocketAddress localAddress = udpClient.getLocalAddress(c); + CLIENTS.put(localAddress, c); + return localAddress; + } + + public void connectUDP(Channel channel) + { + InetSocketAddress address = ZombieClient.CHANNEL_ID_ADDRESS_MAP.get(channel); + System.out.println("UDP address for connect UDP: " + address); + final DatagramChannel c = CLIENTS.get(address); + if ((udpClient != null) && (c != null)) + { + // Connect the UDP + System.out.println("Going to connect UDP in ZombieHandler"); + Runnable runnable = new Runnable() + { + @Override + public void run() + { + udpClient.start(c); + } + }; + ZombieClient.SERVICE.submit(runnable); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) + throws Exception { + System.out.println("\nException caught in class ZombieHandler"); + cause.printStackTrace(); + ctx.channel().close(); + } + + @Override + public void channelRead0(ChannelHandlerContext ctx, + Event event) throws Exception + { + if (Events.START == event.getType()) + { + // TCP write to server + WriteByte write = new WriteByte(ctx.channel(), null, + IAM.DEFENDER); + ZombieClient.SERVICE.scheduleAtFixedRate(write, 10000l, 500, + TimeUnit.MILLISECONDS); + // For UDP write to server + connectUDP(ctx.channel()); + } + else if (Events.NETWORK_MESSAGE == event.getType()) + { + ByteBuf buffer = (ByteBuf) event.getSource(); + if (buffer.readableBytes() >= 4) + { + System.out + .println("UDP event from server in DefenderHandler: " + + buffer.readInt()); + } + else + { + System.out + .println("UDP Event does not have expected data in DefenderHandler"); + } + } + } +} diff --git a/example-games/src/test/java/io/nadron/example/zombieclient/GamePlay.java b/example-games/src/test/java/io/nadron/example/zombieclient/GamePlay.java new file mode 100644 index 00000000..06e77436 --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/zombieclient/GamePlay.java @@ -0,0 +1,48 @@ +package io.nadron.example.zombieclient; + +import io.nadron.client.app.Session; +import io.nadron.client.communication.MessageBuffer; +import io.nadron.client.communication.NettyMessageBuffer; +import io.nadron.client.communication.DeliveryGuaranty.DeliveryGuarantyOptions; +import io.nadron.client.event.Event; +import io.nadron.client.event.Events; +import io.nadron.example.zombie.domain.IAM; +import io.nadron.example.zombie.domain.ZombieCommands; +import io.netty.buffer.ByteBuf; + + +public class GamePlay implements Runnable +{ + private final IAM iam; + private final Session session; + + public GamePlay(IAM iam, Session session) + { + this.iam = iam; + this.session = session; + } + + @Override + public void run() + { + int type = IAM.getInt(iam); + int operation = 0; + switch(iam) + { + case DEFENDER: + operation = ZombieCommands.SHOT_GUN.getCommand(); + break; + case ZOMBIE: + operation = ZombieCommands.EAT_BRAINS.getCommand(); + break; + } + + for(int i = 1; i<10; i++){ + MessageBuffer messageBuffer = new NettyMessageBuffer(); + messageBuffer.writeInt(type); + messageBuffer.writeInt(operation); + Event event = Events.networkEvent(messageBuffer, DeliveryGuarantyOptions.FAST); + session.onEvent(event); + } + } +} diff --git a/example-games/src/test/java/org/menacheri/zombieclient/ReconnectionTest.java b/example-games/src/test/java/io/nadron/example/zombieclient/ReconnectionTest.java similarity index 71% rename from example-games/src/test/java/org/menacheri/zombieclient/ReconnectionTest.java rename to example-games/src/test/java/io/nadron/example/zombieclient/ReconnectionTest.java index d4f60eb1..7fe5cd05 100644 --- a/example-games/src/test/java/org/menacheri/zombieclient/ReconnectionTest.java +++ b/example-games/src/test/java/io/nadron/example/zombieclient/ReconnectionTest.java @@ -1,18 +1,19 @@ -package org.menacheri.zombieclient; +package io.nadron.example.zombieclient; + +import io.nadron.client.app.Session; +import io.nadron.client.app.impl.SessionFactory; +import io.nadron.client.communication.NettyMessageBuffer; +import io.nadron.client.communication.ReconnectPolicy; +import io.nadron.client.event.Event; +import io.nadron.client.event.impl.AbstractSessionEventHandler; +import io.nadron.client.util.LoginHelper; +import io.nadron.client.util.LoginHelper.LoginBuilder; +import io.nadron.example.zombie.domain.IAM; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import org.menacheri.jetclient.app.Session; -import org.menacheri.jetclient.app.impl.SessionFactory; -import org.menacheri.jetclient.communication.NettyMessageBuffer; -import org.menacheri.jetclient.communication.ReconnectPolicy; -import org.menacheri.jetclient.event.Event; -import org.menacheri.jetclient.event.impl.AbstractSessionEventHandler; -import org.menacheri.jetclient.util.LoginHelper; -import org.menacheri.jetclient.util.LoginHelper.LoginBuilder; -import org.menacheri.zombie.domain.IAM; public class ReconnectionTest { @@ -24,8 +25,8 @@ public static void main(String[] args) throws Exception { LoginBuilder builder = new LoginBuilder().username("user") .password("pass").connectionKey("Zombie_ROOM_1_REF_KEY_1") - .jetserverTcpHostName("localhost").tcpPort(18090) - .jetserverUdpHostName("255.255.255.255").udpPort(18090); + .nadronTcpHostName("localhost").tcpPort(18090) + .nadronUdpHostName("255.255.255.255").udpPort(18090); LoginHelper loginHelper = builder.build(); SessionFactory sessionFactory = new SessionFactory(loginHelper); ScheduledExecutorService taskExecutor = Executors.newSingleThreadScheduledExecutor(); diff --git a/example-games/src/test/java/io/nadron/example/zombieclient/ZombieNadclient.java b/example-games/src/test/java/io/nadron/example/zombieclient/ZombieNadclient.java new file mode 100644 index 00000000..66e29c97 --- /dev/null +++ b/example-games/src/test/java/io/nadron/example/zombieclient/ZombieNadclient.java @@ -0,0 +1,73 @@ +package io.nadron.example.zombieclient; + +import io.nadron.client.app.Session; +import io.nadron.client.app.impl.SessionFactory; +import io.nadron.client.communication.NettyMessageBuffer; +import io.nadron.client.event.Event; +import io.nadron.client.event.impl.AbstractSessionEventHandler; +import io.nadron.client.util.LoginHelper; +import io.nadron.client.util.LoginHelper.LoginBuilder; +import io.nadron.example.zombie.domain.IAM; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + + +public class ZombieNadclient +{ + public static void main(String[] args) throws Exception + { + LoginBuilder builder = new LoginBuilder().username("user") + .password("pass").connectionKey("Zombie_ROOM_1") + .nadronTcpHostName("localhost").tcpPort(18090) + .nadronUdpHostName("255.255.255.255").udpPort(18090); + ScheduledExecutorService taskExecutor = Executors.newSingleThreadScheduledExecutor(); + SessionFactory sessionFactory = null; + for(int i = 1; i<= 5 ; i++) + { + builder.connectionKey("Zombie_ROOM_" + i); + LoginHelper loginHelper = builder.build(); + if (i == 1) + { + sessionFactory = new SessionFactory(loginHelper); + } + else + { + // no need to create session factory objects again. + sessionFactory.setLoginHelper(loginHelper); + } + + for (int j = 1; j <= 20; j++) + { + Session session = sessionFactory.createAndConnectSession(); + addDefaultHandlerToSession(session); + GamePlay task = null; + if ((i % 2) == 0) + { + task = new GamePlay(IAM.DEFENDER, session); + } else + { + task = new GamePlay(IAM.ZOMBIE, session); + } + taskExecutor.scheduleAtFixedRate(task, 2000, 200, + TimeUnit.MILLISECONDS); + } + } + } + + private static void addDefaultHandlerToSession(Session session) + { + // we are only interested in data in, so override only that method. + AbstractSessionEventHandler handler = new AbstractSessionEventHandler(session) + { + @Override + public void onDataIn(Event event) + { + NettyMessageBuffer buffer = (NettyMessageBuffer)event.getSource(); + System.out.println("Remaining Human Population: " + buffer.readInt()); + } + }; + session.addHandler(handler); + } +} diff --git a/example-games/src/test/java/org/menacheri/zombie/DefenderHandler.java b/example-games/src/test/java/org/menacheri/zombie/DefenderHandler.java deleted file mode 100644 index c1a63e50..00000000 --- a/example-games/src/test/java/org/menacheri/zombie/DefenderHandler.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.menacheri.zombie; - -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.jboss.netty.channel.socket.DatagramChannel; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.menacheri.zombie.domain.IAM; - -public class DefenderHandler extends SimpleChannelUpstreamHandler -{ - private static final IAM I_AM = IAM.DEFENDER; - private static final Map CLIENTS = new HashMap(); - private final UDPClient udpClient; - - public DefenderHandler() - { - this.udpClient = new UDPClient(this, I_AM, "255.255.255.255", 18090, - Executors.newCachedThreadPool()); - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) - throws Exception - { - Object message = e.getMessage(); - if (message instanceof Event) - { - Event event = (Event) message; - if (Events.START == event.getType()) - { - // TCP write to server - WriteByte write = new WriteByte(e.getChannel(), null, - IAM.DEFENDER); - ZombieClient.SERVICE.scheduleAtFixedRate(write, 10000l, 500, - TimeUnit.MILLISECONDS); - // For UDP write to server - connectUDP(e.getChannel()); - } - else if (Events.NETWORK_MESSAGE == event.getType()) - { - ChannelBuffer buffer = (ChannelBuffer) event.getSource(); - if (buffer.readableBytes() >= 4) - { - System.out - .println("UDP event from server in DefenderHandler: " - + buffer.readInt()); - } - else - { - System.out - .println("UDP Event does not have expected data in DefenderHandler"); - } - } - else - { - super.messageReceived(ctx, e); - } - } - } - - public InetSocketAddress connectLocal() throws UnknownHostException - { - DatagramChannel c = udpClient.createDatagramChannel(); - InetSocketAddress localAddress = udpClient.getLocalAddress(c); - CLIENTS.put(localAddress, c); - return localAddress; - } - - public void connectUDP(Channel channel) - { - InetSocketAddress address = ZombieClient.CHANNEL_ID_ADDRESS_MAP.get(channel.getId()); - System.out.println("UDP address for connect UDP: " + address); - final DatagramChannel c = CLIENTS.get(address); - if ((udpClient != null) && (c != null)) - { - System.out.println("Going to connect UDP in DefenderHandler"); - // Connect the UDP - Runnable runnable = new Runnable() - { - @Override - public void run() - { - udpClient.start(c); - } - }; - ZombieClient.SERVICE.submit(runnable); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception - { - System.out.println("\nException caught in class DefenderHandler"); - e.getCause().printStackTrace(); - e.getChannel().close(); - ZombieClient.SERVICE.shutdown(); - } - -} diff --git a/example-games/src/test/java/org/menacheri/zombie/TimerCanceller.java b/example-games/src/test/java/org/menacheri/zombie/TimerCanceller.java deleted file mode 100644 index e3d17e6c..00000000 --- a/example-games/src/test/java/org/menacheri/zombie/TimerCanceller.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.menacheri.zombie; - -import java.util.concurrent.ScheduledExecutorService; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.menacheri.zombie.domain.ZombieCommands; - - -public class TimerCanceller extends SimpleChannelUpstreamHandler -{ - String type = null; - ScheduledExecutorService service = null; - public TimerCanceller(String type,ScheduledExecutorService service) - { - this.type = type; - this.service = service; - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) - throws Exception - { - Object message = e.getMessage(); - if(message instanceof Event) - { - Event event = (Event)message; - if(Events.NETWORK_MESSAGE == event.getType()) - { - ChannelBuffer apocalypse = (ChannelBuffer) event.getSource(); - if(apocalypse.readableBytes()>=4) - { - int cmd = apocalypse.readInt(); - ZombieCommands command = ZombieCommands.CommandsEnum.fromInt(cmd); - if(command == ZombieCommands.APOCALYPSE) - { - System.out.println("Cancelling " + type + " timer due to apocalypse"); - service.shutdown(); - e.getChannel().close(); - } - } - } - } - if(message instanceof ChannelBuffer) - { - ChannelBuffer apocalypse = (ChannelBuffer) message; - if(apocalypse.readableBytes()>=4) - { - int cmd = apocalypse.readInt(); - ZombieCommands command = ZombieCommands.CommandsEnum.fromInt(cmd); - if(command == ZombieCommands.APOCALYPSE) - { - System.out.println("Cancelling " + type + " timer"); - service.shutdown(); - e.getChannel().close(); - } - } - } - super.messageReceived(ctx, e); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception - { - System.out.println("Going to close channel in timer canceller handler"); - e.getChannel().close(); - } -} diff --git a/example-games/src/test/java/org/menacheri/zombie/UDPClient.java b/example-games/src/test/java/org/menacheri/zombie/UDPClient.java deleted file mode 100644 index b4e35855..00000000 --- a/example-games/src/test/java/org/menacheri/zombie/UDPClient.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.menacheri.zombie; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.net.UnknownHostException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.TimeUnit; - -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; -import org.jboss.netty.channel.ChannelHandler; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.socket.DatagramChannel; -import org.jboss.netty.channel.socket.DatagramChannelFactory; -import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.handlers.netty.EventDecoder; -import org.menacheri.jetserver.util.NettyUtils; -import org.menacheri.zombie.domain.IAM; - - -public class UDPClient -{ - private static final EventDecoder EVENT_DECODER = new EventDecoder(); - private final ConnectionlessBootstrap b; - private final IAM iam; - private final SocketAddress serverAddress; - - public UDPClient(ChannelHandler businessHandler, IAM iam,String remoteHost, int remotePort,ExecutorService executorService) - { - this.iam = iam; - this.serverAddress = new InetSocketAddress(remoteHost,remotePort); - DatagramChannelFactory f = new NioDatagramChannelFactory(executorService); - // Create only one bootstrap per instance. But use it to make multiple udp channels. - b = new ConnectionlessBootstrap(f); - ChannelPipeline p = b.getPipeline(); - p.addLast("eventDecoder",EVENT_DECODER); - p.addLast("businessHandler", businessHandler); - b.setOption("broadcast", "true"); - } - - public ConnectionlessBootstrap getConnectionlessBootstrap() - { - return b; - } - - /** - * Method used to create a datagram channel from the bootstrap instance. - * @return - * @throws UnknownHostException - */ - public DatagramChannel createDatagramChannel() throws UnknownHostException - { - String localHost = InetAddress.getLocalHost().getHostAddress(); - DatagramChannel c = (DatagramChannel) b.bind( new InetSocketAddress(localHost,0)); - return c; - } - - public InetSocketAddress getLocalAddress(DatagramChannel c) - { - InetSocketAddress add = (InetSocketAddress)c.getLocalAddress(); - return add; - } - - public void start(DatagramChannel c) - { - try{ - if(c.isBound()) - { - // Write the connect statement. TODO repeat till we get start. - System.out.println("Events.CONNECT: " + Events.CONNECT); - ChannelBuffer buf = NettyUtils.createBufferForOpcode(Events.CONNECT); - - ChannelFuture future = c.write(buf, serverAddress); - future.addListener(new ChannelFutureListener() - { - @Override - public void operationComplete(ChannelFuture future) throws Exception - { - if(!future.isSuccess()) - { - System.out.println("CONNECT_UDP write to server unsuccessful: " + future.getCause().getMessage()); - } - } - }); - - future.awaitUninterruptibly(); - WriteByte write = new WriteByte(c, serverAddress,iam); - ZombieClient.SERVICE.scheduleAtFixedRate(write,10000l,5000l, TimeUnit.MILLISECONDS); - } - else - { - System.out.println("Error: datagram channel is not bound"); - } - }catch(Exception e){ - e.printStackTrace(); - } - } -} diff --git a/example-games/src/test/java/org/menacheri/zombie/ZombieClient.java b/example-games/src/test/java/org/menacheri/zombie/ZombieClient.java deleted file mode 100644 index f7a25daa..00000000 --- a/example-games/src/test/java/org/menacheri/zombie/ZombieClient.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.menacheri.zombie; - - -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - -import org.jboss.netty.bootstrap.ClientBootstrap; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFactory; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelFutureListener; -import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.util.NettyUtils; - - -public class ZombieClient -{ - public static final ScheduledExecutorService SERVICE; - public static final Map CHANNEL_ID_ADDRESS_MAP; - - static { - SERVICE = Executors.newSingleThreadScheduledExecutor(); - CHANNEL_ID_ADDRESS_MAP = new HashMap(); - Runtime.getRuntime().addShutdownHook(new Thread(){ - @Override - public void run() - { - SERVICE.shutdown(); - } - }); - } - - public static void main(String[] args) throws UnknownHostException - { - String host = "localhost"; - int port = 18090; - ChannelFactory factory = new NioClientSocketChannelFactory(Executors - .newCachedThreadPool(), Executors.newCachedThreadPool()); - final DefenderHandler defHandler = new DefenderHandler(); - PipelineFactory defFactory = new PipelineFactory(defHandler); - final ZombieHandler zomHandler = new ZombieHandler(); - PipelineFactory zomFactory = new PipelineFactory(zomHandler); - ClientBootstrap bootstrap = new ClientBootstrap(factory); - // At client side option is tcpNoDelay and at server child.tcpNoDelay - bootstrap.setOption("tcpNoDelay", true); - bootstrap.setOption("keepAlive", true); - for (int i = 1; i<=50;i++){ - final InetSocketAddress udpLocalAddress; - if(i%2==0){ - bootstrap.setPipelineFactory(defFactory); - udpLocalAddress = defHandler.connectLocal(); - }else{ - bootstrap.setPipelineFactory(zomFactory); - udpLocalAddress = zomHandler.connectLocal(); - } - - ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, - port)); - - future.addListener(new ChannelFutureListener() - { - @Override - public void operationComplete(ChannelFuture future) throws Exception - { - ChannelBuffer loginBuffer = getLoginBuffer("Zombie_ROOM_1_REF_KEY_1",writeSocketAddressToBuffer(udpLocalAddress)); - Channel channel = future.getChannel(); - CHANNEL_ID_ADDRESS_MAP.put(channel.getId(), udpLocalAddress); - channel.write(loginBuffer); - } - }); - } - } - - public static ChannelBuffer getLoginBuffer(String refKey, ChannelBuffer udpAddress) - { - ChannelBuffer opcode = ChannelBuffers.buffer(1); - ChannelBuffer protocol = ChannelBuffers.buffer(1); - opcode.writeByte(Events.LOG_IN); - protocol.writeByte(Events.PROTCOL_VERSION); - String username = "user"; - String password = "pass"; - // write username,password and ref key. - ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(opcode,protocol, - NettyUtils.writeStrings(username,password,refKey),udpAddress); - return buffer; - } - - public static ChannelBuffer writeSocketAddressToBuffer(InetSocketAddress localAddress){ - ChannelBuffer hostName = NettyUtils.writeString(localAddress - .getHostName()); - ChannelBuffer portNum = ChannelBuffers.buffer(4); - portNum.writeInt(localAddress.getPort()); - ChannelBuffer socketAddress = ChannelBuffers.wrappedBuffer(hostName, - portNum); - return socketAddress; - } -} diff --git a/example-games/src/test/java/org/menacheri/zombie/ZombieHandler.java b/example-games/src/test/java/org/menacheri/zombie/ZombieHandler.java deleted file mode 100644 index 7f9f564c..00000000 --- a/example-games/src/test/java/org/menacheri/zombie/ZombieHandler.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.menacheri.zombie; - -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.jboss.netty.channel.socket.DatagramChannel; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.menacheri.zombie.domain.IAM; - -public class ZombieHandler extends SimpleChannelUpstreamHandler -{ - private static final IAM I_AM = IAM.ZOMBIE; - private static final Map CLIENTS = new HashMap(); - private final UDPClient udpClient; - - public ZombieHandler() - { - udpClient = new UDPClient(this, I_AM, "255.255.255.255", 18090, - Executors.newCachedThreadPool()); - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) - throws Exception - { - Object message = e.getMessage(); - if (message instanceof Event) - { - Event event = (Event) message; - if (Events.START == event.getType()) - { - // TCP write to server - WriteByte write = new WriteByte(e.getChannel(), null, - IAM.ZOMBIE); - ZombieClient.SERVICE.scheduleAtFixedRate(write, 2000l, - 500l, TimeUnit.MILLISECONDS); - // For UDP write to server - connectUDP(e.getChannel()); - } - else if (Events.LOG_IN_SUCCESS == event.getType()) - { - - } - else if (Events.NETWORK_MESSAGE == event.getType()) - { - ChannelBuffer buffer = (ChannelBuffer) event.getSource(); - if (buffer.readableBytes() >= 4) - { - System.out - .println("UDP event from server in ZombieHandler: " - + buffer.readInt()); - } - else - { - System.out - .println("UDP Event does not have expected data in ZombieHandler"); - } - } - else - { - super.messageReceived(ctx, e); - } - } - - } - - public InetSocketAddress connectLocal() throws UnknownHostException - { - DatagramChannel c = udpClient.createDatagramChannel(); - InetSocketAddress localAddress = udpClient.getLocalAddress(c); - CLIENTS.put(localAddress, c); - return localAddress; - } - - public void connectUDP(Channel channel) - { - InetSocketAddress address = ZombieClient.CHANNEL_ID_ADDRESS_MAP.get(channel.getId()); - System.out.println("UDP address for connect UDP: " + address); - final DatagramChannel c = CLIENTS.get(address); - if ((udpClient != null) && (c != null)) - { - // Connect the UDP - System.out.println("Going to connect UDP in ZombieHandler"); - Runnable runnable = new Runnable() - { - @Override - public void run() - { - udpClient.start(c); - } - }; - ZombieClient.SERVICE.submit(runnable); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception - { - System.out.println("\nException caught in class ZombieHandler"); - System.out.println(e.getCause()); - e.getChannel().close(); - } -} diff --git a/example-games/src/test/java/org/menacheri/zombieclient/GamePlay.java b/example-games/src/test/java/org/menacheri/zombieclient/GamePlay.java deleted file mode 100644 index 0c8ae8a6..00000000 --- a/example-games/src/test/java/org/menacheri/zombieclient/GamePlay.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.menacheri.zombieclient; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.menacheri.jetclient.app.Session; -import org.menacheri.jetclient.communication.DeliveryGuaranty.DeliveryGuarantyOptions; -import org.menacheri.jetclient.communication.MessageBuffer; -import org.menacheri.jetclient.communication.NettyMessageBuffer; -import org.menacheri.jetclient.event.Event; -import org.menacheri.jetclient.event.Events; -import org.menacheri.zombie.domain.IAM; -import org.menacheri.zombie.domain.ZombieCommands; - -public class GamePlay implements Runnable -{ - private final IAM iam; - private final Session session; - - public GamePlay(IAM iam, Session session) - { - this.iam = iam; - this.session = session; - } - - @Override - public void run() - { - int type = IAM.getInt(iam); - int operation = 0; - switch(iam) - { - case DEFENDER: - operation = ZombieCommands.SHOT_GUN.getCommand(); - break; - case ZOMBIE: - operation = ZombieCommands.EAT_BRAINS.getCommand(); - break; - } - - MessageBuffer messageBuffer = new NettyMessageBuffer(); - messageBuffer.writeInt(type); - messageBuffer.writeInt(operation); - Event event = Events.networkEvent(messageBuffer,DeliveryGuarantyOptions.FAST); - session.onEvent(event); - } -} diff --git a/example-games/src/test/java/org/menacheri/zombieclient/ZombieJetclient.java b/example-games/src/test/java/org/menacheri/zombieclient/ZombieJetclient.java deleted file mode 100644 index 24221451..00000000 --- a/example-games/src/test/java/org/menacheri/zombieclient/ZombieJetclient.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.menacheri.zombieclient; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import org.menacheri.jetclient.app.Session; -import org.menacheri.jetclient.app.impl.SessionFactory; -import org.menacheri.jetclient.communication.NettyMessageBuffer; -import org.menacheri.jetclient.event.Event; -import org.menacheri.jetclient.event.impl.AbstractSessionEventHandler; -import org.menacheri.jetclient.util.LoginHelper; -import org.menacheri.jetclient.util.LoginHelper.LoginBuilder; -import org.menacheri.zombie.domain.IAM; - -public class ZombieJetclient -{ - public static void main(String[] args) throws Exception - { - LoginBuilder builder = new LoginBuilder().username("user") - .password("pass").connectionKey("Zombie_ROOM_1_REF_KEY_1") - .jetserverTcpHostName("localhost").tcpPort(18090) - .jetserverUdpHostName("255.255.255.255").udpPort(18090); - LoginHelper loginHelper = builder.build(); - SessionFactory sessionFactory = new SessionFactory(loginHelper); - ScheduledExecutorService taskExecutor = Executors.newSingleThreadScheduledExecutor(); - for(int i = 1; i<=50; i++){ - Session session = sessionFactory.createAndConnectSession(); - addDefaultHandlerToSession(session); - GamePlay task = null; - if((i % 2) == 0){ - task = new GamePlay(IAM.DEFENDER, session); - } - else{ - task = new GamePlay(IAM.ZOMBIE, session); - } - taskExecutor.scheduleAtFixedRate(task, 2000, 200, TimeUnit.MILLISECONDS); - } - } - - private static void addDefaultHandlerToSession(Session session) - { - // we are only interested in data in, so override only that method. - AbstractSessionEventHandler handler = new AbstractSessionEventHandler(session) - { - @Override - public void onDataIn(Event event) - { - NettyMessageBuffer buffer = (NettyMessageBuffer)event.getSource(); - System.out.println("Remaining Human Population: " + buffer.readInt()); - } - }; - session.addHandler(handler); - } -} diff --git a/jetclient-as3/pom.xml b/jetclient-as3/pom.xml index 84f5ad93..827a05de 100644 --- a/jetclient-as3/pom.xml +++ b/jetclient-as3/pom.xml @@ -1,17 +1,22 @@ - + 4.0.0 - org.menacheri - jetclient-as3 - 0.1 + com.github.menacher + nadclient-as3 + 0.5-SNAPSHOT swc - jetclient-as3 - https://github.com/menacher/java-game-server/tree/master/jetclient-as3 + nadclient-as3 + https://github.com/menacher/java-game-server/tree/netty4/jetclient-as3 This is an action script client library for jetserver. Flash/Air/Flex clients can use this library to connect and interact - with jetserver. + with nadron server. + + org.sonatype.oss + oss-parent + 7 + + GNU Lesser General Public License (LGPL), Version 2.1 @@ -20,7 +25,21 @@ - + + scm:git:git://github.com/menacher/java-game-server.git + scm:git:ssh://git@github.com/menacher/java-game-server.git + https://github.com/menacher/java-game-server.git + HEAD + + + + + menacher + Abraham Menacherry + abrahammenacherry@gmail.com + + + UTF-8 @@ -29,6 +48,7 @@ src/main/flex src/test/flex + org.sonatype.flexmojos flexmojos-maven-plugin @@ -38,6 +58,24 @@ true + + + org.apache.maven.plugins + maven-release-plugin + 2.4.1 + + + default + + perform + + + C:/Users/aby/Documents/GitHub/java-game-server/jetclient-as3/target/checkout/jetclient-as3/pom.xml + + + + + diff --git a/jetclient-as3/src/main/flex/org/menacheri/Main.as b/jetclient-as3/src/main/flex/io/nadron/Main.as similarity index 74% rename from jetclient-as3/src/main/flex/org/menacheri/Main.as rename to jetclient-as3/src/main/flex/io/nadron/Main.as index 26fc7dad..d045aef0 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/Main.as +++ b/jetclient-as3/src/main/flex/io/nadron/Main.as @@ -1,16 +1,16 @@ -package org.menacheri +package io.nadron { import flash.display.Sprite; import flash.events.Event; import flash.events.TimerEvent; import flash.utils.ByteArray; import flash.utils.Timer; - import org.menacheri.jetclient.app.impl.SessionFactory; - import org.menacheri.jetclient.app.Session; - import org.menacheri.jetclient.communication.MessageBuffer; - import org.menacheri.jetclient.event.Events; - import org.menacheri.jetclient.event.JetEvent; - import org.menacheri.jetclient.util.LoginHelper; + import io.nadron.app.impl.SessionFactory; + import io.nadron.app.Session; + import io.nadron.communication.MessageBuffer; + import io.nadron.event.Events; + import io.nadron.event.NadEvent; + import io.nadron.util.LoginHelper; /** * ... @@ -31,7 +31,7 @@ { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point - var loginHelper:LoginHelper = new LoginHelper("user", "pass", "Zombie_ROOM_1_REF_KEY_1", "localhost", 18090); + var loginHelper:LoginHelper = new LoginHelper("user", "pass", "Zombie_ROOM_1", "localhost", 18090); var sessionFactory:SessionFactory = new SessionFactory(loginHelper); for (var i:uint = 0; i < 50; i++) { @@ -43,8 +43,8 @@ private function traceData(event:Event):void { - var jetEvent:JetEvent = event as JetEvent; - var messageBuffer:MessageBuffer = jetEvent.getSource() as MessageBuffer; + var nEvent:NadEvent = event as NadEvent; + var messageBuffer:MessageBuffer = nEvent.getSource() as MessageBuffer; var buffer:ByteArray = messageBuffer.getBuffer(); trace("Remaining Human Population: " + buffer.readInt()); if (false == runOnce) @@ -75,8 +75,8 @@ bytes.writeInt(2); // operation = eat brains } var buffer:MessageBuffer = new MessageBuffer(bytes); - var jetEvent:JetEvent = Events.event(Events.NETWORK_MESSAGE, buffer); - session.sendToServer(jetEvent); + var nEvent:NadEvent = Events.event(Events.NETWORK_MESSAGE, buffer); + session.sendToServer(nEvent); } } diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/JetClient.as b/jetclient-as3/src/main/flex/io/nadron/NadClient.as similarity index 80% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/JetClient.as rename to jetclient-as3/src/main/flex/io/nadron/NadClient.as index 74d1753b..8b983bef 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/JetClient.as +++ b/jetclient-as3/src/main/flex/io/nadron/NadClient.as @@ -1,23 +1,23 @@ -package org.menacheri.jetclient +package io.nadron { /** - * Used to create a TCP socket connection to remote Jetserver. + * Used to create a TCP socket connection to remote Nadron server. * @author Abraham Menacherry */ - public class JetClient + public class NadClient { import flash.events.*; import flash.utils.ByteArray; import flash.utils.Dictionary; import flash.net.Socket; import flash.system.Security; - import org.menacheri.jetclient.codecs.Transform; - import org.menacheri.jetclient.event.JetEvent; + import io.nadron.codecs.Transform; + import io.nadron.event.NadEvent; private var remoteHost:String; private var remotePort:int; - public function JetClient(remoteHost:String, remotePort:int) + public function NadClient(remoteHost:String, remotePort:int) { this.remoteHost = remoteHost; this.remotePort = remotePort; @@ -26,7 +26,10 @@ package org.menacheri.jetclient public function connect(loginBytes:ByteArray):Socket { var socket:Socket = new Socket(remoteHost, remotePort); - socket.addEventListener(Event.CONNECT, socketConnect); + socket.addEventListener(Event.CONNECT, function(event:Event): void { + trace("Connected: " + event); + socket.writeBytes(loginBytes); + } ); socket.addEventListener(Event.CLOSE, socketClose); socket.addEventListener(IOErrorEvent.IO_ERROR, socketError); socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityError); @@ -35,7 +38,6 @@ package org.menacheri.jetclient try { trace("Trying to connect to " + remoteHost + ":" + remotePort + "\n"); socket.connect(remoteHost, remotePort); - socket.writeBytes(loginBytes); } catch (error:Error) { /* * Unable to connect to remote server, display error diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/app/Session.as b/jetclient-as3/src/main/flex/io/nadron/app/Session.as similarity index 78% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/app/Session.as rename to jetclient-as3/src/main/flex/io/nadron/app/Session.as index 64bd3b70..83453650 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/app/Session.as +++ b/jetclient-as3/src/main/flex/io/nadron/app/Session.as @@ -1,16 +1,16 @@ -package org.menacheri.jetclient.app +package io.nadron.app { import flash.events.EventDispatcher; import flash.events.IEventDispatcher; - import org.menacheri.jetclient.codecs.CodecChain; - import org.menacheri.jetclient.communication.MessageSender; - import org.menacheri.jetclient.event.JetEvent; + import io.nadron.codecs.CodecChain; + import io.nadron.communication.MessageSender; + import io.nadron.event.NadEvent; import flash.events.Event; - import org.menacheri.jetclient.codecs.InAndOutCodecChain; + import io.nadron.codecs.InAndOutCodecChain; /** * This interface abstracts a session in jetclient. A session can be thought of as a high - * level connection to a remote jetserver over TCP. The session also has event dispatching + * level connection to a remote nadron server over TCP. The session also has event dispatching * capabilities. So when an event comes into the session, it will get dispatched to the * appropriate event listener. * diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/app/impl/DefaultSession.as b/jetclient-as3/src/main/flex/io/nadron/app/impl/DefaultSession.as similarity index 86% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/app/impl/DefaultSession.as rename to jetclient-as3/src/main/flex/io/nadron/app/impl/DefaultSession.as index e440c9c5..ade0bded 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/app/impl/DefaultSession.as +++ b/jetclient-as3/src/main/flex/io/nadron/app/impl/DefaultSession.as @@ -1,12 +1,13 @@ -package org.menacheri.jetclient.app.impl +package io.nadron.app.impl { import flash.events.EventDispatcher; + import flash.events.ProgressEvent; import flash.utils.Dictionary; - import org.menacheri.jetclient.codecs.CodecChain; - import org.menacheri.jetclient.communication.MessageSender; - import org.menacheri.jetclient.app.Session; + import io.nadron.codecs.CodecChain; + import io.nadron.communication.MessageSender; + import io.nadron.app.Session; import flash.events.Event; - import org.menacheri.jetclient.protocol.Protocol; + import io.nadron.protocol.Protocol; /** * The default implementation of the session interface. This class is responsible @@ -52,6 +53,10 @@ package org.menacheri.jetclient.app.impl return; } dispatchEvent(data as Event); + // if there is anymore data in the socket, then force message received to be invoked again. + if (messageSender.getSocket().bytesAvailable > 0) { + messageSender.getSocket().dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA)); + } } public function sendToServer(message:Object):void diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/app/impl/SessionFactory.as b/jetclient-as3/src/main/flex/io/nadron/app/impl/SessionFactory.as similarity index 66% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/app/impl/SessionFactory.as rename to jetclient-as3/src/main/flex/io/nadron/app/impl/SessionFactory.as index f0d4eb7a..f1ef2ea4 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/app/impl/SessionFactory.as +++ b/jetclient-as3/src/main/flex/io/nadron/app/impl/SessionFactory.as @@ -1,24 +1,24 @@ -package org.menacheri.jetclient.app.impl +package io.nadron.app.impl { import flash.events.Event; import flash.events.ProgressEvent; import flash.net.Socket; import flash.utils.ByteArray; - import org.menacheri.jetclient.app.Session; - import org.menacheri.jetclient.codecs.impl.LoginInOutCodecs; - import org.menacheri.jetclient.codecs.InAndOutCodecChain; - import org.menacheri.jetclient.codecs.Transform; - import org.menacheri.jetclient.communication.MessageSender; - import org.menacheri.jetclient.handlers.LoginHandler; - import org.menacheri.jetclient.JetClient; - import org.menacheri.jetclient.protocol.impl.MessageBufferProtocol; - import org.menacheri.jetclient.protocol.Protocol; - import org.menacheri.jetclient.util.LoginHelper; + import io.nadron.app.Session; + import io.nadron.codecs.impl.LoginInOutCodecs; + import io.nadron.codecs.InAndOutCodecChain; + import io.nadron.codecs.Transform; + import io.nadron.communication.MessageSender; + import io.nadron.handlers.LoginHandler; + import io.nadron.NadClient; + import io.nadron.protocol.impl.MessageBufferProtocol; + import io.nadron.protocol.Protocol; + import io.nadron.util.LoginHelper; /** * Class used to create a session in jetclient. SessionFactory will also create - * the actual connection to the jetserver by initializing a socket connection using - * JetClient class. + * the actual connection to the nadron server by initializing a socket connection using + * NadClient class. * * @author Abraham Menacherry * @@ -27,7 +27,7 @@ package org.menacheri.jetclient.app.impl { /** * This class holds a number of variables like username, password etc which - * are necessary for creating connections to remote jetserver. + * are necessary for creating connections to remote nadron server. */ private var loginHelper:LoginHelper; private static var sessionId:uint = 0; @@ -38,7 +38,7 @@ package org.menacheri.jetclient.app.impl } /** - * Creates and connects a session to the remote jetserver. + * Creates and connects a session to the remote nadron server. * * @return The session instance created. * @@ -71,9 +71,9 @@ package org.menacheri.jetclient.app.impl protocol = new MessageBufferProtocol(); } protocol.applyProtocol(session); - var jetClient:JetClient = new JetClient(loginHelper.getRemoteHost(), loginHelper.getRemotePort()); + var nadClient:NadClient = new NadClient(loginHelper.getRemoteHost(), loginHelper.getRemotePort()); var loginBytes:ByteArray = loginCodecs.getOutCodecs().transform(loginHelper.getLoginEvent()) as ByteArray; - var socket:Socket = jetClient.connect(loginBytes); + var socket:Socket = nadClient.connect(loginBytes); var messageSender:MessageSender = protocol.createMessageSender(socket); session.setMessageSender(messageSender); var loginHandler:LoginHandler = new LoginHandler(session, loginCodecs); diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/CodecChain.as b/jetclient-as3/src/main/flex/io/nadron/codecs/CodecChain.as similarity index 90% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/CodecChain.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/CodecChain.as index 01338c7b..b908ac39 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/CodecChain.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/CodecChain.as @@ -1,4 +1,4 @@ -package org.menacheri.jetclient.codecs +package io.nadron.codecs { /** diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/InAndOutCodecChain.as b/jetclient-as3/src/main/flex/io/nadron/codecs/InAndOutCodecChain.as similarity index 88% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/InAndOutCodecChain.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/InAndOutCodecChain.as index 40ab9b5e..8d388525 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/InAndOutCodecChain.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/InAndOutCodecChain.as @@ -1,4 +1,4 @@ -package org.menacheri.jetclient.codecs +package io.nadron.codecs { /** diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/Transform.as b/jetclient-as3/src/main/flex/io/nadron/codecs/Transform.as similarity index 81% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/Transform.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/Transform.as index 5603b8f1..faabd841 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/Transform.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/Transform.as @@ -1,8 +1,8 @@ -package org.menacheri.jetclient.codecs +package io.nadron.codecs { /** - * An interface which is implemented by all codecs in jetclient. + * An interface which is implemented by all codecs in nadclient. * @author Abraham Menacherry */ public interface Transform diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/AMFDeserializer.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/AMFDeserializer.as similarity index 63% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/AMFDeserializer.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/AMFDeserializer.as index 17aae237..273bd680 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/AMFDeserializer.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/AMFDeserializer.as @@ -1,34 +1,34 @@ -package org.menacheri.jetclient.codecs.impl -{ - import flash.utils.ByteArray; - import org.menacheri.jetclient.codecs.Transform; - import org.menacheri.jetclient.event.Events; - - /** - * This decoder will convert an incoming ByteArray into a JetEvent. It will first read the opcode - * byte to see which kind of event is coming from remote jetserver, say SESSION_MESSAGE and it will - * read the payload into an object using byte array's readObject method. - * @author Abraham Menacherry - */ - public class AMFDeserializer implements Transform - { - - public function AMFDeserializer() - { - - } - - public function transform(input:Object):Object - { - var bytes:ByteArray = input as ByteArray; - var eventType:int = bytes.readByte(); - if (eventType == Events.NETWORK_MESSAGE) - { - eventType = Events.SESSION_MESSAGE; - } - return Events.event(eventType, bytes.readObject()); - } - - } - +package io.nadron.codecs.impl +{ + import flash.utils.ByteArray; + import io.nadron.codecs.Transform; + import io.nadron.event.Events; + + /** + * This decoder will convert an incoming ByteArray into a NadEvent. It will first read the opcode + * byte to see which kind of event is coming from remote nadron server, say SESSION_MESSAGE and it will + * read the payload into an object using byte array's readObject method. + * @author Abraham Menacherry + */ + public class AMFDeserializer implements Transform + { + + public function AMFDeserializer() + { + + } + + public function transform(input:Object):Object + { + var bytes:ByteArray = input as ByteArray; + var eventType:int = bytes.readByte(); + if (eventType == Events.NETWORK_MESSAGE) + { + eventType = Events.SESSION_MESSAGE; + } + return Events.event(eventType, bytes.readObject()); + } + + } + } \ No newline at end of file diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/AMFSerializer.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/AMFSerializer.as similarity index 58% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/AMFSerializer.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/AMFSerializer.as index aad3ad53..ff891b26 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/AMFSerializer.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/AMFSerializer.as @@ -1,12 +1,12 @@ -package org.menacheri.jetclient.codecs.impl +package io.nadron.codecs.impl { import flash.utils.ByteArray; - import org.menacheri.jetclient.codecs.Transform; - import org.menacheri.jetclient.event.JetEvent; + import io.nadron.codecs.Transform; + import io.nadron.event.NadEvent; /** - * Converts an incoming JetEvent into a ByteArray. It will read the event type from the - * JetEvent. Then it will serialize the payload an object to byte array. Both the event + * Converts an incoming NadEvent into a ByteArray. It will read the event type from the + * NadEvent. Then it will serialize the payload an object to byte array. Both the event * type and serialized bytes are written to a byte array and send to next encoder in the chain. * @author Abraham Menacherry */ @@ -23,10 +23,10 @@ if(input == null){ throw new Error("null isn't a legal serialization candidate"); } - var jetEvent:JetEvent = input as JetEvent; + var nEvent:NadEvent = input as NadEvent; var bytes:ByteArray = new ByteArray(); - bytes.writeByte(jetEvent.getType()); - bytes.writeObject(jetEvent.getSource()); + bytes.writeByte(nEvent.getType()); + bytes.writeObject(nEvent.getSource()); bytes.position = 0; return bytes; } diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/DefaultCodecChain.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/DefaultCodecChain.as similarity index 89% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/DefaultCodecChain.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/DefaultCodecChain.as index a4aa9477..96d31c61 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/DefaultCodecChain.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/DefaultCodecChain.as @@ -1,7 +1,7 @@ -package org.menacheri.jetclient.codecs.impl +package io.nadron.codecs.impl { - import org.menacheri.jetclient.codecs.CodecChain; - import org.menacheri.jetclient.codecs.Transform; + import io.nadron.codecs.CodecChain; + import io.nadron.codecs.Transform; /** * Default implementation of a codecchain which uses an array diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LengthFieldBasedFrameDecoder.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/LengthFieldBasedFrameDecoder.as similarity index 50% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LengthFieldBasedFrameDecoder.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/LengthFieldBasedFrameDecoder.as index 04eaae11..6f444236 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LengthFieldBasedFrameDecoder.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/LengthFieldBasedFrameDecoder.as @@ -1,13 +1,13 @@ -package org.menacheri.jetclient.codecs.impl +package io.nadron.codecs.impl { import flash.events.Event; import flash.net.Socket; import flash.utils.ByteArray; - import org.menacheri.jetclient.codecs.Transform; + import io.nadron.codecs.Transform; /** * A codec which can decode an incoming frame from remote jetserver based on the - * length of the incoming bytes. Jetserver sends data in the form of -. + * length of the incoming bytes. Nadron server sends data in the form of -. * This decoder will read the length of the payload, capture the payload and pass it on to * the next decoder in the chain as a ByteArray. If all the bytes are not available it will return null. * @author Abraham Menacherry @@ -17,12 +17,15 @@ package org.menacheri.jetclient.codecs.impl private var lengthFieldLength:int; private var lengthRead:Boolean; private var length:int; + private var message:ByteArray; + private var currentReadLength:int; public function LengthFieldBasedFrameDecoder(lengthFieldLength:int = 2) { lengthRead = false; length = 0; this.lengthFieldLength = lengthFieldLength; + message = new ByteArray(); } public function transform(input:Object):Object @@ -35,18 +38,34 @@ package org.menacheri.jetclient.codecs.impl { length = socket.readShort(); lengthRead = true; + message.clear(); + currentReadLength = 0; } - if (socket.bytesAvailable >= length) + var bytesAvailable:uint = socket.bytesAvailable; + if(bytesAvailable > 0) { - // reset the frame flags. So that next frame can be read. - lengthRead = false; - length = 0; - var message:ByteArray = new ByteArray(); - socket.readBytes(message, 0, length); - return message; - } - else + var lengthToRead:uint; + // if not enough bytes to complete the message then read it into message array are return null + if( (length - currentReadLength) > bytesAvailable) + { + lengthToRead = bytesAvailable; + socket.readBytes(message, currentReadLength, lengthToRead); + currentReadLength += lengthToRead; + return null; + } + else//(length - currentReadLength) <= bytesAvailable + { + // enough or more bytes are available return message + lengthToRead = (length - currentReadLength); + socket.readBytes(message, currentReadLength, lengthToRead); + lengthRead = false; + length = 0; + currentReadLength = 0; + return message; + } + } + else { return null; } diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LengthFieldPrepender.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/LengthFieldPrepender.as similarity index 79% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LengthFieldPrepender.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/LengthFieldPrepender.as index 2edd47c4..1d29cf31 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LengthFieldPrepender.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/LengthFieldPrepender.as @@ -1,10 +1,10 @@ -package org.menacheri.jetclient.codecs.impl +package io.nadron.codecs.impl { import flash.utils.ByteArray; - import org.menacheri.jetclient.codecs.Transform; + import io.nadron.codecs.Transform; /** - * Whenever a message is sent to remote jetserver the length of the number of bytes + * Whenever a message is sent to remote nadron server the length of the number of bytes * needs to be prepended to the message. This encoder will do that. It will accept a * byte array, find its length, create another byte array of the form * and return it. Normally this is the last encoder before a message is written to a socket. diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LoginInOutCodecs.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/LoginInOutCodecs.as similarity index 83% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LoginInOutCodecs.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/LoginInOutCodecs.as index 242ee395..74a11aaf 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/LoginInOutCodecs.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/LoginInOutCodecs.as @@ -1,8 +1,8 @@ -package org.menacheri.jetclient.codecs.impl +package io.nadron.codecs.impl { - import org.menacheri.jetclient.codecs.CodecChain; - import org.menacheri.jetclient.codecs.impl.DefaultCodecChain; - import org.menacheri.jetclient.codecs.InAndOutCodecChain; + import io.nadron.codecs.CodecChain; + import io.nadron.codecs.impl.DefaultCodecChain; + import io.nadron.codecs.InAndOutCodecChain; /** * The logging in process requires both writing to remote jetserver as well as reading from it. diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/MessagBufferEventDecoder.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/MessagBufferEventDecoder.as similarity index 57% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/MessagBufferEventDecoder.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/MessagBufferEventDecoder.as index b09a564c..ef51bd15 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/MessagBufferEventDecoder.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/MessagBufferEventDecoder.as @@ -1,14 +1,14 @@ -package org.menacheri.jetclient.codecs.impl +package io.nadron.codecs.impl { import flash.utils.ByteArray; - import org.menacheri.jetclient.codecs.Transform; - import org.menacheri.jetclient.event.Events; - import org.menacheri.jetclient.event.JetEvent; - import org.menacheri.jetclient.communication.MessageBuffer; + import io.nadron.codecs.Transform; + import io.nadron.event.Events; + import io.nadron.event.NadEvent; + import io.nadron.communication.MessageBuffer; /** - * This decoder will convert an incoming ByteArray into a JetEvent. It will first read the opcode - * byte to see which kind of event is coming from remote jetserver, say SESSION_MESSAGE and it will + * This decoder will convert an incoming ByteArray into a NadEvent. It will first read the opcode + * byte to see which kind of event is coming from remote nadron server, say SESSION_MESSAGE and it will * read the payload. The opcode will be used to create appropriate event type and the payload will * be written to a MessageBuffer. * @author Abraham Menacherry @@ -21,7 +21,7 @@ package org.menacheri.jetclient.codecs.impl } - /* INTERFACE org.menacheri.jetclient.codecs.Transform */ + /* INTERFACE io.nadron.codecs.Transform */ public function transform(input:Object):Object { @@ -33,7 +33,7 @@ package org.menacheri.jetclient.codecs.impl eventType = Events.SESSION_MESSAGE; } var buffer:MessageBuffer = new MessageBuffer(message); - var event:JetEvent = Events.event(eventType, buffer); + var event:NadEvent = Events.event(eventType, buffer); return event; } diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/MessageBufferEventEncoder.as b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/MessageBufferEventEncoder.as similarity index 65% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/MessageBufferEventEncoder.as rename to jetclient-as3/src/main/flex/io/nadron/codecs/impl/MessageBufferEventEncoder.as index ce02c4e5..17f58cce 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/codecs/impl/MessageBufferEventEncoder.as +++ b/jetclient-as3/src/main/flex/io/nadron/codecs/impl/MessageBufferEventEncoder.as @@ -1,17 +1,17 @@ -package org.menacheri.jetclient.codecs.impl +package io.nadron.codecs.impl { import flash.utils.ByteArray; - import org.menacheri.jetclient.codecs.Transform; - import org.menacheri.jetclient.communication.MessageBuffer; - import org.menacheri.jetclient.event.JetEvent; + import io.nadron.codecs.Transform; + import io.nadron.communication.MessageBuffer; + import io.nadron.event.NadEvent; /** - * Converts an incoming JetEvent into a ByteArray. It will read the event type and + * Converts an incoming NadEvent into a ByteArray. It will read the event type and * the source of the event and write them to a ByteArray. * @author Abraham Menacherry */ public class MessageBufferEventEncoder implements Transform { - import org.menacheri.jetclient.event.Events; + import io.nadron.event.Events; public function MessageBufferEventEncoder() { @@ -20,7 +20,7 @@ package org.menacheri.jetclient.codecs.impl public function transform(input:Object):Object { - var event:JetEvent = input as JetEvent; + var event:NadEvent = input as NadEvent; var message:ByteArray = new ByteArray(); var opCode:int = event.getType(); message.writeByte(opCode); diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/DefaultMessageSender.as b/jetclient-as3/src/main/flex/io/nadron/communication/DefaultMessageSender.as similarity index 75% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/DefaultMessageSender.as rename to jetclient-as3/src/main/flex/io/nadron/communication/DefaultMessageSender.as index 9f0e3670..9cb41574 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/DefaultMessageSender.as +++ b/jetclient-as3/src/main/flex/io/nadron/communication/DefaultMessageSender.as @@ -1,11 +1,11 @@ -package org.menacheri.jetclient.communication +package io.nadron.communication { import flash.net.Socket; import flash.utils.ByteArray; - import org.menacheri.jetclient.app.Session; - import org.menacheri.jetclient.codecs.Transform; + import io.nadron.app.Session; + import io.nadron.codecs.Transform; /** - * A class used by the session to send messages to the remote JetServer. It contains methods for writing + * A class used by the session to send messages to the remote Nadron Server. It contains methods for writing * messages as well as closing socket. It also has responsibility to tranform incoming object to bytes using * codec chain before writing to socket. * @author Abraham Menacherry @@ -31,6 +31,11 @@ package org.menacheri.jetclient.communication socket.flush(); } + public function getSocket():Socket + { + return socket; + } + public function close():void { if (null != socket) diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/MessageBuffer.as b/jetclient-as3/src/main/flex/io/nadron/communication/MessageBuffer.as similarity index 95% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/MessageBuffer.as rename to jetclient-as3/src/main/flex/io/nadron/communication/MessageBuffer.as index 93da5e9c..c1b37f5a 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/MessageBuffer.as +++ b/jetclient-as3/src/main/flex/io/nadron/communication/MessageBuffer.as @@ -1,4 +1,4 @@ -package org.menacheri.jetclient.communication +package io.nadron.communication { import flash.utils.ByteArray; @@ -31,7 +31,7 @@ package org.menacheri.jetclient.communication } /** - * Each string is written as to the array since JetServer protocol expects it in this way + * Each string is written as to the array since Nadron Server protocol expects it in this way * @param theString */ public function writeString(theString:String):void { diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/MessageSender.as b/jetclient-as3/src/main/flex/io/nadron/communication/MessageSender.as similarity index 64% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/MessageSender.as rename to jetclient-as3/src/main/flex/io/nadron/communication/MessageSender.as index 05feb077..256eea9d 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/communication/MessageSender.as +++ b/jetclient-as3/src/main/flex/io/nadron/communication/MessageSender.as @@ -1,5 +1,6 @@ -package org.menacheri.jetclient.communication +package io.nadron.communication { + import flash.net.Socket; /** * ... @@ -9,6 +10,7 @@ package org.menacheri.jetclient.communication { function sendMessage(message:Object):void; function close():void; + function getSocket():Socket; } } \ No newline at end of file diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/event/Events.as b/jetclient-as3/src/main/flex/io/nadron/event/Events.as similarity index 92% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/event/Events.as rename to jetclient-as3/src/main/flex/io/nadron/event/Events.as index c7cb566e..22e0ff93 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/event/Events.as +++ b/jetclient-as3/src/main/flex/io/nadron/event/Events.as @@ -1,7 +1,7 @@ -package org.menacheri.jetclient.event +package io.nadron.event { import flash.utils.Dictionary; - import org.menacheri.jetclient.event.impl.DefaultEvent; + import io.nadron.event.impl.DefaultEvent; /** * Integer versions of events are used to accept incoming events from remote jetserver and * to write back events to it. String versions are used for internal event dispatch from the session. @@ -123,20 +123,20 @@ package org.menacheri.jetclient.event } /** - * Creates a JetEvent instance using the integer event type and the source. + * Creates a NadEvent instance using the integer event type and the source. * @param eventType * @param source * @return */ - public static function event(eventType:int,source:Object):JetEvent + public static function event(eventType:int,source:Object):NadEvent { var dispatchEventType:String = convertEventTypeToString(eventType); - var jetEvent:DefaultEvent = new DefaultEvent(dispatchEventType); + var nEvent:DefaultEvent = new DefaultEvent(dispatchEventType); var date:Date = new Date(); - jetEvent.setSource(source); - jetEvent.setType(eventType); - jetEvent.setTimestamp(date.valueOf()); - return jetEvent; + nEvent.setSource(source); + nEvent.setType(eventType); + nEvent.setTimestamp(date.valueOf()); + return nEvent; } } diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/event/JetEvent.as b/jetclient-as3/src/main/flex/io/nadron/event/NadEvent.as similarity index 80% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/event/JetEvent.as rename to jetclient-as3/src/main/flex/io/nadron/event/NadEvent.as index 1d6e7e32..2fc4526f 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/event/JetEvent.as +++ b/jetclient-as3/src/main/flex/io/nadron/event/NadEvent.as @@ -1,11 +1,11 @@ -package org.menacheri.jetclient.event +package io.nadron.event { /** * ... * @author Abraham Menacherry */ - public interface JetEvent + public interface NadEvent { function getType():int function setType(type:int):void diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/event/impl/DefaultEvent.as b/jetclient-as3/src/main/flex/io/nadron/event/impl/DefaultEvent.as similarity index 73% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/event/impl/DefaultEvent.as rename to jetclient-as3/src/main/flex/io/nadron/event/impl/DefaultEvent.as index f2bb9442..34260ef0 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/event/impl/DefaultEvent.as +++ b/jetclient-as3/src/main/flex/io/nadron/event/impl/DefaultEvent.as @@ -1,15 +1,15 @@ -package org.menacheri.jetclient.event.impl +package io.nadron.event.impl { import flash.events.Event; - import org.menacheri.jetclient.event.JetEvent; + import io.nadron.event.NadEvent; /** * ... * @author Abraham Menacherry */ - public class DefaultEvent extends Event implements JetEvent + public class DefaultEvent extends Event implements NadEvent { - private var jetEventType:int; + private var nEventType:int; private var source:Object; private var timestamp:Number; @@ -20,12 +20,12 @@ package org.menacheri.jetclient.event.impl public function getType():int { - return jetEventType; + return nEventType; } public function setType(type:int):void { - this.jetEventType = type; + this.nEventType = type; } public function getSource():Object diff --git a/jetclient-as3/src/main/flex/io/nadron/handlers/LoginHandler.as b/jetclient-as3/src/main/flex/io/nadron/handlers/LoginHandler.as new file mode 100644 index 00000000..e78c9593 --- /dev/null +++ b/jetclient-as3/src/main/flex/io/nadron/handlers/LoginHandler.as @@ -0,0 +1,75 @@ +package io.nadron.handlers +{ + import flash.events.Event; + import flash.events.ProgressEvent; + import flash.net.Socket; + import io.nadron.app.impl.DefaultSession; + import io.nadron.app.Session; + import io.nadron.codecs.CodecChain; + import io.nadron.codecs.InAndOutCodecChain; + import io.nadron.codecs.Transform; + import io.nadron.event.Events; + import io.nadron.event.NadEvent; + + /** + * Used for logging in to the remote Nadron server. It will basically wait till the START event is sent + * by remote Nadron Server and then set the messageReceived function on the session and the event + * listener for future socket communication. + * @author Abraham Menacherry + */ + public class LoginHandler + { + private var session:Session; + private var loginCodecs:InAndOutCodecChain; + + public function LoginHandler(session:Session, loginCodecs:InAndOutCodecChain) + { + this.session = session; + this.loginCodecs = loginCodecs; + } + + public function handleLogin(event:Event):void + { + var nEvent:NadEvent = loginCodecs.getInCodecs().transform(event) as NadEvent; + if (null == nEvent) { + // Decoding is not over, mostly because the whole frame + // was not received by the LengthFieldBasedFrameDecoder. + return; + } + var socket:Socket = event.currentTarget as Socket; + if(nEvent.getType() == Events.LOG_IN_SUCCESS || nEvent.getType() == Events.GAME_ROOM_JOIN_SUCCESS) + { + trace("Log in success/Game room join success Event received: " + nEvent.getType()); + + if (socket.bytesAvailable > 0) + { + //force the socket to read GAME_ROOM_JOIN_SUCCESS + socket.dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA)); + } + } + else if (nEvent.getType() == Events.START) { + trace("Start Event received"); + + socket.removeEventListener(ProgressEvent.SOCKET_DATA, this.handleLogin); + socket.addEventListener(ProgressEvent.SOCKET_DATA, session.messageReceived); + if (socket.bytesAvailable > 0) + { + //check if socket received message from the server and force it to read the message + socket.dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA)); + } + } + } + + public function getLoginCodecs():InAndOutCodecChain + { + return loginCodecs; + } + + public function setLoginCodecs(loginCodecs:InAndOutCodecChain):void + { + this.loginCodecs = loginCodecs; + } + + } + +} \ No newline at end of file diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/Protocol.as b/jetclient-as3/src/main/flex/io/nadron/protocol/Protocol.as similarity index 57% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/Protocol.as rename to jetclient-as3/src/main/flex/io/nadron/protocol/Protocol.as index 9776fdd9..9589833a 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/Protocol.as +++ b/jetclient-as3/src/main/flex/io/nadron/protocol/Protocol.as @@ -1,11 +1,11 @@ -package org.menacheri.jetclient.protocol +package io.nadron.protocol { import flash.net.Socket; - import org.menacheri.jetclient.app.Session; - import org.menacheri.jetclient.communication.MessageSender; + import io.nadron.app.Session; + import io.nadron.communication.MessageSender; /** - * A network protocol that is used to connect to remote jetserver. Implementaions will use + * A network protocol that is used to connect to remote nadron server. Implementaions will use * appropriate encoders and decoders based on the protocol implemented by server. * @author Abraham Menacherry */ diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/impl/AMF3Protocol.as b/jetclient-as3/src/main/flex/io/nadron/protocol/impl/AMF3Protocol.as similarity index 62% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/impl/AMF3Protocol.as rename to jetclient-as3/src/main/flex/io/nadron/protocol/impl/AMF3Protocol.as index 7f37d0a9..372b17a4 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/impl/AMF3Protocol.as +++ b/jetclient-as3/src/main/flex/io/nadron/protocol/impl/AMF3Protocol.as @@ -1,20 +1,20 @@ -package org.menacheri.jetclient.protocol.impl +package io.nadron.protocol.impl { import flash.net.Socket; - import org.menacheri.jetclient.app.Session; - import org.menacheri.jetclient.codecs.CodecChain; - import org.menacheri.jetclient.codecs.impl.AMFDeserializer; - import org.menacheri.jetclient.codecs.impl.AMFSerializer; - import org.menacheri.jetclient.codecs.impl.DefaultCodecChain; - import org.menacheri.jetclient.codecs.impl.LengthFieldBasedFrameDecoder; - import org.menacheri.jetclient.codecs.impl.LengthFieldPrepender; - import org.menacheri.jetclient.communication.DefaultMessageSender; - import org.menacheri.jetclient.communication.MessageSender; - import org.menacheri.jetclient.protocol.Protocol; + import io.nadron.app.Session; + import io.nadron.codecs.CodecChain; + import io.nadron.codecs.impl.AMFDeserializer; + import io.nadron.codecs.impl.AMFSerializer; + import io.nadron.codecs.impl.DefaultCodecChain; + import io.nadron.codecs.impl.LengthFieldBasedFrameDecoder; + import io.nadron.codecs.impl.LengthFieldPrepender; + import io.nadron.communication.DefaultMessageSender; + import io.nadron.communication.MessageSender; + import io.nadron.protocol.Protocol; /** * This protocol has encoders and decoders which do AMF3 (de)serialization while - * transmitting and receiving messages to remote jetserver. + * transmitting and receiving messages to remote Nadron server. * @author Abraham Menacherry */ public class AMF3Protocol implements Protocol diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/impl/MessageBufferProtocol.as b/jetclient-as3/src/main/flex/io/nadron/protocol/impl/MessageBufferProtocol.as similarity index 66% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/impl/MessageBufferProtocol.as rename to jetclient-as3/src/main/flex/io/nadron/protocol/impl/MessageBufferProtocol.as index b9c669e8..cf624509 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/protocol/impl/MessageBufferProtocol.as +++ b/jetclient-as3/src/main/flex/io/nadron/protocol/impl/MessageBufferProtocol.as @@ -1,16 +1,16 @@ -package org.menacheri.jetclient.protocol.impl +package io.nadron.protocol.impl { import flash.net.Socket; - import org.menacheri.jetclient.app.Session; - import org.menacheri.jetclient.codecs.CodecChain; - import org.menacheri.jetclient.codecs.impl.DefaultCodecChain; - import org.menacheri.jetclient.codecs.impl.LengthFieldBasedFrameDecoder; - import org.menacheri.jetclient.codecs.impl.LengthFieldPrepender; - import org.menacheri.jetclient.codecs.impl.MessagBufferEventDecoder; - import org.menacheri.jetclient.codecs.impl.MessageBufferEventEncoder; - import org.menacheri.jetclient.communication.DefaultMessageSender; - import org.menacheri.jetclient.communication.MessageSender; - import org.menacheri.jetclient.protocol.Protocol; + import io.nadron.app.Session; + import io.nadron.codecs.CodecChain; + import io.nadron.codecs.impl.DefaultCodecChain; + import io.nadron.codecs.impl.LengthFieldBasedFrameDecoder; + import io.nadron.codecs.impl.LengthFieldPrepender; + import io.nadron.codecs.impl.MessagBufferEventDecoder; + import io.nadron.codecs.impl.MessageBufferEventEncoder; + import io.nadron.communication.DefaultMessageSender; + import io.nadron.communication.MessageSender; + import io.nadron.protocol.Protocol; /** * A default protocol which is of the form . * @author Abraham Menacherry diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/util/LoginHelper.as b/jetclient-as3/src/main/flex/io/nadron/util/LoginHelper.as similarity index 79% rename from jetclient-as3/src/main/flex/org/menacheri/jetclient/util/LoginHelper.as rename to jetclient-as3/src/main/flex/io/nadron/util/LoginHelper.as index d41fa9ca..646e25d0 100644 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/util/LoginHelper.as +++ b/jetclient-as3/src/main/flex/io/nadron/util/LoginHelper.as @@ -1,8 +1,8 @@ -package org.menacheri.jetclient.util +package io.nadron.util { - import org.menacheri.jetclient.communication.MessageBuffer; - import org.menacheri.jetclient.event.JetEvent; - import org.menacheri.jetclient.event.Events; + import io.nadron.communication.MessageBuffer; + import io.nadron.event.NadEvent; + import io.nadron.event.Events; import flash.utils.ByteArray; /** @@ -27,7 +27,7 @@ package org.menacheri.jetclient.util this.remotePort = remotePort; } - public function getLoginEvent():JetEvent + public function getLoginEvent():NadEvent { var loginBuffer:MessageBuffer = new MessageBuffer(new ByteArray()); loginBuffer.writeMultiStrings(username, password, connectionKey); diff --git a/jetclient-as3/src/main/flex/org/menacheri/jetclient/handlers/LoginHandler.as b/jetclient-as3/src/main/flex/org/menacheri/jetclient/handlers/LoginHandler.as deleted file mode 100644 index 3d2ff452..00000000 --- a/jetclient-as3/src/main/flex/org/menacheri/jetclient/handlers/LoginHandler.as +++ /dev/null @@ -1,59 +0,0 @@ -package org.menacheri.jetclient.handlers -{ - import flash.events.Event; - import flash.events.ProgressEvent; - import flash.net.Socket; - import org.menacheri.jetclient.app.impl.DefaultSession; - import org.menacheri.jetclient.app.Session; - import org.menacheri.jetclient.codecs.CodecChain; - import org.menacheri.jetclient.codecs.InAndOutCodecChain; - import org.menacheri.jetclient.codecs.Transform; - import org.menacheri.jetclient.event.Events; - import org.menacheri.jetclient.event.JetEvent; - - /** - * Used for logging in to the remote jetserver. It will basically wait till the START event is sent - * by remote JetServer and then set the messageReceived function on the session and the event - * listener for future socket communication. - * @author Abraham Menacherry - */ - public class LoginHandler - { - private var session:Session; - private var loginCodecs:InAndOutCodecChain; - - public function LoginHandler(session:Session, loginCodecs:InAndOutCodecChain) - { - this.session = session; - this.loginCodecs = loginCodecs; - } - - public function handleLogin(event:Event):void - { - var jetEvent:JetEvent = loginCodecs.getInCodecs().transform(event) as JetEvent; - if (null == jetEvent) { - // Decoding is not over, mostly because the whole frame - // was not received by the LengthFieldBasedFrameDecoder. - return; - } - if (jetEvent.getType() == Events.START) { - trace("Start Event received"); - var socket:Socket = event.currentTarget as Socket; - socket.removeEventListener(ProgressEvent.SOCKET_DATA, this.handleLogin); - socket.addEventListener(ProgressEvent.SOCKET_DATA, session.messageReceived); - } - } - - public function getLoginCodecs():InAndOutCodecChain - { - return loginCodecs; - } - - public function setLoginCodecs(loginCodecs:InAndOutCodecChain):void - { - this.loginCodecs = loginCodecs; - } - - } - -} \ No newline at end of file diff --git a/jetclient/.project b/jetclient/.project deleted file mode 100644 index ee9b7e4f..00000000 --- a/jetclient/.project +++ /dev/null @@ -1,13 +0,0 @@ - - jetclient - This is a client library for jetserver https://github.com/menacher/java-game-server/tree/master/jetserver. Java clients can use this program to connect and interact with jetserver. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. - - - - org.eclipse.jdt.core.javabuilder - - - - org.eclipse.jdt.core.javanature - - \ No newline at end of file diff --git a/jetclient/README.md b/jetclient/README.md deleted file mode 100644 index 1c9a2da8..00000000 --- a/jetclient/README.md +++ /dev/null @@ -1,25 +0,0 @@ -This is a client project for [jetserver](https://github.com/menacher/java-game-server/tree/master/jetserver) library. An example main class is provided in src/main/test folder. - -About the Client -================ -Execute org.menacheri.TestClass from command line or eclipse and it will connect to remote jetserver and start receiving events. Assumption is that TestClass using accurate hostname and port number. -Execution ---------- -Pointers on main classes, classpaths and command line flags. - -**To start the client ** -jetclient can be executed from console using below command. -java -cp ./jetclient-0.1.jar;./netty-3.3.1.Final.jar org.menacheri.TestClass - -Usage as game client -==================== -The general usage steps could be as outlined below. -1. Add jetclient-0.1.jar and netty-3.3.1.Final.jar to your project class path. -2. Create LoginBuilder, session and SessionEventHandler as shown in TestClass. example-games project has a ZombieJetClient which shows a better example. -3. Use the SessionEventHandler to accept events from remote server as well as to write back events to the server. -4. To write back to the remote jetserver create a tcp/udp network event using the factory method Event event = Events.networkEvent(messageBuffer); or Events.networkEvent(messageBuffer,DeliveryGuaranty.Fast); -5. Now call session.onEvent(event); and this event will be transmitted to the remote jetserver. - -Jar Dependencies ----------------- -netty-3.3.1.Final.jar \ No newline at end of file diff --git a/jetclient/binaries/jetclient-0.1-javadoc.jar b/jetclient/binaries/jetclient-0.1-javadoc.jar deleted file mode 100644 index a37d9ff5..00000000 Binary files a/jetclient/binaries/jetclient-0.1-javadoc.jar and /dev/null differ diff --git a/jetclient/binaries/jetclient-0.1-sources.jar b/jetclient/binaries/jetclient-0.1-sources.jar deleted file mode 100644 index f0426d4e..00000000 Binary files a/jetclient/binaries/jetclient-0.1-sources.jar and /dev/null differ diff --git a/jetclient/binaries/jetclient-0.1.jar b/jetclient/binaries/jetclient-0.1.jar deleted file mode 100644 index 85f89f68..00000000 Binary files a/jetclient/binaries/jetclient-0.1.jar and /dev/null differ diff --git a/jetclient/pom.xml b/jetclient/pom.xml deleted file mode 100644 index 3518f9db..00000000 --- a/jetclient/pom.xml +++ /dev/null @@ -1,109 +0,0 @@ - - 4.0.0 - org.menacheri - jetclient - jar - 0.1 - jetclient - https://github.com/menacher/java-game-server/tree/master/jetclient - This is a client library for jetserver https://github.com/menacher/java-game-server/tree/master/jetserver. Java clients can use this program to connect and interact with jetserver. - - - org.sonatype.oss - oss-parent - 7 - - - - - GNU Lesser General Public License (LGPL), Version 2.1 - http://www.gnu.org/licenses/lgpl-2.1.txt - repo - - - - - scm:git:git@github.com:menacher/java-game-server.git - scm:git:git@github.com:menacher/java-game-server.git - git@github.com:menacher/java-game-server.git - - - - - menacher - Abraham Menacherry - abrahammenacherry@gmail.com - - - - - UTF-8 - - - - - junit - junit - 4.8.2 - test - - - io.netty - netty - 3.6.2.Final - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.1.2 - - - attach-sources - verify - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.8.1 - - - attach-javadoc - verify - - jar - - - - - private - true - - - - - - org.apache.maven.plugins - maven-eclipse-plugin - 2.8 - - - true - true - - - - - - diff --git a/jetclient/src/main/java/org/menacheri/jetclient/communication/NettyMessageBuffer.java b/jetclient/src/main/java/org/menacheri/jetclient/communication/NettyMessageBuffer.java deleted file mode 100644 index c30e99a2..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/communication/NettyMessageBuffer.java +++ /dev/null @@ -1,298 +0,0 @@ -package org.menacheri.jetclient.communication; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.buffer.DynamicChannelBuffer; -import org.jboss.netty.handler.codec.serialization.ObjectEncoder; -import org.menacheri.convert.Transform; -import org.menacheri.jetclient.util.NettyUtils; - -/** - * This class is an implementation of the {@link MessageBuffer} interface. It - * is a thin wrapper over the the Netty {@link ChannelBuffer} with some - * additional methods for string and object read write. It does not expose all - * methods of the ChannelBuffer, instead it has a method - * {@link #getNativeBuffer()} which can be used to retrieve the buffer and then - * call the appropriate method. For writing to the buffer, this class uses - * {@link DynamicChannelBuffer} implementation. - * - * @author Abraham Menacherry - * - */ -public class NettyMessageBuffer implements MessageBuffer -{ - private final ChannelBuffer buffer; - - public NettyMessageBuffer() - { - buffer = ChannelBuffers.dynamicBuffer(); - } - - /** - * This constructor can be used when trying to read information from a - * {@link ChannelBuffer}. - * - * @param buffer - */ - public NettyMessageBuffer(ChannelBuffer buffer) - { - this.buffer = buffer; - } - - @Override - public boolean isReadable() - { - return buffer.readable(); - } - - @Override - public int readableBytes() - { - return buffer.readableBytes(); - } - - @Override - public byte[] array() - { - return buffer.array(); - } - - @Override - public void clear() - { - buffer.clear(); - } - - @Override - public ChannelBuffer getNativeBuffer() - { - return buffer; - } - - @Override - public int readByte() - { - return buffer.readByte(); - } - - @Override - public int readUnsignedByte() - { - return buffer.readUnsignedByte(); - } - - @Override - public byte[] readBytes(int length) - { - byte[] bytes = new byte[length]; - buffer.readBytes(bytes); - return bytes; - } - - @Override - public void readBytes(byte[] dst) - { - buffer.readBytes(dst); - } - - @Override - public void readBytes(byte[] dst, int dstIndex, int length) - { - buffer.readBytes(dst, dstIndex, length); - } - - @Override - public char readChar() - { - return buffer.readChar(); - } - - @Override - public int readUnsignedShort() - { - return buffer.readUnsignedShort(); - } - - @Override - public int readShort() - { - return buffer.readShort(); - } - - @Override - public int readUnsignedMedium() - { - return buffer.readUnsignedMedium(); - } - - @Override - public int readMedium() - { - return buffer.readMedium(); - } - - @Override - public long readUnsignedInt() - { - return buffer.readUnsignedInt(); - } - - @Override - public int readInt() - { - return buffer.readInt(); - } - - @Override - public long readLong() - { - return buffer.readLong(); - } - - @Override - public float readFloat() - { - return buffer.readFloat(); - } - - @Override - public double readDouble() - { - return buffer.readChar(); - } - - @Override - public String readString() - { - return NettyUtils.readString(buffer); - } - - @Override - public String[] readStrings(int numOfStrings) - { - return NettyUtils.readStrings(buffer, numOfStrings); - } - - /** - * Used to read an object from the buffer. Note that the encoder used to - * write the object in the first place must be Netty {@link ObjectEncoder}. - * To read objects written in using other encoders like say AMF3, use the - * {@link #readObject(Transform)} method instead. - * - * @return The object that is read from the underlying {@link ChannelBuffer} - */ - public Object readObject() - { - return NettyUtils.readObject(buffer); - } - - /** - * Used to read a specified number of objects from the buffer. Note that the - * encoder used to write the object in the first place must be Netty - * {@link ObjectEncoder}. To read objects written in using other encoders - * like say AMF3, use the {@link #readObject(Transform)} method instead. - * - * @param numOfObjects - * The number of objects to be read from the underlying - * {@link ChannelBuffer} - * @return The object that is read from the underlying {@link ChannelBuffer} - */ - public Object[] readObjects(int numOfObjects) - { - return NettyUtils.readObjects(buffer, numOfObjects); - } - - public V readObject(Transform converter) - { - return NettyUtils.readObject(buffer, converter); - } - - @Override - public MessageBuffer writeByte(byte b) - { - buffer.writeByte(b); - return this; - } - - @Override - public MessageBuffer writeBytes(byte[] src) - { - buffer.writeBytes(src); - return this; - } - - @Override - public MessageBuffer writeChar(int value) - { - buffer.writeChar(value); - return this; - } - - @Override - public MessageBuffer writeShort(int value) - { - buffer.writeShort(value); - return this; - } - - @Override - public MessageBuffer writeMedium(int value) - { - buffer.writeMedium(value); - return this; - } - - @Override - public MessageBuffer writeInt(int value) - { - buffer.writeInt(value); - return this; - } - - @Override - public MessageBuffer writeLong(long value) - { - buffer.writeLong(value); - return this; - } - - @Override - public MessageBuffer writeFloat(float value) - { - buffer.writeFloat(value); - return this; - } - - @Override - public MessageBuffer writeDouble(double value) - { - buffer.writeDouble(value); - return this; - } - - @Override - public MessageBuffer writeString(String message) - { - ChannelBuffer strBuf = NettyUtils.writeString(message); - buffer.writeBytes(strBuf); - return this; - } - - @Override - public MessageBuffer writeStrings(String... messages) - { - ChannelBuffer strMultiBuf = NettyUtils.writeStrings(messages); - buffer.writeBytes(strMultiBuf); - return this; - } - - @Override - public MessageBuffer writeObject( - Transform converter, V object) - { - ChannelBuffer objBuf = NettyUtils.writeObject(converter, object); - buffer.writeBytes(objBuf); - return this; - } - -} diff --git a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/DefaultToClientHandler.java b/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/DefaultToClientHandler.java deleted file mode 100644 index 6886d599..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/DefaultToClientHandler.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.menacheri.jetclient.handlers.netty; - -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.menacheri.jetclient.NettyTCPClient; -import org.menacheri.jetclient.app.Session; -import org.menacheri.jetclient.event.Events; -import org.menacheri.jetclient.event.Event; - -/** - * A stateful handler whose job is to transmit messages coming on the Netty - * {@link ChannelPipeline} to the session. - * - * @author Abraham Menacherry. - * - */ -public class DefaultToClientHandler extends SimpleChannelUpstreamHandler -{ - static final String NAME = "defaultHandler"; - private final Session session; - - public DefaultToClientHandler(Session session) - { - this.session = session; - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) - throws Exception - { - Event event = (Event) e.getMessage(); - session.onEvent(event); - } - - @Override - public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) - throws Exception - { - NettyTCPClient.ALL_CHANNELS.add(e.getChannel()); - super.channelConnected(ctx, e); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception - { - System.err.println("Class:DefaultToClientHandler" - + " Exception occurred in tcp channel: " + e.getCause()); - Event event = Events.event(e, Events.EXCEPTION); - session.onEvent(event); - } - -// @Override -// public void channelDisconnected(ChannelHandlerContext ctx, -// ChannelStateEvent e) throws Exception -// { -// if (!session.isShuttingDown()) -// { -// Event event = Events.event(e, Events.DISCONNECT); -// session.onEvent(event); -// } -// else -// { -// System.err.println("Session is already shutting down. " -// + "Disconnect event will be discarded for channel {}" -// + e.getChannel().getId()); -// } -// -// } - -// @Override -// public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) -// throws Exception -// { -// if (!session.isShuttingDown()) -// { -// Event event = Events.event(e, Events.DISCONNECT); -// session.onEvent(event); -// } -// } - - public static String getName() - { - return NAME; - } -} diff --git a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/ExecutionHandlerSingleton.java b/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/ExecutionHandlerSingleton.java deleted file mode 100644 index 2571c228..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/ExecutionHandlerSingleton.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.menacheri.jetclient.handlers.netty; - -import org.jboss.netty.handler.execution.ExecutionHandler; -import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor; - -/** - * Creates an ExecutionHandler instance as a singleton. - * @author Abraham Menacherry - * - */ -public class ExecutionHandlerSingleton -{ - private static ExecutionHandler EXECUTION_HANDLER; - - public synchronized static ExecutionHandler getExecutionHandler() - { - if(null == EXECUTION_HANDLER){ - EXECUTION_HANDLER = new ExecutionHandler( new OrderedMemoryAwareThreadPoolExecutor(16, 1048576, 1048576)); - } - return EXECUTION_HANDLER; - } - -} diff --git a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/MessageBufferEventDecoder.java b/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/MessageBufferEventDecoder.java deleted file mode 100644 index 0b8447c2..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/MessageBufferEventDecoder.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.menacheri.jetclient.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.menacheri.jetclient.communication.NettyMessageBuffer; -import org.menacheri.jetclient.event.Events; - -/** - * This decoder will convert a Netty {@link ChannelBuffer} to a - * {@link NettyMessageBuffer}. It will also convert - * {@link Events#NETWORK_MESSAGE} events to {@link Events#SESSION_MESSAGE} - * event. - * - * @author Abraham Menacherry - * - */ -@Sharable -public class MessageBufferEventDecoder extends OneToOneDecoder -{ - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if (null == msg) - { - return msg; - } - ChannelBuffer buffer = (ChannelBuffer) msg; - byte opcode = buffer.readByte(); - if (opcode == Events.NETWORK_MESSAGE) - { - opcode = Events.SESSION_MESSAGE; - } - return Events.event(new NettyMessageBuffer(buffer), opcode); - } - -} diff --git a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/MessageBufferEventEncoder.java b/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/MessageBufferEventEncoder.java deleted file mode 100644 index 80df42fa..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/MessageBufferEventEncoder.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.menacheri.jetclient.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.menacheri.jetclient.communication.MessageBuffer; -import org.menacheri.jetclient.event.Event; -import org.menacheri.jetclient.event.Events; - -/** - * Converts an incoming {@link Event} which in turn has a - * IMessageBuffer payload to a Netty {@link ChannelBuffer}. - * Note that {@link Event} instances containing other type of objects as its - * payload will result in {@link ClassCastException}. - * - * @author Abraham Menacherry. - * - */ -@Sharable -public class MessageBufferEventEncoder extends OneToOneEncoder -{ - - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if (null == msg) - { - return msg; - } - Event event = (Event) msg; - ChannelBuffer opcode = ChannelBuffers.buffer(1); - opcode.writeByte(event.getType()); - if (Events.LOG_IN == event.getType() || Events.RECONNECT == event.getType()) - { - // write protocol version also - ChannelBuffer protocolVersion = ChannelBuffers.buffer(1); - protocolVersion.writeByte(Events.PROTOCOL_VERSION); - opcode = ChannelBuffers.wrappedBuffer(opcode, protocolVersion); - } - - ChannelBuffer buffer = null; - if (null != event.getSource()) - { - @SuppressWarnings("unchecked") - MessageBuffer msgBuffer = (MessageBuffer) event - .getSource(); - ChannelBuffer data = msgBuffer.getNativeBuffer(); - buffer = ChannelBuffers.wrappedBuffer(opcode, data); - } - else - { - buffer = opcode; - } - return buffer; - } - -} diff --git a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/TCPPipelineFactory.java b/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/TCPPipelineFactory.java deleted file mode 100644 index 754248e9..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/TCPPipelineFactory.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.menacheri.jetclient.handlers.netty; - -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; -import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; -import org.menacheri.jetclient.app.Session; -import org.menacheri.jetclient.communication.MessageBuffer; -import org.menacheri.jetclient.event.Event; - -/** - * This pipeline factory can be considered the default 'protocol' for client - * side communication with jetserver. For other protocols, different - * {@link ChannelPipelineFactory}, with different encoders and decoders in its - * pipeline should be used to connect to remote jetserver. - * - * @author Abraham Menacherry. - * - */ -public class TCPPipelineFactory implements ChannelPipelineFactory -{ - /** - * Prepends the length of transmitted message before sending to remote - * jetserver. - */ - private static final LengthFieldPrepender LENGTH_FIELD_PREPENDER = new LengthFieldPrepender( - 2); - /** - * Decodes incoming messages from remote jetserver to {@link MessageBuffer} - * type, puts this as the payload for an {@link Event} and passes this - * {@link Event} instance to the next decoder/handler in the chain. - */ - private static final MessageBufferEventDecoder EVENT_DECODER = new MessageBufferEventDecoder(); - /** - * Decodes incoming messages from remote jetserver to {@link MessageBuffer} - * type, puts this as the payload for an {@link Event} and passes this - * {@link Event} instance to the next decoder/handler in the chain. - */ - private static final MessageBufferEventEncoder EVENT_ENCODER = new MessageBufferEventEncoder(); - /** - * Used to transmit the message to {@link Session}. - */ - private final DefaultToClientHandler defaultToClientHandler; - - public TCPPipelineFactory(Session session) - { - this.defaultToClientHandler = new DefaultToClientHandler(session); - } - - @Override - public ChannelPipeline getPipeline() throws Exception - { - ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("lengthDecoder", new LengthFieldBasedFrameDecoder( - Integer.MAX_VALUE, 0, 2, 0, 2)); - pipeline.addLast("eventDecoder", EVENT_DECODER); - pipeline.addLast(DefaultToClientHandler.getName(), - defaultToClientHandler); - - // Down stream handlers are added now. Note that the last one added to - // pipeline is actually the first encoder in the pipeline. - pipeline.addLast("lengthFieldPrepender", LENGTH_FIELD_PREPENDER); - pipeline.addLast("eventEncoder", EVENT_ENCODER); - - return pipeline; - } -} diff --git a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/UDPPipelineFactory.java b/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/UDPPipelineFactory.java deleted file mode 100644 index d49ef3fa..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/UDPPipelineFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.menacheri.jetclient.handlers.netty; - -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.Channels; - -public class UDPPipelineFactory implements ChannelPipelineFactory -{ - /** - * This pipeline will be shared across all the channels. In Netty UDP - * implementation it does not make sense to have different pipelines for - * different channels as the protocol is essentials "connection-less" for a - * bootstrap. - */ - private static final ChannelPipeline pipeline; - - private static final MessageBufferEventDecoder EVENT_DECODER; - private static final MessageBufferEventEncoder EVENT_ENCODER; - private static final UDPUpstreamHandler UDP_UPSTREAM_HANDLER; - - private static final UDPPipelineFactory INSTANCE; - static { - EVENT_DECODER = new MessageBufferEventDecoder(); - EVENT_ENCODER = new MessageBufferEventEncoder(); - UDP_UPSTREAM_HANDLER = new UDPUpstreamHandler(); - pipeline = init(); - INSTANCE = new UDPPipelineFactory(); - } - - static ChannelPipeline init() - { - ChannelPipeline pipeline = Channels.pipeline(); - pipeline.addLast("eventDecoder", EVENT_DECODER); - pipeline.addLast("eventEncoder", EVENT_ENCODER); - pipeline.addLast("UDPUpstreamHandler",UDP_UPSTREAM_HANDLER); - return pipeline; - } - - @Override - public ChannelPipeline getPipeline() throws Exception - { - return pipeline; - } - - public static UDPPipelineFactory getInstance() - { - return INSTANCE; - } -} diff --git a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/UDPUpstreamHandler.java b/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/UDPUpstreamHandler.java deleted file mode 100644 index 12691085..00000000 --- a/jetclient/src/main/java/org/menacheri/jetclient/handlers/netty/UDPUpstreamHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.menacheri.jetclient.handlers.netty; - -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.jboss.netty.channel.socket.DatagramChannel; -import org.menacheri.jetclient.NettyUDPClient; -import org.menacheri.jetclient.app.Session; -import org.menacheri.jetclient.event.Events; -import org.menacheri.jetclient.event.Event; - -/** - * This upstream handler handles ALL UDP events. It will lookup the - * appropriate session from {@link NettyUDPClient#CLIENTS} map and then transmit - * the event to that {@link Session}. Note If this class cannot find the - * appropriate session to transmit this event to, then the event is - * silently discarded. - * - * @author Abraham Menacherry. - * - */ -public class UDPUpstreamHandler extends SimpleChannelUpstreamHandler -{ - public UDPUpstreamHandler() - { - super(); - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) - throws Exception - { - // Lookup the session from the local address. - DatagramChannel datagramChannel = (DatagramChannel) e.getChannel(); - Session session = NettyUDPClient.CLIENTS.get(datagramChannel - .getLocalAddress()); - if (null != session) - { - Event event = (Event) e.getMessage(); - // Pass the event on to the session - session.onEvent(event); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception - { - System.err.println(e.getCause()); - DatagramChannel datagramChannel = (DatagramChannel) e.getChannel(); - Session session = NettyUDPClient.CLIENTS.get(datagramChannel - .getLocalAddress()); - if (null != session) - { - Event event = Events.event(e, Events.EXCEPTION); - session.onEvent(event); - } - } - - @Override - public void channelDisconnected(ChannelHandlerContext ctx, - ChannelStateEvent e) throws Exception - { - DatagramChannel datagramChannel = (DatagramChannel) e.getChannel(); - Session session = NettyUDPClient.CLIENTS.get(datagramChannel - .getLocalAddress()); - if ((null != session) && !session.isShuttingDown()) - { - Event event = Events.event(e, Events.DISCONNECT); - session.onEvent(event); - } - else if (null != session) - { - System.out.println("Session is already shutting down. " - + "Disconnect event will be discarded for channel {}" - + datagramChannel.getId()); - } - - } - - @Override - public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) - throws Exception - { - DatagramChannel datagramChannel = (DatagramChannel) e.getChannel(); - Session session = NettyUDPClient.CLIENTS.get(datagramChannel - .getLocalAddress()); - if ((null != session) && !session.isShuttingDown()) - { - Event event = Events.event(e, Events.DISCONNECT); - session.onEvent(event); - } - } - -} diff --git a/jetserver/.gitignore b/jetserver/.gitignore deleted file mode 100644 index 25544de1..00000000 --- a/jetserver/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/JetServer.log -/target diff --git a/jetserver/binaries/jetserver-0.1-javadoc.jar b/jetserver/binaries/jetserver-0.1-javadoc.jar deleted file mode 100644 index 6d33c328..00000000 Binary files a/jetserver/binaries/jetserver-0.1-javadoc.jar and /dev/null differ diff --git a/jetserver/binaries/jetserver-0.1-sources.jar b/jetserver/binaries/jetserver-0.1-sources.jar deleted file mode 100644 index c3379419..00000000 Binary files a/jetserver/binaries/jetserver-0.1-sources.jar and /dev/null differ diff --git a/jetserver/binaries/jetserver-0.1.jar b/jetserver/binaries/jetserver-0.1.jar deleted file mode 100644 index 2277ddae..00000000 Binary files a/jetserver/binaries/jetserver-0.1.jar and /dev/null differ diff --git a/jetserver/lib/gson-2.2.2.jar b/jetserver/lib/gson-2.2.2.jar deleted file mode 100644 index 9adc66fd..00000000 Binary files a/jetserver/lib/gson-2.2.2.jar and /dev/null differ diff --git a/jetserver/lib/netty-3.6.2.Final.jar b/jetserver/lib/netty-3.6.2.Final.jar deleted file mode 100644 index a421e280..00000000 Binary files a/jetserver/lib/netty-3.6.2.Final.jar and /dev/null differ diff --git a/jetserver/src/main/java/org/menacheri/jetserver/app/impl/Sessions.java b/jetserver/src/main/java/org/menacheri/jetserver/app/impl/Sessions.java deleted file mode 100644 index 409f7cb7..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/app/impl/Sessions.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.menacheri.jetserver.app.impl; - -import org.menacheri.jetserver.app.GameRoom; -import org.menacheri.jetserver.app.Player; -import org.menacheri.jetserver.app.PlayerSession; -import org.menacheri.jetserver.app.Session; -import org.menacheri.jetserver.app.impl.DefaultPlayerSession.PlayerSessionBuilder; -import org.menacheri.jetserver.app.impl.DefaultSession.SessionBuilder; - - -/** - * Factory class used to create a {@link PlayerSession} instance. It will - * create a new instance, initialize it and set the {@link GameRoom} reference - * if necessary. - * - * @author Abraham Menacherry - * - */ -public class Sessions -{ - - public static Session newSession() - { - return new SessionBuilder().build(); - } - - public static PlayerSession newPlayerSession(GameRoom gameRoom, Player player) - { - return new PlayerSessionBuilder().parentGameRoom(gameRoom).player(player).build(); - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/event/impl/ExceptionEventHandler.java b/jetserver/src/main/java/org/menacheri/jetserver/event/impl/ExceptionEventHandler.java deleted file mode 100644 index acb8ec1b..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/event/impl/ExceptionEventHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.menacheri.jetserver.event.impl; - -import org.menacheri.jetserver.app.Session; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.SessionEventHandler; - -public class ExceptionEventHandler implements SessionEventHandler -{ - private final Session session; - - public ExceptionEventHandler(Session session){ - this.session = session; - } - - @Override - public void onEvent(Event event) { - - } - - @Override - public int getEventType() { - return Events.EXCEPTION; - } - - @Override - public Session getSession() { - return null; - } - - @Override - public void setSession(Session session) - throws UnsupportedOperationException { - - } - - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/AMF3ToEventSourceDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/AMF3ToEventSourceDecoder.java deleted file mode 100644 index dcaff52d..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/AMF3ToEventSourceDecoder.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.menacheri.jetserver.event.Event; - -/** - * If the incoming event is of type {@link Event} then it will only - * de-serialize the source of the event rather than the whole event object. The - * de-serialized source is now set as source of the event. - * - * @author Abraham Menacherry - * - */ -public class AMF3ToEventSourceDecoder extends AMF3ToJavaObjectDecoder -{ - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - Event event = (Event) msg; - Object source = super.decode(ctx, channel, event.getSource()); - event.setSource(source); - return event; - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayDecoder.java deleted file mode 100644 index cf5940e6..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayDecoder.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * This is a very basic decoder which will decode the {@link ChannelBuffer} to - * a byte array and send it onwards. It is useful for sending game operations as - * bytes and should be used for fast paced games where object serialization - * would be expensive. It can however be used with a serializer also, sine it is - * sending a byte array. - * - * @author Abraham Menacherry - * - */ -@Sharable -public class ByteArrayDecoder extends OneToOneDecoder -{ - private static final Logger LOG = LoggerFactory.getLogger(ByteArrayDecoder.class); - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if ((null == msg) || !(msg instanceof ChannelBuffer)) - { - // TODO add an exception handler to the pipeline to deal with this - // scenario. - LOG.error("Incoming message not of ChannelBuffer type {}",msg); - return msg; - } - - ChannelBuffer buffer = (ChannelBuffer) msg; - - // TODO return this instead of byte array. This maybe more useful protocol. - //buffer.toByteBuffer(); - return buffer.array(); - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayStreamDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayStreamDecoder.java deleted file mode 100644 index 90c5f729..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayStreamDecoder.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import java.io.ByteArrayInputStream; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -@Sharable -public class ByteArrayStreamDecoder extends OneToOneDecoder{ - private static final Logger LOG = LoggerFactory.getLogger(ByteArrayStreamDecoder.class); - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception { - if ((null == msg)) - { - LOG.error("Incoming message is null"); - return msg; - } - Event event = (Event)msg; - if(event.getType() == Events.SESSION_MESSAGE) - { - ChannelBuffer buffer = (ChannelBuffer)event.getSource(); - LOG.trace("BinaryArray with size:{} Received.", buffer.readableBytes()); - ByteArrayInputStream bis = new ByteArrayInputStream(buffer.array()); - event.setSource(bis); - } - return event; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayToChannelBufferEncoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayToChannelBufferEncoder.java deleted file mode 100644 index 19ca9e7e..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ByteArrayToChannelBufferEncoder.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Converts a byte array object to a {@link ChannelBuffer}. It actually wraps - * the byte array with the {@link ChannelBuffer} instance using wrappedBuffer - * method. - * - * @author Abraham Menacherry - * - */ -@Sharable -public class ByteArrayToChannelBufferEncoder extends OneToOneEncoder -{ - private static final Logger LOG = LoggerFactory.getLogger(AMF3ToJavaObjectDecoder.class); - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if (!(msg instanceof byte[])) - { - LOG.error("Invalid object type passed into encoder: {} " - + "Expected byte[] object in class " - + "ByteArrayToChannelBufferEncoder.",msg.getClass().getName()); - return msg; - } - byte[] byteArray = (byte[]) msg; - LOG.trace("Converting byte array to channel buffer in ByteArrayToChannelBufferEncoder"); - ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(byteArray); - return buffer; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/DefaultToServerHandler.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/DefaultToServerHandler.java deleted file mode 100644 index 3afff2fc..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/DefaultToServerHandler.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.menacheri.jetserver.app.GameEvent; -import org.menacheri.jetserver.app.PlayerSession; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * This class will handle on the {@link GameEvent}s by forwarding message - * events to the associated session instance. - * - * @author Abraham Menacherry - * - */ -public class DefaultToServerHandler extends SimpleChannelUpstreamHandler -{ - private static final Logger LOG = LoggerFactory.getLogger(DefaultToServerHandler.class); - - /** - * The player session associated with this stateful business handler. - */ - private final PlayerSession playerSession; - - public DefaultToServerHandler(PlayerSession playerSession) - { - super(); - this.playerSession = playerSession; - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) - throws Exception - { - playerSession.onEvent((Event) e.getMessage()); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception - { - LOG.error("Exception during network communication: {}.", e); - Event event = Events.event(e, Events.EXCEPTION); - playerSession.onEvent(event); - } - - @Override - public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) - throws Exception - { - LOG.debug("Netty Channel {} is closed.", e.getChannel().getId()); - if (!playerSession.isShuttingDown()) - { - // Should not send close to session, since reconnection/other - // business logic might be in place. - Event event = Events.event(e, Events.DISCONNECT); - playerSession.onEvent(event); - } - } - - public PlayerSession getPlayerSession() - { - return playerSession; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventDecoder.java deleted file mode 100644 index 4eb41b58..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventDecoder.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.menacheri.jetserver.event.Events; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -@Sharable -public class EventDecoder extends OneToOneDecoder -{ - private static final Logger LOG = LoggerFactory.getLogger(EventDecoder.class); - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if(null == msg) - { - LOG.error("Null msg received in EventDecoder"); - return msg; - } - ChannelBuffer buffer = (ChannelBuffer)msg; - int opcode = buffer.readUnsignedByte(); - if(Events.LOG_IN == opcode || Events.RECONNECT == opcode){ - buffer.readUnsignedByte();// To read-destroy the protocol version byte. - } - return Events.event(buffer, opcode); - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventEncoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventEncoder.java deleted file mode 100644 index 0e48b9c1..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventEncoder.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.menacheri.jetserver.event.Event; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * A simple event encoder will receive an incoming event, and convert it to a - * {@link ChannelBuffer}. It will read the event type and put it as the - * opcode(i.e first byte of the buffer), then it will read the event body and - * put convert to ChannelBuffer if necessary and put it as the body of the - * message. - * - * @author Abraham Menacherry - * - */ -@Sharable -public class EventEncoder extends OneToOneEncoder -{ - private static final Logger LOG = LoggerFactory - .getLogger(EventDecoder.class); - - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if (null == msg) - { - LOG.error("Received null message in EventEncoder"); - return msg; - } - Event event = (Event) msg; - ChannelBuffer opcode = ChannelBuffers.buffer(1); - opcode.writeByte(event.getType()); - ChannelBuffer buffer = null; - if(null != event.getSource()) - { - ChannelBuffer data = (ChannelBuffer) event.getSource(); - buffer = ChannelBuffers.wrappedBuffer(opcode, data); - } - else - { - buffer = opcode; - } - return buffer; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventSourceToAMF3Encoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventSourceToAMF3Encoder.java deleted file mode 100644 index 4005714f..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/EventSourceToAMF3Encoder.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; - -@Sharable -public class EventSourceToAMF3Encoder extends JavaObjectToAMF3Encoder -{ - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - Event event = (Event)msg; - ChannelBuffer payload = (ChannelBuffer) super.encode(ctx, channel, event.getSource()); - return Events.event(payload, event.getType()); - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/FlashPolicyServerDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/FlashPolicyServerDecoder.java deleted file mode 100644 index d2ac9706..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/FlashPolicyServerDecoder.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.replay.ReplayingDecoder; -import org.jboss.netty.handler.codec.replay.VoidEnum; -import org.jboss.netty.util.CharsetUtil; - -/** - * @author Bruce Mitchener - */ -public class FlashPolicyServerDecoder extends ReplayingDecoder { - // We don't check for the trailing NULL to make telnet-based debugging easier. - private final ChannelBuffer requestBuffer = ChannelBuffers.copiedBuffer("", CharsetUtil.US_ASCII); - - @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, - ChannelBuffer buffer, VoidEnum state) { - - ChannelBuffer data = buffer.readBytes(requestBuffer.readableBytes()); - if (data.equals(requestBuffer)) { - return data; - } - channel.close(); - return null; - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/IdleStateCheckHandler.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/IdleStateCheckHandler.java deleted file mode 100644 index 8eb0f502..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/IdleStateCheckHandler.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.timeout.IdleState; -import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; -import org.jboss.netty.handler.timeout.IdleStateEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Sharable -public class IdleStateCheckHandler extends IdleStateAwareChannelHandler -{ - private static final Logger LOG = LoggerFactory.getLogger(IdleStateCheckHandler.class); - - @Override - public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) - throws Exception - { - if(e.getState() == IdleState.ALL_IDLE){ - LOG.warn("Channel {} has been idle, it will be disconnected now: ",e.getChannel()); - e.getChannel().close(); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception - { - LOG.warn("Channel {} has thrown exception {}",e.getChannel(),e); - e.getChannel().close(); - super.exceptionCaught(ctx, e); - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/JavaObjectToAMF3Encoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/JavaObjectToAMF3Encoder.java deleted file mode 100644 index 1fb0896d..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/JavaObjectToAMF3Encoder.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.menacheri.jetserver.convert.flex.AMFSerializer; -import org.menacheri.jetserver.convert.flex.SerializationContextProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * This class will convert the incoming java object to Flex AMF3 byte format and - * put them in a Netty {@link ChannelBuffer}. It will return this ChannelBuffer - * to downstream handler. - * - * @author Abraham Menacherry - * - */ -@Sharable -public class JavaObjectToAMF3Encoder extends OneToOneEncoder -{ - private static final Logger LOG = LoggerFactory.getLogger(JavaObjectToAMF3Encoder.class); - - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception { - SerializationContextProvider contextProvider = new SerializationContextProvider(); - AMFSerializer serializer = new AMFSerializer(contextProvider.get()); - ByteArrayOutputStream baos = null; - try - { - baos = serializer.toAmf(msg); - } - catch (IOException e) - { - LOG.error("IO Error: {}",e); - throw e; - } - return convertBAOSToChannelBuffer(baos); - } - - /** - * Utility method to convert a byte array output stream object to a Netty - * channel buffer. This method will created a "wrapped" buffer which will - * not do any copy. - * - * @param baos - * The byte array output stream to convert. - * @return Returns the ChannelBuffer object or null if input is null. - */ - public ChannelBuffer convertBAOSToChannelBuffer(ByteArrayOutputStream baos) - { - if (null == baos) - return null; - - return wrappedBuffer(baos.toByteArray()); - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/MessageBufferEventDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/MessageBufferEventDecoder.java deleted file mode 100644 index 694e29c1..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/MessageBufferEventDecoder.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.menacheri.jetserver.communication.NettyMessageBuffer; -import org.menacheri.jetserver.event.Events; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This decoder will convert a Netty {@link ChannelBuffer} to a - * {@link NettyMessageBuffer}. It will also convert - * {@link Events#NETWORK_MESSAGE} events to {@link Events#SESSION_MESSAGE} - * event. - * - * @author Abraham Menacherry - * - */ -@Sharable -public class MessageBufferEventDecoder extends OneToOneDecoder -{ - private static final Logger LOG = LoggerFactory.getLogger(MessageBufferEventDecoder.class); - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if(null == msg) - { - LOG.error("Null message received in MessageBufferEventDecoder"); - return msg; - } - ChannelBuffer buffer = (ChannelBuffer)msg; - byte opcode = buffer.readByte(); - if (opcode == Events.NETWORK_MESSAGE) - { - opcode = Events.SESSION_MESSAGE; - } - return Events.event(new NettyMessageBuffer(buffer), opcode); - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/MessageBufferEventEncoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/MessageBufferEventEncoder.java deleted file mode 100644 index e4194510..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/MessageBufferEventEncoder.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.menacheri.jetserver.communication.MessageBuffer; -import org.menacheri.jetserver.event.Event; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -@Sharable -public class MessageBufferEventEncoder extends OneToOneEncoder -{ - private static final Logger LOG = LoggerFactory - .getLogger(MessageBufferEventEncoder.class); - - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - if (null == msg) - { - LOG.error("Null message received in MessageBufferEventEncoder"); - return msg; - } - Event event = (Event) msg; - ChannelBuffer opcode = ChannelBuffers.buffer(1); - opcode.writeByte(event.getType()); - ChannelBuffer buffer = null; - if(null != event.getSource()) - { - @SuppressWarnings("unchecked") - MessageBuffer msgBuffer = (MessageBuffer)event.getSource(); - ChannelBuffer data = msgBuffer.getNativeBuffer(); - buffer = ChannelBuffers.wrappedBuffer(opcode, data); - } - else - { - buffer = opcode; - } - return buffer; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/NulEncoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/NulEncoder.java deleted file mode 100644 index ccd801b8..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/NulEncoder.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelHandler.Sharable; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Sharable -public class NulEncoder extends OneToOneEncoder { - - private static final Logger LOG = LoggerFactory.getLogger(NulEncoder.class); - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception { - if(!(msg instanceof ChannelBuffer)) - { - LOG.error("Expected channel buffer but recieved: {}", msg - .getClass().getCanonicalName()); - return msg; - } - ChannelBuffer nulBuffer = ChannelBuffers.wrappedBuffer(new byte[] { 0 }); - ChannelBuffer buffer = ChannelBuffers.wrappedBuffer((ChannelBuffer)msg,nulBuffer); - return buffer; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ProtocolMultiplexerDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ProtocolMultiplexerDecoder.java deleted file mode 100644 index 7d75012a..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/ProtocolMultiplexerDecoder.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.FrameDecoder; -import org.menacheri.jetserver.util.BinaryUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class can be used to switch login-protocol based on the incoming bytes - * sent by a client. So, based on the incoming bytes, it is possible to set SSL - * enabled, normal HTTP, default jetserver protocol, or custom user protocol for - * allowing client to login to jetserver. The appropriate protocol searcher - * needs to be injected via spring to this class. - * - * @author Abraham Menacherry - * - */ -public class ProtocolMultiplexerDecoder extends FrameDecoder -{ - - private static final Logger LOG = LoggerFactory - .getLogger(ProtocolMultiplexerDecoder.class); - - private final LoginProtocol loginProtocol; - private final int bytesForProtocolCheck; - - public ProtocolMultiplexerDecoder(int bytesForProtocolCheck, - LoginProtocol loginProtocol) - { - this.loginProtocol = loginProtocol; - this.bytesForProtocolCheck = bytesForProtocolCheck; - } - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - ChannelBuffer buffer) throws Exception - { - // Will use the first bytes to detect a protocol. - if (buffer.readableBytes() < bytesForProtocolCheck) - { - return null; - } - - ChannelPipeline pipeline = ctx.getPipeline(); - - if (!loginProtocol.applyProtocol(buffer, pipeline)) - { - byte[] headerBytes = new byte[bytesForProtocolCheck]; - buffer.getBytes(buffer.readerIndex(), headerBytes, 0, - bytesForProtocolCheck); - LOG.error( - "Unknown protocol, discard everything and close the connection {}. Incoming Bytes {}", - ctx.getChannel().getId(), - BinaryUtils.getHexString(headerBytes)); - close(buffer, channel); - return null; - } - else - { - pipeline.remove(this); - } - - // Forward the current read buffer as is to the new handlers. - return buffer.readBytes(buffer.readableBytes()); - } - - protected void close(ChannelBuffer buffer, Channel channel) - { - buffer.skipBytes(buffer.readableBytes()); - channel.close(); - } - - public LoginProtocol getLoginProtocol() - { - return loginProtocol; - } - - public int getBytesForProtocolCheck() - { - return bytesForProtocolCheck; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/TextWebsocketDecoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/TextWebsocketDecoder.java deleted file mode 100644 index 77554b27..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/TextWebsocketDecoder.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.impl.DefaultEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.gson.Gson; - -/** - * This class will convert an incoming {@link TextWebSocketFrame} to an - * {@link Event}. The incoming data is expected to be a JSon string - * representation of an Event object. This class uses {@link Gson} to do the - * decoding to {@link DefaultEvent}. If the incoming event is of type - * {@link Events#NETWORK_MESSAGE} then it will be converted to - * {@link Events#SESSION_MESSAGE}. - * - * @author Abraham Menacherry - * - */ -public class TextWebsocketDecoder extends OneToOneDecoder -{ - - private static final Logger LOG = LoggerFactory - .getLogger(ByteArrayStreamDecoder.class); - private Gson gson; - - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - Event event = null; - try - { - TextWebSocketFrame frame = (TextWebSocketFrame) msg; - event = gson.fromJson(frame.getText(), DefaultEvent.class); - if (event.getType() == Events.NETWORK_MESSAGE) - { - event.setType(Events.SESSION_MESSAGE); - } - } - catch (Exception e) - { - LOG.error("Exception occurred while decoding json: ", e); - } - return event; - } - - public Gson getGson() - { - return gson; - } - - public void setGson(Gson gson) - { - this.gson = gson; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/TextWebsocketEncoder.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/TextWebsocketEncoder.java deleted file mode 100644 index d19fdad6..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/TextWebsocketEncoder.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; -import org.menacheri.jetserver.event.Event; - -import com.google.gson.Gson; - -/** - * This encoder will convert an incoming object (mostly expected to be an - * {@link Event} object) to a {@link TextWebSocketFrame} object. It uses - * {@link Gson} to do the Object to JSon String encoding. - * - * @author Abraham Menacherry - * - */ -public class TextWebsocketEncoder extends OneToOneEncoder -{ - - private Gson gson; - - @Override - protected Object encode(ChannelHandlerContext ctx, Channel channel, - Object msg) throws Exception - { - String json = gson.toJson(msg); - return new TextWebSocketFrame(json); - } - - public Gson getGson() - { - return gson; - } - - public void setGson(Gson gson) - { - this.gson = gson; - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/UDPUpstreamHandler.java b/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/UDPUpstreamHandler.java deleted file mode 100644 index dd5fafbe..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/handlers/netty/UDPUpstreamHandler.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.menacheri.jetserver.handlers.netty; - -import java.net.SocketAddress; - -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.jboss.netty.channel.socket.DatagramChannel; -import org.menacheri.jetserver.app.Session; -import org.menacheri.jetserver.communication.MessageSender.Fast; -import org.menacheri.jetserver.communication.NettyUDPMessageSender; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.service.SessionRegistryService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class UDPUpstreamHandler extends SimpleChannelUpstreamHandler -{ - private static final Logger LOG = LoggerFactory.getLogger(UDPUpstreamHandler.class); - private SessionRegistryService udpSessionRegistry; - public UDPUpstreamHandler() - { - super(); - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) - throws Exception - { - // Get the session using the remoteAddress. - SocketAddress remoteAddress = e.getRemoteAddress(); - Session session = udpSessionRegistry.getSession(remoteAddress); - if(null != session) - { - Event event = (Event) e.getMessage(); - // If the session's UDP has not been connected yet then send a - // CONNECT event. - if (!session.isUDPEnabled()) - { - event = getUDPConnectEvent(event, remoteAddress, - (DatagramChannel) e.getChannel()); - // Pass the connect event on to the session - session.onEvent(event); - } - else if (event.getType() == Events.CONNECT) - { - // Duplicate connect just discard. - LOG.trace("Duplicate CONNECT {} received in UDP channel, " - + "for session: {} going to discard", event, session); - } - else - { - // Pass the original event on to the session - session.onEvent(event); - } - } - else - { - LOG.trace("Packet received from unknown source address: {}, going to discard",remoteAddress); - } - } - - public Event getUDPConnectEvent(Event event, SocketAddress remoteAddress, - DatagramChannel udpChannel) - { - LOG.debug("Incoming udp connection remote address : {}", - remoteAddress); - - if (event.getType() != Events.CONNECT) - { - LOG.warn("Going to discard UDP Message Event with type {} " - + "It will get converted to a CONNECT event since " - + "the UDP MessageSender is not initialized till now", - event.getType()); - } - Fast messageSender = new NettyUDPMessageSender(remoteAddress, udpChannel, udpSessionRegistry); - Event connectEvent = Events.connectEvent(messageSender); - - return connectEvent; - } - - public SessionRegistryService getUdpSessionRegistry() - { - return udpSessionRegistry; - } - - public void setUdpSessionRegistry( - SessionRegistryService udpSessionRegistry) - { - this.udpSessionRegistry = udpSessionRegistry; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/AMF3Protocol.java b/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/AMF3Protocol.java deleted file mode 100644 index f0b36689..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/AMF3Protocol.java +++ /dev/null @@ -1,143 +0,0 @@ -package org.menacheri.jetserver.protocols.impl; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; -import org.menacheri.jetserver.app.PlayerSession; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.handlers.netty.AMF3ToEventSourceDecoder; -import org.menacheri.jetserver.handlers.netty.DefaultToServerHandler; -import org.menacheri.jetserver.handlers.netty.EventDecoder; -import org.menacheri.jetserver.handlers.netty.EventEncoder; -import org.menacheri.jetserver.handlers.netty.EventSourceToAMF3Encoder; -import org.menacheri.jetserver.protocols.AbstractNettyProtocol; -import org.menacheri.jetserver.util.NettyUtils; - - -/** - * This protocol defines AMF3 as a byte array being sent over the wire. Used by - * flash clients that use Socket class. This class applies the flash AMF3 - * protocol to the {@link PlayerSession}'s pipeline. The major handlers - * involved are {@link AMF3ToEventSourceDecoder} and - * {@link EventSourceToAMF3Encoder}. - * - * @author Abraham Menacherry - * - * - */ -public class AMF3Protocol extends AbstractNettyProtocol -{ - /** - * After the frame decoder retrieves the bytes from the incoming stream, - * this decoder will convert it to an {@link Event} with the opcode set as - * the first byte read from the buffer. And the source object of the event - * created will have the rest of the {@link ChannelBuffer}. - */ - private EventDecoder eventDecoder; - - /** - * This decoder will do the actual serialization to java object. Any game - * handlers need to be added after this in the pipeline so that they can - * operate on the java object. - */ - private AMF3ToEventSourceDecoder amf3ToEventSourceDecoder; - - /** - * Once the game handler is done with its operations, it writes back the - * java object to the client. When writing back to flash client, it needs to - * use this encoder to encode it to AMF3 format. - */ - private EventSourceToAMF3Encoder eventSourceToAMF3Encoder; - - /** - * This encoder will take the event parsed by the java object to AMF3 - * encoder and create a single wrapped {@link ChannelBuffer} with the opcode - * as header and amf3 bytes as body. - */ - private EventEncoder eventEncoder; - - /** - * Utility handler provided by netty to add the length of the outgoing - * message to the message as a header. - */ - private LengthFieldPrepender lengthFieldPrepender; - - public AMF3Protocol() - { - super("AMF3"); - } - - @Override - public void applyProtocol(PlayerSession playerSession) - { - ChannelPipeline pipeline = NettyUtils - .getPipeLineOfConnection(playerSession); - - // Upstream handlers or encoders (i.e towards server) are added to - // pipeline now. - pipeline.addLast("lengthDecoder", createLengthBasedFrameDecoder()); - pipeline.addLast("eventDecoder",eventDecoder); - pipeline.addLast("amf3ToEventSourceDecoder", amf3ToEventSourceDecoder); - pipeline.addLast("eventHandler", new DefaultToServerHandler( - playerSession)); - - // Downstream handlers (i.e towards client) are added to pipeline now. - // NOTE the last encoder in the pipeline is the first encoder to be called. - pipeline.addLast("lengthFieldPrepender", lengthFieldPrepender); - pipeline.addLast("eventEncoder",eventEncoder); - pipeline.addLast("eventSourceToAMF3Encoder", eventSourceToAMF3Encoder); - } - - public EventSourceToAMF3Encoder getEventSourceToAMF3Encoder() - { - return eventSourceToAMF3Encoder; - } - - public LengthFieldPrepender getLengthFieldPrepender() - { - return lengthFieldPrepender; - } - - public EventDecoder getEventDecoder() - { - return eventDecoder; - } - - public EventEncoder getEventEncoder() - { - return eventEncoder; - } - - public AMF3ToEventSourceDecoder getAmf3ToEventSourceDecoder() - { - return amf3ToEventSourceDecoder; - } - - public void setEventDecoder(EventDecoder eventDecoder) - { - this.eventDecoder = eventDecoder; - } - - public void setEventSourceToAMF3Encoder( - EventSourceToAMF3Encoder eventToAMF3Encoder) - { - this.eventSourceToAMF3Encoder = eventToAMF3Encoder; - } - - public void setEventEncoder(EventEncoder eventEncoder) - { - this.eventEncoder = eventEncoder; - } - - public void setLengthFieldPrepender(LengthFieldPrepender lengthFieldPrepender) - { - this.lengthFieldPrepender = lengthFieldPrepender; - } - - public void setAmf3ToEventSourceDecoder( - AMF3ToEventSourceDecoder amf3ToEventSourceDecoder) - { - this.amf3ToEventSourceDecoder = amf3ToEventSourceDecoder; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/SimpleByteArrayProtocol.java b/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/SimpleByteArrayProtocol.java deleted file mode 100644 index e43e47b0..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/SimpleByteArrayProtocol.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.menacheri.jetserver.protocols.impl; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; -import org.menacheri.jetserver.app.PlayerSession; -import org.menacheri.jetserver.handlers.netty.ByteArrayDecoder; -import org.menacheri.jetserver.handlers.netty.ByteArrayToChannelBufferEncoder; -import org.menacheri.jetserver.protocols.AbstractNettyProtocol; -import org.menacheri.jetserver.util.NettyUtils; -import org.springframework.beans.factory.annotation.Required; - - -/** - * A protocol that can be used for fast paced games where operations and other - * values can be sent as bytes which then get processed and converted to actual - * java method operations. Messages with pay load like [OPCODE][PAYLOAD] will - * find this protocol the most useful. - * - * @author Abraham Menacherry - * - */ -public class SimpleByteArrayProtocol extends AbstractNettyProtocol -{ - /** - * Used to retrieve the rest of the bytes after the length field is - * stripped. - */ - private ByteArrayDecoder byteArrayDecoder; - /** - * Converts a byte array to a {@link ChannelBuffer} while sending to the client. - */ - private ByteArrayToChannelBufferEncoder byteArrayToChannelBufferEncoder; - /** - * Utility handler provided by netty to add the length of the outgoing - * message to the message as a header. - */ - private LengthFieldPrepender lengthFieldPrepender; - - public SimpleByteArrayProtocol() - { - super("SIMPLE_BYTE_ARRAY_PROTOCOL"); - } - - public SimpleByteArrayProtocol(ByteArrayDecoder byteArrayDecoder, - LengthFieldPrepender lengthFieldPrepender) - { - super("SIMPLE_BYTE_ARRAY_PROTOCOL"); - this.byteArrayDecoder = byteArrayDecoder; - this.lengthFieldPrepender = lengthFieldPrepender; - } - - @Override - public void applyProtocol(PlayerSession playerSession) - { - ChannelPipeline pipeline = NettyUtils - .getPipeLineOfConnection(playerSession); - // Upstream handlers or encoders (i.e towards server) are added to - // pipeline now. - pipeline.addLast("lengthDecoder", createLengthBasedFrameDecoder()); - pipeline.addLast("byteArrayDecoder", byteArrayDecoder); - - // Downstream handlers - Filter for data which flows from server to - // client. Note that the last handler added is actually the first - // handler for outgoing data. - pipeline.addLast("byteArrayToChannelBufferEncoder", byteArrayToChannelBufferEncoder); - pipeline.addLast("lengthFieldPrepender", lengthFieldPrepender); - } - - public ByteArrayDecoder getByteArrayDecoder() - { - return byteArrayDecoder; - } - - @Required - public void setByteArrayDecoder(ByteArrayDecoder byteArrayDecoder) - { - this.byteArrayDecoder = byteArrayDecoder; - } - - public LengthFieldPrepender getLengthFieldPrepender() - { - return lengthFieldPrepender; - } - - @Required - public void setLengthFieldPrepender(LengthFieldPrepender lengthFieldPrepender) - { - this.lengthFieldPrepender = lengthFieldPrepender; - } - - public ByteArrayToChannelBufferEncoder getByteArrayToChannelBufferEncoder() - { - return byteArrayToChannelBufferEncoder; - } - - @Required - public void setByteArrayToChannelBufferEncoder( - ByteArrayToChannelBufferEncoder byteArrayToChannelBufferEncoder) - { - this.byteArrayToChannelBufferEncoder = byteArrayToChannelBufferEncoder; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/SimpleSgsProtocolConstants.java b/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/SimpleSgsProtocolConstants.java deleted file mode 100644 index ecec7177..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/protocols/impl/SimpleSgsProtocolConstants.java +++ /dev/null @@ -1,468 +0,0 @@ -package org.menacheri.jetserver.protocols.impl; - - -/** - * SGS Protocol constants. - *

- * A protocol message is constructed as follows: - *

    - *
  • (unsigned short) payload length, not including this field - *
  • (byte) operation code - *
  • optional content, depending on the operation code. - *
- *

- * A {@code ByteArray} is encoded in a context dependent fashion. If the - * ByteArray is the only content, or if the ByteArray is the last piece of - * content (that is, if the length of the ByteArray can be determined by the - * payload length and the length of what has come before), the ByteArray is - * encoded as - *

    - *
  • (byte[]) the bytes in the array - *
- * If there is other content that follows the ByteArray, then the ByteArray is - * encoded as - *
    - *
  • (unsigned short) number of bytes in the array - *
  • (byte[]) content - *
- *

- * A {@code String} is encoded as follows: - *

    - *
  • (unsigned short) number of bytes of modified UTF-8 encoded String - *
  • (byte[]) String encoded in modified UTF-8 as described in - * {@link java.io.DataInput} - *
- * Note that these encodings only apply to those data items that are specified - * explicitly in the protocol. Application data, passed as a ByteArray, may - * contain any information, but will need to be parsed (and, if necessary, - * converted to and from a network representation) by the application or client. - *

- * The total length of a message must not be greater than 65535 bytes; given the - * header information this means that the payload of a message cannot be greater - * than 65532 bytes. If a message larger than this must be sent, it is the - * responsibility of the sender to break the message into pieces and of the - * receiver to re-assemble those pieces. - *

- * Behavior not specified in this document is left as an implementation - * decision for the particular client and server. Information on the - * implementation characteristics of the RedDwarf server can be found - * in the overview for the - * implementation. - */ -public class SimpleSgsProtocolConstants{ - - /** - * This class should not be instantiated. - */ - protected SimpleSgsProtocolConstants() { - } - - /** - * The maximum length of a protocol message: - * {@value #MAX_MESSAGE_LENGTH} bytes. - */ - public static final int MAX_MESSAGE_LENGTH = 65535; - - /** - * The maximum payload length: - * {@value #MAX_PAYLOAD_LENGTH} bytes. - */ - public static final int MAX_PAYLOAD_LENGTH = 65532; - - /** The version number, currently {@code 0x05}. */ - public static final byte VERSION = 0x05; - - /** - * Login request from a client to a server. This message should only be sent - * to a server; if received by a client it should be ignored.
- * Opcode: {@code 0x10}
- * Payload: - *

    - *
  • (byte) protocol version - *
  • (String) name - *
  • (String) password - *
- * The {@code protocol version} will be checked by the server to insure that - * the client and server are using the same protocol or versions of the - * protocol that are compatible. If the server determines that the protocol - * version used by the sender and the protocol version or versions required - * by the server are not compatible, the server will disconnect the client. - * In cases where the protocols being used are not compatible, no other - * communication between the client and the server is guaranteed to be - * understood. - *

- * The {@code name} and {@code password} strings are passed to the server's - * authentication mechanism. After the server processes the login request, - * the server sends one of the following acknowledgments to the client: - *

    - *
  • {@link #LOGIN_SUCCESS}, if user authentication succeeds and - * invoking the {@code loggedIn}' method on the application's - * {@code AppListener} with the user's {@code ClientSession} returns a - * non-null, serializable {@code ClientSessionListener}; - *
  • {@link #LOGIN_REDIRECT}, if user authentication succeeds, but the - * server requests that the client redirect the login request to another - * node; or - *
  • {@link #LOGIN_FAILURE}, if user authentication fails, or if the - * user is already logged in and the server is configured to reject new - * logins for the same user, or if invoking the {@code loggedIn} method on - * the application's {@code AppListener} with the user's - * {@code ClientSession} returns a null, or non-serializable - * {@code ClientSessionListener} or the method does not complete - * successfully. - *
- *

- * If a client is currently logged in, the result of receiving a - * LOGIN_REQUEST is not defined by the protocol, but is an - * implementation-dependent detail of the server. - */ - public static final byte LOGIN_REQUEST = 0x10; - - /** - * Login success. Server response to a client's {@link #LOGIN_REQUEST}. - *
- * Opcode: {@code 0x11}
- * Payload: - *

    - *
  • (ByteArray) reconnectionKey - *
- * The {@code reconnectionKey} is an opaque reference that can be held by - * the client for use in case the client is disconnected and wishes to - * reconnect to the server with the same identity using a - * {@link #RECONNECT_REQUEST}. - */ - public static final byte LOGIN_SUCCESS = 0x11; - - /** - * Login failure. Server response to a client's {@link #LOGIN_REQUEST}. - *
- * Opcode: {@code 0x12}
- * Payload: - *
    - *
  • (String) reason - *
- * This message indicates that the server rejects the {@link #LOGIN_REQUEST} - * for some reason, for example - *
    - *
  • user authentication failure, - *
  • failure during application processing of the client session, or - *
  • a user with the same identity is already logged in, and the server - * is configured to reject new logins for clients who are currently logged - * in - *
- * - */ - public static final byte LOGIN_FAILURE = 0x12; - - /** - * Login redirect. Server response to a client's {@link #LOGIN_REQUEST}. - *
- * Opcode: {@code 0x13}
- * Payload: - *
    - *
  • (String) hostname - *
  • (int) port - *
- * This message indicates a redirection from the node to which the - * {@link #LOGIN_REQUEST} was sent to another node. The client receiving - * this request should shut down the connection to the original node and - * establish a connection to the node indicated by the {@code hostname} and - * {@code port} in the payload. The client should then attempt to log in to - * the node to which it has been redirected by sending a - * {@link #LOGIN_REQUEST} to that node. - */ - public static final byte LOGIN_REDIRECT = 0x13; - - /** - * Suspend messages notification. Server to client notification. - *
- * Opcode: {@code 0x14}
- * Payload: (none)

- * - * This message notifies a client to suspend sending messages to the - * server until it receives further instruction (such as {@link - * #RELOCATE_NOTIFICATION} or {@link #RESUME_MESSAGES}). The client - * should send the acknowledgment {@link #SUSPEND_MESSAGES_COMPLETE} to - * the server when it has suspended sending messages. After the server - * sends a {@code SUSPEND_MESSAGES} notification to the client, the - * server may decide to drop messages from the client if it does not - * receive the {@link #SUSPEND_MESSAGES_COMPLETE} acknowledgment in a - * timely fashion.

- * - * This opcode was introduced in protocol version {@code 0x05}. - */ - public static final byte SUSPEND_MESSAGES = 0x14; - - /** - * Acknowledgment of {@link #SUSPEND_MESSAGES} notification. Client to - * server notification. - *
- * Opcode: {@code 0x15}
- * Payload: (none)

- * - * This message notifies the server that the client has received the - * {@link #SUSPEND_MESSAGES} notification. Any messages received by the - * server after this notification will be dropped, unless the server - * has instructed the client to either resume messages or relocate its - * client session to another node.

- * - * This opcode was introduced in protocol version {@code 0x05}. - */ - public static final byte SUSPEND_MESSAGES_COMPLETE = 0x15; - - /** - * Resume messages notification. Server to client notification. - *
- * Opcode: {@code 0x16}
- * Payload: (none)

- * - * This message notifies the client that it can resume sending messages - * to the server.

- * - * This opcode was introduced in protocol version {@code 0x05}. - */ - public static final byte RESUME_MESSAGES = 0x16; - - /** - * Relocate session notification. Server to client notification. - *
- * Opcode: {@code 0x17}
- * Payload: - *

    - *
  • (String) hostname - *
  • (int) port - *
  • (ByteArray) relocationKey - *
- * - * This message notifies a client to relocate its session on the - * current node to a new node. The client receiving this request should - * shut down the connection to the original node and establish a - * connection to the node indicated by the {@code hostname} and {@code - * port} in the payload. The client should then attempt to reestablish - * the client session with the server (without logging in) using the - * {@code relocationKey} specified in the payload.

- * - * This opcode was introduced in protocol version {@code 0x05}. - */ - public static final byte RELOCATE_NOTIFICATION = 0x17; - - /** - * Relocation request. Client requesting relocation to a server.
- * Opcode: {@code 0x18}
- * Payload: - *

    - *
  • (byte) protocol version - *
  • (ByteArray) relocationKey - *
- * - * This message requests that the client's existing client session be - * relocated to (and re-established with) the server. The {@code - * relocationKey} must match the one that the client received in the - * previous {@link #RELOCATE_NOTIFICATION} message. If relocation is - * successful, the server acknowledges the request with a {@link - * #RELOCATE_SUCCESS} message containing a {@code reconnectionKey} for - * reconnecting to the server. If relocation is not successful, a - * {@link #RELOCATE_FAILURE} message is sent to the client. If the - * client receives a {@code RELOCATE_FAILURE} message, the client - * should disconnect from the server.

- * - * This opcode was introduced in protocol version {@code 0x05}. - */ - public static final byte RELOCATE_REQUEST = 0x18; - - /** - * Relocation success. Server response to a client's {@link - * #RELOCATE_REQUEST}. - *
- * Opcode: {@code 0x19}
- * Payload: - *

    - *
  • (ByteArray) reconnectionKey - *
- * The {@code reconnectionKey} is an opaque reference that can be held by - * the client for use in case the client is disconnected and wishes to - * reconnect to the server with the same identity using a - * {@link #RECONNECT_REQUEST}.

- * - * This opcode was introduced in protocol version {@code 0x05}. - */ - public static final byte RELOCATE_SUCCESS = 0x19; - - /** - * Relocate failure. Server response to a client's {@link - * #RELOCATE_REQUEST}. - *
- * Opcode: {@code 0x1a}
- * Payload: - *

    - *
  • (String) reason - *
- * This message indicates that the server rejects the {@link - * #RELOCATE_REQUEST} for some reason, for example - *
    - *
  • session not relocating to the server - *
  • relocation key mismatch - *
  • a user with the same identity is already logged in - *

- * - * This opcode was introduced in protocol version {@code 0x05}. - */ - public static final byte RELOCATE_FAILURE = 0x1a; - - /** - * Reconnection request. Client requesting reconnect to a server.
- * Opcode: {@code 0x20}
- * Payload: - *

    - *
  • (byte) protocol version - *
  • (ByteArray) reconnectionKey - *
- * This message requests that the client be reconnected to an existing - * client session with the server. The {@code reconnectionKey} must match - * the one that the client received in the previous {@link #LOGIN_SUCCESS} - * or {@link #RECONNECT_SUCCESS} message (if reconnection was performed - * subsequent to login). If reconnection is successful, the server - * acknowledges the request with a {@link #RECONNECT_SUCCESS} message - * containing a new {@code reconnectionKey}. If reconnection is not - * successful, a {@link #RECONNECT_FAILURE} message is sent to the client. - * If the client receives a {@code RECONNECT_FAILURE} message, the client - * should disconnect from the server. - */ - public static final byte RECONNECT_REQUEST = 0x20; - - /** - * Reconnect success. Server response to a client's - * {@link #RECONNECT_REQUEST}.
- * Opcode: {@code 0x21}
- * Payload: - *
    - *
  • (ByteArray) reconnectionKey - *
- * Indicates that a {@link #RECONNECT_REQUEST} has been successful. The - * message will include a {@code reconnectionKey} that can be used in a - * subsequent reconnect requests from the client. Reciept of this message - * indicates that the client session has been re-established. - */ - public static final byte RECONNECT_SUCCESS = 0x21; - - /** - * Reconnect failure. Server response to a client's - * {@link #RECONNECT_REQUEST}. - *
- * Opcode: {@code 0x22} - *
- * Payload: - *
    - *
  • (String) reason - *
- * This response indicates that a reconnect request could not be honored by - * the server. This could be because of an invalid reconnect key, or - * because too much time has elapsed between the session disconnection and - * the reconnect request (which, in turn, may cause the server to - * discard the session state). The string returned details the reason for - * the denial of reconnection. - */ - public static final byte RECONNECT_FAILURE = 0x22; - - /** - * Session message. May be sent by the client or the server. Maximum length - * is {@value #MAX_PAYLOAD_LENGTH} bytes. Larger messages require - * fragmentation and reassembly above this protocol layer. - *
- * Opcode: {@code 0x30} - *
- * Payload: - *
    - *
  • (ByteArray) message - *
- * This message allows information to be sent between the client and the - * server. The content of the message is application dependent, and the - * mechanisms for constructing and parsing these messages is an - * application-level task. - */ - public static final byte SESSION_MESSAGE = 0x30; - - /** - * Logout request from a client to a server. - *
- * Opcode: {@code 0x40} - *
- * No payload. - *
- * This message will cause the client to be logged out of the server. The - * server will remove all of the client's channel memberships. Any message - * (other than {@link #LOGIN_REQUEST}) sent by the client after sending this - * message will be ignored, and any message will need to be sent on a new - * connection to the server. - */ - public static final byte LOGOUT_REQUEST = 0x40; - - /** - * Logout success. Server response to a client's {@link #LOGOUT_REQUEST}. - *
- * Opcode: {@code 0x41} - *
- * No payload. - *
- * This message is sent from the server to the client to indicate that a - * {@link #LOGOUT_REQUEST} has been received and that the client has been - * logged out of the current session. On receipt of this message, the client - * should shut down any networking resources that are used to communicate - * with the server. - */ - public static final byte LOGOUT_SUCCESS = 0x41; - - /** - * Channel join. Server notifying a client that it has joined a channel. - *
- * Opcode: {@code 0x50} - *
- * Payload: - *
    - *
  • (String) channel name - *
  • (ByteArray) channel ID - *
- * This message is sent from the server to the client to indicate that the - * client has been added to the channel identified by the {@code channel - * name} and {@code channel ID} contained in the message. - */ - public static final byte CHANNEL_JOIN = 0x50; - - /** - * Channel leave. Server notifying a client that the client has left a - * channel. - *
- * Opcode: {@code 0x51} - *
- * Payload: - *
    - *
  • (ByteArray) channel ID - *
- * This message is sent from the server indicating to the client that the - * client has been removed from the channel with the indicated {@code - * channel ID}. The client can no longer send messages on the channel. - */ - public static final byte CHANNEL_LEAVE = 0x51; - - /** - * Channel message. May be sent by the client or the server. Maximum length - * is {@value #MAX_PAYLOAD_LENGTH} bytes minus the sum of the {@code - * channel ID} size and two bytes (the size of the unsigned short indicating - * the {@code channel Id} size). Larger messages require fragmentation and - * reassembly above this protocol layer. - *
- * Opcode: {@code 0x52} - *
- * Payload: - *
    - *
  • (unsigned short) channel ID size - *
  • (ByteArray) channel ID - *
  • (ByteArray) message - *
- * This message requests that the specified message be sent to all members - * of the specified channel. If the client sending the request is not a - * member of the channel, the message will be rejected by the server. The - * server may also refuse to send the message, or alter the message, because - * of application-specific logic. - */ - public static final byte CHANNEL_MESSAGE = 0x52; -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/AbstractNettyServer.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/AbstractNettyServer.java deleted file mode 100644 index 3a11ea72..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/AbstractNettyServer.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import java.net.InetSocketAddress; - -import org.jboss.netty.bootstrap.Bootstrap; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.channel.group.ChannelGroup; -import org.jboss.netty.channel.group.ChannelGroupFuture; -import org.jboss.netty.channel.group.DefaultChannelGroup; -import org.menacheri.jetserver.app.Session; -import org.menacheri.jetserver.service.GameAdminService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Required; - - -public abstract class AbstractNettyServer implements NettyServer -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractNettyServer.class); - public static final ChannelGroup ALL_CHANNELS = new DefaultChannelGroup("JETSERVER-CHANNELS"); - protected Session session; - protected InetSocketAddress socketAddress; - protected int portNumber = 18090; - protected Bootstrap serverBootstrap; - protected ChannelPipelineFactory pipelineFactory; - protected GameAdminService gameAdminService; - - public AbstractNettyServer() - { - super(); - } - - @Override - public void stopServer() throws Exception - { - LOG.debug("In stopServer method of class: {}", - this.getClass().getName()); - ChannelGroupFuture future = ALL_CHANNELS.close(); - try { - future.await(); - } catch (InterruptedException e) { - LOG.error("Execption occurred while waiting for channels to close: {}",e); - } - serverBootstrap.releaseExternalResources(); - gameAdminService.shutdown(); - } - - @Override - public void configureServerBootStrap(String[] optionsList) - { - // For clients who do not use spring. - if(null == serverBootstrap){ - createServerBootstrap(); - } - serverBootstrap.setPipelineFactory(pipelineFactory); - if (null != optionsList && optionsList.length > 0) - { - for (String option : optionsList) - { - serverBootstrap.setOption(option, true); - } - } - } - - public int getPortNumber(String[] args) - { - if (null == args || args.length < 1) - { - return portNumber; - } - - try - { - return Integer.parseInt(args[0]); - } - catch (NumberFormatException e) - { - LOG.error("Exception occurred while " - + "trying to parse the port number: {}", args[0]); - LOG.error("NumberFormatException: {}",e); - throw e; - } - } - - @Override - public Bootstrap getServerBootstrap() - { - return serverBootstrap; - } - - @Override - public void setServerBootstrap(Bootstrap serverBootstrap) - { - this.serverBootstrap = serverBootstrap; - } - - @Override - public ChannelPipelineFactory getPipelineFactory() - { - return pipelineFactory; - } - - @Override - @Required - public void setPipelineFactory(ChannelPipelineFactory factory) - { - pipelineFactory = factory; - } - - public int getPortNumber() - { - return portNumber; - } - - public void setPortNumber(int portNumber) - { - this.portNumber = portNumber; - } - - public GameAdminService getGameAdminService() - { - return gameAdminService; - } - - public void setGameAdminService(GameAdminService gameAdminService) - { - this.gameAdminService = gameAdminService; - } - - @Override - public InetSocketAddress getSocketAddress() - { - return socketAddress; - } - - public void setInetAddress(InetSocketAddress inetAddress) - { - this.socketAddress = inetAddress; - } - - @Override - public String toString() - { - return "NettyServer [socketAddress=" + socketAddress + ", portNumber=" - + portNumber + "]"; - } - - @Override - public Session getSession() - { - return session; - } - - @Override - public void setSession(Session session) - { - this.session = session; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/FlashPolicyServer.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/FlashPolicyServer.java deleted file mode 100644 index b3a416c3..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/FlashPolicyServer.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import java.util.concurrent.Executors; - -import org.jboss.netty.bootstrap.Bootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; -import org.menacheri.jetserver.concurrent.NamedThreadFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class FlashPolicyServer extends NettyTCPServer -{ - private static final Logger LOG = LoggerFactory.getLogger(FlashPolicyServer.class); - private int portNumber = 843; - - public int getPortNumber(String[] args) - { - if (null == args || args.length != 2) - { - LOG.debug("Going to use port: {}", portNumber); - return portNumber; - } - - try - { - int portNumberArg = Integer.parseInt(args[1]); - LOG.debug("Going to use port: {}", portNumberArg); - return portNumberArg; - } - catch (NumberFormatException e) - { - LOG.error("Exception occurred while " - + "trying to parse the port number: {}, {}", args[0], e); - throw e; - } - } - - public Bootstrap createServerBootstrap() - { - // TODO The thread pools should be injected from spring. - serverBootstrap = new ServerBootstrap( - - new NioServerSocketChannelFactory(Executors - .newFixedThreadPool(1,new NamedThreadFactory( - "Flash-Server-Boss")), Executors - .newFixedThreadPool(1,new NamedThreadFactory( - "Flash-Server-Worker")))); - - return serverBootstrap; - } - - public int getPortNumber() - { - return portNumber; - } - - public void setPortNumber(int portNumber) - { - this.portNumber = portNumber; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/FlashPolicyServerPipelineFactory.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/FlashPolicyServerPipelineFactory.java deleted file mode 100644 index 423cdbfc..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/FlashPolicyServerPipelineFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import static org.jboss.netty.channel.Channels.pipeline; - -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.handler.timeout.ReadTimeoutHandler; -import org.jboss.netty.util.Timer; -import org.menacheri.jetserver.handlers.netty.FlashPolicyServerDecoder; -import org.menacheri.jetserver.handlers.netty.FlashPolicyServerHandler; - - -/** - * @author Bruce Mitchener - */ -public class FlashPolicyServerPipelineFactory implements ChannelPipelineFactory -{ - private Timer timer; - - public ChannelPipeline getPipeline() throws Exception { - // Create a default pipeline implementation. - ChannelPipeline pipeline = pipeline(); - pipeline.addLast("timeout", new ReadTimeoutHandler(timer, 30)); - pipeline.addLast("decoder", new FlashPolicyServerDecoder()); - pipeline.addLast("handler", getFlashPolicyServerHandler()); - return pipeline; - } - - /** - * Spring will return the actual prototype bean from its context here. It - * uses method lookup here. - * - * @return a new instance of the {@link FlashPolicyServerHandler} - */ - protected FlashPolicyServerHandler getFlashPolicyServerHandler() - { - return null; - } - - public Timer getTimer() - { - return timer; - } - - public void setTimer(Timer timer) - { - this.timer = timer; - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/LoginPipelineFactory.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/LoginPipelineFactory.java deleted file mode 100644 index c77917ef..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/LoginPipelineFactory.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import static org.jboss.netty.channel.Channels.pipeline; - -import org.jboss.netty.channel.ChannelHandler; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; -import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; -import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; -import org.jboss.netty.handler.timeout.IdleStateHandler; -import org.jboss.netty.util.Timer; -import org.menacheri.jetserver.handlers.netty.EventDecoder; -import org.menacheri.jetserver.handlers.netty.LoginHandler; - - -public class LoginPipelineFactory implements ChannelPipelineFactory -{ - /** - * TODO make this configurable - */ - private static final int MAX_IDLE_SECONDS = 60; - private int frameSize; - private Timer timer; - private IdleStateAwareChannelHandler idleCheckHandler; - private EventDecoder eventDecoder; - private LoginHandler loginHandler; - private LengthFieldPrepender lengthFieldPrepender; - - @Override - public ChannelPipeline getPipeline() throws Exception - { - // Create a default pipeline implementation. - ChannelPipeline pipeline = pipeline(); - addHandlers(pipeline); - return pipeline; - } - - public ChannelPipeline addHandlers(ChannelPipeline pipeline) - { - if (null == pipeline) - return null; - pipeline.addLast("framer",createLengthBasedFrameDecoder()); - pipeline.addLast("idleStateCheck", new IdleStateHandler(timer, 0, 0, - MAX_IDLE_SECONDS)); - pipeline.addLast("idleCheckHandler", idleCheckHandler); - pipeline.addLast("eventDecoder", eventDecoder); - pipeline.addLast("loginHandler", loginHandler); - pipeline.addLast("lengthFieldPrepender",lengthFieldPrepender); - return pipeline; - } - - public ChannelHandler createLengthBasedFrameDecoder() - { - return new LengthFieldBasedFrameDecoder(frameSize, 0, 2, 0, 2); - } - - public int getFrameSize() - { - return frameSize; - } - - public void setFrameSize(int frameSize) - { - this.frameSize = frameSize; - } - - public EventDecoder getEventDecoder() - { - return eventDecoder; - } - - public void setEventDecoder(EventDecoder eventDecoder) - { - this.eventDecoder = eventDecoder; - } - - public LoginHandler getLoginHandler() - { - return loginHandler; - } - - public void setLoginHandler(LoginHandler loginHandler) - { - this.loginHandler = loginHandler; - } - - public IdleStateAwareChannelHandler getIdleCheckHandler() - { - return idleCheckHandler; - } - - public void setIdleCheckHandler(IdleStateAwareChannelHandler idleCheckHandler) - { - this.idleCheckHandler = idleCheckHandler; - } - - public Timer getTimer() - { - return timer; - } - - public void setTimer(Timer timer) - { - this.timer = timer; - } - - public LengthFieldPrepender getLengthFieldPrepender() - { - return lengthFieldPrepender; - } - - public void setLengthFieldPrepender(LengthFieldPrepender lengthFieldPrepender) - { - this.lengthFieldPrepender = lengthFieldPrepender; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyServer.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyServer.java deleted file mode 100644 index 64b6fbf3..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyServer.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import org.jboss.netty.bootstrap.Bootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.menacheri.jetserver.server.Server; - -/** - * An interface specific to the JBoss Netty implementation. It will be - * implemented by a class that will start up a Netty server at a specified port. - * - * @author Abraham Menacherry - * - */ -public interface NettyServer extends Server -{ - /** - * Creates a {@link ServerBootstrap} object which is used to start a server. - * - * @return Returns the created {@link ServerBootstrap}. - */ - public Bootstrap createServerBootstrap(); - - /** - * If thread pools or TCP/IP parameters or the pipeline factory need to be - * modified then it is this method that needs to be overriden. - * - * @param optionsList - * Used to set tcp ip options like noDelay etc. - */ - public void configureServerBootStrap(String[] optionsList); - - /** - * createServerBootstrap will create a pipeline factory and save it as a - * class variable. This method can then be used to retrieve that value. - * - * @return Returns the channel pipeline factory that is associated with this - * netty server. - */ - public ChannelPipelineFactory getPipelineFactory(); - - /** - * Method can be used to set the pipeline factory that is to be used by the - * netty server. - * - * @param factory - * The factory which will create a pipeline on each incoming - * connection. - */ - public void setPipelineFactory(ChannelPipelineFactory factory); - - /** - * @return Returns the created server bootstrap object. - */ - public Bootstrap getServerBootstrap(); - - /** - * Sets the server bootstrap, could be TCP, UDP bootstrap. - * - * @param serverBootstrap - */ - public void setServerBootstrap(Bootstrap serverBootstrap); -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyTCPServer.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyTCPServer.java deleted file mode 100644 index fcee39ab..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyTCPServer.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import java.net.InetSocketAddress; -import java.util.Arrays; -import java.util.concurrent.Executors; - -import org.jboss.netty.bootstrap.Bootstrap; -import org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelException; -import org.jboss.netty.channel.group.ChannelGroupFuture; -import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; -import org.menacheri.jetserver.concurrent.NamedThreadFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * This class is used for TCP IP communications with client. It uses Netty tcp - * server bootstrap for this. - * - * @author Abraham Menacherry - * - */ -public class NettyTCPServer extends AbstractNettyServer -{ - private static final Logger LOG = LoggerFactory.getLogger(NettyTCPServer.class); - - private String[] args; - - public NettyTCPServer() - { - - } - - public void startServer(int port) throws Exception - { - portNumber = port; - startServer(args); - } - - @Override - public void startServer() throws Exception - { - startServer(args); - } - - public void startServer(String[] args) throws Exception - { - int portNumber = getPortNumber(args); - InetSocketAddress socketAddress = new InetSocketAddress(portNumber); - startServer(socketAddress); - } - - public Bootstrap createServerBootstrap() - { - // TODO The thread pools should be injected from spring. - serverBootstrap = new ServerBootstrap( - new NioServerSocketChannelFactory(Executors - .newCachedThreadPool(new NamedThreadFactory( - "TCP-Server-Boss")), Executors - .newCachedThreadPool(new NamedThreadFactory( - "TCP-Server-Worker")))); - - return serverBootstrap; - } - - @Override - public TransmissionProtocol getTransmissionProtocol() - { - return TRANSMISSION_PROTOCOL.TCP; - } - - @Override - public void startServer(InetSocketAddress socketAddress) - { - this.socketAddress = socketAddress; - if (null == args || args.length == 0) - { - String[] optionsList = new String[2]; - optionsList[0] = "child.tcpNoDelay"; - optionsList[1] = "child.keepAlive"; - configureServerBootStrap(optionsList); - } - else - { - configureServerBootStrap(args); - } - try - { - ((ServerBootstrap) serverBootstrap).bind(socketAddress); - } - catch (ChannelException e) - { - LOG.error("Unable to start TCP server due to error {}",e); - throw e; - } - } - - public void stopServer() throws Exception - { - LOG.debug("In stopServer method of class: {}", - this.getClass().getName()); - ChannelGroupFuture future = ALL_CHANNELS.close(); - try { - future.await(); - } catch (InterruptedException e) { - LOG.error("Execption occurred while waiting for channels to close: {}",e); - } - super.stopServer(); - } - - public String[] getArgs() - { - return args; - } - - public void setArgs(String[] args) - { - this.args = args; - } - - @Override - public String toString() - { - return "NettyTCPServer [args=" + Arrays.toString(args) - + ", socketAddress=" + socketAddress + ", portNumber=" + portNumber - + "]"; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyUDPServer.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyUDPServer.java deleted file mode 100644 index a1a80257..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/NettyUDPServer.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import java.net.InetSocketAddress; -import java.util.Arrays; -import java.util.concurrent.Executors; - -import org.jboss.netty.bootstrap.Bootstrap; -import org.jboss.netty.bootstrap.ConnectionlessBootstrap; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelException; -import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory; -import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; -import org.menacheri.jetserver.concurrent.NamedThreadFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -/** - * This server does UDP connection less broadcast. Since it does not store the - * connection, each call to a channel write must also contain the remote socket - * address e.getChannel().write("Message", e.getRemoteAddress()). - * Since it uses the same channel for all incoming connections, the handlers - * cannot be modified refer to nabble - * post - * - * @author Abraham Menacherry - * - */ -public class NettyUDPServer extends AbstractNettyServer -{ - private static final Logger LOG = LoggerFactory.getLogger(NettyUDPServer.class); - private FixedReceiveBufferSizePredictorFactory bufferSizePredictor; - private String[] args; - - /** - * The connected channel for this server. This reference can be used to - * shutdown this server. - */ - private Channel channel; - - public NettyUDPServer() - { - - } - - @Override - public void startServer(int port) throws Exception - { - portNumber = port; - startServer(args); - } - - @Override - public void startServer() throws Exception - { - startServer(args); - } - - public void startServer(String[] args) throws Exception - { - int portNumber = getPortNumber(args); - InetSocketAddress socketAddress = new InetSocketAddress(portNumber); - startServer(socketAddress); - } - - @Override - public Bootstrap createServerBootstrap() - { - serverBootstrap = new ConnectionlessBootstrap( - new NioDatagramChannelFactory(Executors - .newCachedThreadPool(new NamedThreadFactory( - "UDP-Server-Worker")))); - return serverBootstrap; - } - - @Override - public void stopServer() throws Exception - { - if(null != channel) - { - channel.close(); - } - super.stopServer(); - } - - public FixedReceiveBufferSizePredictorFactory getBufferSizePredictor() - { - return bufferSizePredictor; - } - - public void setBufferSizePredictor( - FixedReceiveBufferSizePredictorFactory bufferSizePredictor) - { - this.bufferSizePredictor = bufferSizePredictor; - } - - @Override - public TransmissionProtocol getTransmissionProtocol() - { - return TRANSMISSION_PROTOCOL.UDP; - } - - @Override - public void startServer(InetSocketAddress socketAddress) - { - this.socketAddress = socketAddress; - //TODO these should be set from spring - serverBootstrap.setOption("broadcast", "false"); - serverBootstrap.setOption("receiveBufferSizePredictorFactory", - bufferSizePredictor); - serverBootstrap.setOption("sendBufferSize", 65536); - serverBootstrap.setOption("receiveBufferSize", 65536); - configureServerBootStrap(args); - - try - { - channel = ((ConnectionlessBootstrap) serverBootstrap) - .bind(socketAddress); - } - catch (ChannelException e) - { - LOG.error("Unable to start UDP server due to error {}",e); - throw e; - } - - } - - public String[] getArgs() - { - return args; - } - - public void setArgs(String[] args) - { - this.args = args; - } - - @Override - public String toString() - { - return "NettyUDPServer [args=" + Arrays.toString(args) - + ", socketAddress=" + socketAddress + ", portNumber=" + portNumber - + "]"; - } - -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/ProtocolMultiplexerPipelineFactory.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/ProtocolMultiplexerPipelineFactory.java deleted file mode 100644 index f94aa5cf..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/ProtocolMultiplexerPipelineFactory.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import static org.jboss.netty.channel.Channels.pipeline; - -import org.jboss.netty.channel.ChannelHandler; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; -import org.jboss.netty.handler.timeout.IdleStateHandler; -import org.jboss.netty.util.Timer; -import org.menacheri.jetserver.handlers.netty.LoginProtocol; -import org.menacheri.jetserver.handlers.netty.ProtocolMultiplexerDecoder; - -public class ProtocolMultiplexerPipelineFactory implements - ChannelPipelineFactory -{ - private static final int MAX_IDLE_SECONDS = 60; - private Timer timer; - private IdleStateAwareChannelHandler idleCheckHandler; - private int bytesForProtocolCheck; - private LoginProtocol loginProtocol; - - @Override - public ChannelPipeline getPipeline() throws Exception - { - // Create a default pipeline implementation. - ChannelPipeline pipeline = pipeline(); - pipeline.addLast("idleStateCheck", new IdleStateHandler(timer, 0, 0, - MAX_IDLE_SECONDS)); - pipeline.addLast("idleCheckHandler", idleCheckHandler); - pipeline.addLast("multiplexer", createProtcolMultiplexerDecoder()); - return pipeline; - } - - protected ChannelHandler createProtcolMultiplexerDecoder() - { - return new ProtocolMultiplexerDecoder(bytesForProtocolCheck,loginProtocol); - } - - public Timer getTimer() - { - return timer; - } - - public void setTimer(Timer timer) - { - this.timer = timer; - } - - public IdleStateAwareChannelHandler getIdleCheckHandler() - { - return idleCheckHandler; - } - - public void setIdleCheckHandler(IdleStateAwareChannelHandler idleCheckHandler) - { - this.idleCheckHandler = idleCheckHandler; - } - - public int getBytesForProtocolCheck() - { - return bytesForProtocolCheck; - } - - public void setBytesForProtocolCheck(int bytesForProtocolCheck) - { - this.bytesForProtocolCheck = bytesForProtocolCheck; - } - - public LoginProtocol getLoginProtocol() - { - return loginProtocol; - } - - public void setLoginProtocol(LoginProtocol loginProtocol) - { - this.loginProtocol = loginProtocol; - } -} diff --git a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/UDPChannelPipelineFactory.java b/jetserver/src/main/java/org/menacheri/jetserver/server/netty/UDPChannelPipelineFactory.java deleted file mode 100644 index bd3e5733..00000000 --- a/jetserver/src/main/java/org/menacheri/jetserver/server/netty/UDPChannelPipelineFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.menacheri.jetserver.server.netty; - -import static org.jboss.netty.channel.Channels.pipeline; - -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelPipelineFactory; -import org.menacheri.jetserver.handlers.netty.MessageBufferEventDecoder; -import org.menacheri.jetserver.handlers.netty.MessageBufferEventEncoder; -import org.menacheri.jetserver.handlers.netty.UDPUpstreamHandler; - - -public class UDPChannelPipelineFactory implements ChannelPipelineFactory -{ - /** - * This pipeline will be shared across all the channels. In Netty UDP - * implementation it does not make sense to have different pipelines for - * different channels as the protocol is essentials "connection-less" - */ - ChannelPipeline pipeline; - /** - * The Message buffer event decoder and encoder for the pipeline. - */ - private MessageBufferEventDecoder messageBufferEventDecoder; - private MessageBufferEventEncoder messageBufferEventEncoder; - - // Create a default pipeline implementation. - private UDPUpstreamHandler upstream; - - public UDPChannelPipelineFactory() - { - - } - - public UDPChannelPipelineFactory(UDPUpstreamHandler upstream) - { - this.upstream = upstream; - } - - /** - * This method creates a single pipeline object that will be shared for all - * the channels. - */ - public void init() - { - pipeline = pipeline(); - - pipeline.addLast("messageBufferEventDecoder", messageBufferEventDecoder); - pipeline.addLast("upstream", upstream); - - // Downstream handlers - Filter for data which flows from server to - // client. Note that the last handler added is actually the first - // handler for outgoing data. - pipeline.addLast("messageBufferEventEncoder",messageBufferEventEncoder); - } - - @Override - public ChannelPipeline getPipeline() throws Exception - { - return pipeline; - } - - public void setUpstream(UDPUpstreamHandler upstream) - { - this.upstream = upstream; - } - - public MessageBufferEventDecoder getMessageBufferEventDecoder() - { - return messageBufferEventDecoder; - } - - public void setMessageBufferEventDecoder( - MessageBufferEventDecoder messageBufferEventDecoder) - { - this.messageBufferEventDecoder = messageBufferEventDecoder; - } - - public MessageBufferEventEncoder getMessageBufferEventEncoder() - { - return messageBufferEventEncoder; - } - - public void setMessageBufferEventEncoder( - MessageBufferEventEncoder messageBufferEventEncoder) - { - this.messageBufferEventEncoder = messageBufferEventEncoder; - } - - public UDPUpstreamHandler getUpstream() - { - return upstream; - } - -} diff --git a/jetserver/src/main/resources/jetserver/beans/netty-handlers.xml b/jetserver/src/main/resources/jetserver/beans/netty-handlers.xml deleted file mode 100644 index 584fc706..00000000 --- a/jetserver/src/main/resources/jetserver/beans/netty-handlers.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jetserver/src/main/resources/jetserver/beans/server-beans.xml b/jetserver/src/main/resources/jetserver/beans/server-beans.xml deleted file mode 100644 index 371c2765..00000000 --- a/jetserver/src/main/resources/jetserver/beans/server-beans.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jetserver/src/main/resources/jetserver/beans/server-protocols.xml b/jetserver/src/main/resources/jetserver/beans/server-protocols.xml deleted file mode 100644 index 2a5bb30c..00000000 --- a/jetserver/src/main/resources/jetserver/beans/server-protocols.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jetserver/src/main/resources/jetserver/beans/service-beans.xml b/jetserver/src/main/resources/jetserver/beans/service-beans.xml deleted file mode 100644 index 1dda923e..00000000 --- a/jetserver/src/main/resources/jetserver/beans/service-beans.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jetserver/src/main/resources/jetserver/props/jetserver.properties b/jetserver/src/main/resources/jetserver/props/jetserver.properties deleted file mode 100644 index 75422787..00000000 --- a/jetserver/src/main/resources/jetserver/props/jetserver.properties +++ /dev/null @@ -1,4 +0,0 @@ -flash.policy.port=843 -tcp.port=18090 -udp.port=18090 -reconnect.delay=300000 \ No newline at end of file diff --git a/jetserver/src/test/java/org/menacheri/jetserver/protocols/impl/AMF3StringProtocolTest.java b/jetserver/src/test/java/org/menacheri/jetserver/protocols/impl/AMF3StringProtocolTest.java deleted file mode 100644 index 369ac3c6..00000000 --- a/jetserver/src/test/java/org/menacheri/jetserver/protocols/impl/AMF3StringProtocolTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.menacheri.jetserver.protocols.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.handler.codec.base64.Base64Decoder; -import org.jboss.netty.handler.codec.base64.Base64Encoder; -import org.jboss.netty.handler.codec.embedder.DecoderEmbedder; -import org.jboss.netty.handler.codec.embedder.EncoderEmbedder; -import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; -import org.jboss.netty.handler.codec.frame.Delimiters; -import org.junit.Before; -import org.junit.Test; -import org.menacheri.jetserver.communication.NettyMessageBuffer; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.handlers.netty.AMF3ToJavaObjectDecoder; -import org.menacheri.jetserver.handlers.netty.JavaObjectToAMF3Encoder; -import org.menacheri.jetserver.handlers.netty.NulEncoder; -import org.menacheri.jetserver.protocols.impl.AMF3StringProtocol; - -public class AMF3StringProtocolTest { - - private AMF3StringProtocol amf3StringProtocol; - private DelimiterBasedFrameDecoder delimiterDecoder; - @Before - public void setUp() - { - amf3StringProtocol = new AMF3StringProtocol(); - amf3StringProtocol.setMaxFrameSize(1024); - delimiterDecoder = new DelimiterBasedFrameDecoder(amf3StringProtocol.getMaxFrameSize(), - Delimiters.nulDelimiter()); - amf3StringProtocol.setBase64Decoder(new Base64Decoder()); - amf3StringProtocol.setAmf3ToJavaObjectDecoder(new AMF3ToJavaObjectDecoder()); - amf3StringProtocol.setNulEncoder(new NulEncoder()); - amf3StringProtocol.setBase64Encoder(new Base64Encoder()); - amf3StringProtocol.setJavaObjectToAMF3Encoder(new JavaObjectToAMF3Encoder()); - } - - @Test - public void verifyAMF3StringEncodingAndDecoding() throws InterruptedException - { - DecoderEmbedder decoder = new DecoderEmbedder( - delimiterDecoder, amf3StringProtocol.getBase64Decoder(), - amf3StringProtocol.getAmf3ToJavaObjectDecoder()); - - EncoderEmbedder encoder = new EncoderEmbedder( - amf3StringProtocol.getNulEncoder(), - amf3StringProtocol.getBase64Encoder(), - amf3StringProtocol.getJavaObjectToAMF3Encoder()); - - NettyMessageBuffer payload = new NettyMessageBuffer(); - payload.writeStrings("user","pass","TestRoom1"); - - Event event = Events.event(payload, Events.LOG_IN); - encoder.offer(event); - ChannelBuffer encoded = encoder.peek(); - - Thread.sleep(10);// despite delay the timestamps should be same since we are decoding the whole object. - decoder.offer(encoded); - Event decoded = decoder.peek(); - assertEquals(decoded.getType(),Events.LOG_IN); - assertTrue("Timestamps should be same" ,decoded.getTimeStamp() == event.getTimeStamp()); - NettyMessageBuffer decodedPayload = (NettyMessageBuffer)decoded.getSource(); - // NettyMessageBuffer will not get de-serialized properly. - assertNull(decodedPayload.readString()); - } -} diff --git a/jetserver/src/test/java/org/menacheri/jetserver/protocols/impl/MessageBufferProtocolTest.java b/jetserver/src/test/java/org/menacheri/jetserver/protocols/impl/MessageBufferProtocolTest.java deleted file mode 100644 index 8eb92a8f..00000000 --- a/jetserver/src/test/java/org/menacheri/jetserver/protocols/impl/MessageBufferProtocolTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.menacheri.jetserver.protocols.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.handler.codec.embedder.DecoderEmbedder; -import org.jboss.netty.handler.codec.embedder.EncoderEmbedder; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; -import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; -import org.junit.Before; -import org.junit.Test; -import org.menacheri.jetserver.communication.NettyMessageBuffer; -import org.menacheri.jetserver.event.Events; -import org.menacheri.jetserver.event.Event; -import org.menacheri.jetserver.handlers.netty.MessageBufferEventDecoder; -import org.menacheri.jetserver.handlers.netty.MessageBufferEventEncoder; -import org.menacheri.jetserver.protocols.impl.MessageBufferProtocol; - -public class MessageBufferProtocolTest { - - private MessageBufferProtocol messageBufferProtocol; - private LengthFieldBasedFrameDecoder frameDecoder; - - @Before - public void setUp() - { - messageBufferProtocol = new MessageBufferProtocol(); - messageBufferProtocol.setLengthFieldPrepender(new LengthFieldPrepender(2, false)); - messageBufferProtocol.setMessageBufferEventDecoder(new MessageBufferEventDecoder()); - messageBufferProtocol.setMessageBufferEventEncoder(new MessageBufferEventEncoder()); - frameDecoder = messageBufferProtocol.createLengthBasedFrameDecoder(); - } - - @Test - public void verifyEventEncodingAndDecoding() throws InterruptedException - { - DecoderEmbedder decoder = new DecoderEmbedder( - frameDecoder, - messageBufferProtocol.getMessageBufferEventDecoder()); - EncoderEmbedder encoder = new EncoderEmbedder( - messageBufferProtocol.getLengthFieldPrepender(), - messageBufferProtocol.getMessageBufferEventEncoder()); - NettyMessageBuffer payload = new NettyMessageBuffer(); - payload.writeStrings("user","pass","TestRoom1"); - Event event = Events.event(payload, Events.LOG_IN); - encoder.offer(event); - ChannelBuffer encoded = encoder.peek(); - - Thread.sleep(100);// so that timestamps will differ. - decoder.offer(encoded); - Event decoded = decoder.peek(); - assertEquals(decoded.getType(),Events.LOG_IN); - assertFalse("Timestamps should not be same",decoded.getTimeStamp() == event.getTimeStamp()); - NettyMessageBuffer decodedPayload = (NettyMessageBuffer)decoded.getSource(); - assertEquals("user",decodedPayload.readString()); - assertEquals("pass",decodedPayload.readString()); - assertEquals("TestRoom1",decodedPayload.readString()); - } -} diff --git a/jetserver/src/test/java/org/menacheri/jetserver/util/SessionHandlerLatchCounter.java b/jetserver/src/test/java/org/menacheri/jetserver/util/SessionHandlerLatchCounter.java deleted file mode 100644 index 9acd07c6..00000000 --- a/jetserver/src/test/java/org/menacheri/jetserver/util/SessionHandlerLatchCounter.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.menacheri.jetserver.util; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicLong; - -import org.menacheri.jetserver.app.Session; -import org.menacheri.jetserver.event.NetworkEvent; -import org.menacheri.jetserver.event.impl.DefaultSessionEventHandler; - -public class SessionHandlerLatchCounter extends DefaultSessionEventHandler { - - private final AtomicLong counter; - private final CountDownLatch latch; - - public SessionHandlerLatchCounter(Session session, AtomicLong counter, - CountDownLatch latch) { - super(session); - this.counter = counter; - this.latch = latch; - } - - @Override - public void onNetworkMessage(NetworkEvent event) { - counter.incrementAndGet(); - latch.countDown(); - } - - public AtomicLong getCounter() { - return counter; - } - - public CountDownLatch getLatch() { - return latch; - } - -} diff --git a/jetclient-js/README.md b/nadclient-js/README.md similarity index 56% rename from jetclient-js/README.md rename to nadclient-js/README.md index 973c41f1..94f9ed39 100644 --- a/jetclient-js/README.md +++ b/nadclient-js/README.md @@ -1,15 +1,15 @@ -This is a **Javascript** client project for [jetserver](https://github.com/menacher/java-game-server/tree/master/jetserver) library. An example html which can connect to a locally running Jetserver is located at **test/jetclient.html**. +This is a **Javascript** client project for [Nadron](https://github.com/menacher/java-game-server/tree/netty4/nadron) library. An example html which can connect to a locally running Nadron is located at **test/nadclient.html**. About the Client ================ -Click on `Start War!` button after loading jetclient.html in a websocket compatible browser to start the game. Assumption is that Jetserver is running and jetclient.html is using accurate hostname and port number. +Click on `Start War!` button after loading jetclient.html in a websocket compatible browser to start the game. Assumption is that Nadron server is running and nadclient.html is using accurate hostname and port number. Usage as your own game client ============================= The general usage steps could be as outlined below. 1. Create a `config` object containing the `user`, `password` and `connectionkey` to connect to game room. If you are using a different protocol, then add the appropriate `CodeChain`'s also to the `config` object. By default `JSon` encoding/decoding is used. -2. Create a `session`(s) using the `SessionFactory` by passing in a `url` for the remote jetserver, `config` object and a `callback` function which will receive the `session` object after successful login to remote jeteserver. -3. Add necessary handlers to the session using `addHandler` function. The default events are provided the `jet` class for e.g `jet.lOG_IN`. At the very least you would want to add a handler for the `jet.SESSION_MESSAGE` event to receive incoming events from jetserver. +2. Create a `session`(s) using the `SessionFactory` by passing in a `url` for the remote Nadron server, `config` object and a `callback` function which will receive the `session` object after successful login to remote Nadron server. +3. Add necessary handlers to the session using `addHandler` function. The default events are provided the `nad` class for e.g `nad.lOG_IN`. At the very least you would want to add a handler for the `nad.SESSION_MESSAGE` event to receive incoming events from jetserver. 4. Event objects to be sent to server can be created using the `jet.nevent` function. 5. Data can be send to remote server using `session.send` function. diff --git a/jetclient-js/src/jet-0.1.js b/nadclient-js/src/nad-0.1.js similarity index 69% rename from jetclient-js/src/jet-0.1.js rename to nadclient-js/src/nad-0.1.js index d7be0b9c..7356aa2d 100644 --- a/jetclient-js/src/jet-0.1.js +++ b/nadclient-js/src/nad-0.1.js @@ -1,42 +1,42 @@ -(function (jet) { +(function (nad) { "use strict"; // Event code Constants - jet.ANY = 0x00; - jet.PROTOCOL_VERSION = 0x01; + nad.ANY = 0x00; + nad.PROTOCOL_VERSION = 0x01; - jet.CONNECT = 0x02; - jet.RECONNECT = 0x03; - jet.CONNECT_FAILED = 0x06; - jet.LOG_IN = 0x08; - jet.LOG_OUT = 0x0a; - jet.LOG_IN_SUCCESS = 0x0b; - jet.LOG_IN_FAILURE = 0x0c; - jet.LOG_OUT_SUCCESS = 0x0e; - jet.LOG_OUT_FAILURE = 0x0f; + nad.CONNECT = 0x02; + nad.RECONNECT = 0x03; + nad.CONNECT_FAILED = 0x06; + nad.LOG_IN = 0x08; + nad.LOG_OUT = 0x0a; + nad.LOG_IN_SUCCESS = 0x0b; + nad.LOG_IN_FAILURE = 0x0c; + nad.LOG_OUT_SUCCESS = 0x0e; + nad.LOG_OUT_FAILURE = 0x0f; - jet.GAME_LIST = 0x10; - jet.ROOM_LIST = 0x12; - jet.GAME_ROOM_JOIN = 0x14; - jet.GAME_ROOM_LEAVE = 0x16; - jet.GAME_ROOM_JOIN_SUCCESS = 0x18; - jet.GAME_ROOM_JOIN_FAILURE = 0x19; + nad.GAME_LIST = 0x10; + nad.ROOM_LIST = 0x12; + nad.GAME_ROOM_JOIN = 0x14; + nad.GAME_ROOM_LEAVE = 0x16; + nad.GAME_ROOM_JOIN_SUCCESS = 0x18; + nad.GAME_ROOM_JOIN_FAILURE = 0x19; //Event sent from server to client to start message sending from client to server. - jet.START = 0x1a; + nad.START = 0x1a; // Event sent from server to client to stop messages from being sent to server. - jet.STOP = 0x1b; + nad.STOP = 0x1b; // Incoming data from server or from another session. - jet.SESSION_MESSAGE = 0x1c; + nad.SESSION_MESSAGE = 0x1c; // This event is used to send data from the current machine to remote server - jet.NETWORK_MESSAGE = 0x1d; - jet.CHANGE_ATTRIBUTE = 0x20; - jet.DISCONNECT = 0x22;// Use this one for handling close event of ws. - jet.EXCEPTION = 0x24; + nad.NETWORK_MESSAGE = 0x1d; + nad.CHANGE_ATTRIBUTE = 0x20; + nad.DISCONNECT = 0x22;// Use this one for handling close event of ws. + nad.EXCEPTION = 0x24; // Functions // Creates a new event object - jet.NEvent = function (eventType, payload, session, date) { + nad.NEvent = function (eventType, payload, session, date) { return { type : eventType, source : payload, @@ -45,17 +45,26 @@ }; }; - // Creates a login event object to login to remote jetserver - jet.LoginEvent = function (config) { - return jet.NEvent(jet.LOG_IN, [config.user, config.pass, config.connectionKey]); + //Special event creation function to send the json class name to Nadron server. + nad.CNameEvent = function (className) { + return { + type : nad.NETWORK_MESSAGE, + cName : className, + timeStamp : new Date().getTime() + }; + }; + + // Creates a login event object to login to remote Nadron server + nad.LoginEvent = function (config) { + return nad.NEvent(nad.LOG_IN, [config.user, config.pass, config.connectionKey]); }; // If using a differnt protocol, then use this codec chain, to decode and encode incoming and outgoing requests. Something like a Chain of Responsibility pattern. - jet.CodecChain = function () { + nad.CodecChain = function () { this.chain = []; }; - jet.CodecChain.prototype.add = function (func) { + nad.CodecChain.prototype.add = function (func) { if (func && typeof (func) === 'function') { this.chain.push(func); } else { @@ -64,11 +73,11 @@ return this; }; - jet.CodecChain.prototype.remove = function (func) { + nad.CodecChain.prototype.remove = function (func) { removeFromArray(this.chain, func); }; - jet.CodecChain.prototype.tranform = function (message) { + nad.CodecChain.prototype.tranform = function (message) { var i = 0; for(;i + + + + Simple Canvas Game + + + + + + + + \ No newline at end of file diff --git a/nadclient-js/test/images/background.png b/nadclient-js/test/images/background.png new file mode 100644 index 00000000..eaeb8878 Binary files /dev/null and b/nadclient-js/test/images/background.png differ diff --git a/nadclient-js/test/images/hero.png b/nadclient-js/test/images/hero.png new file mode 100644 index 00000000..3cc1bd38 Binary files /dev/null and b/nadclient-js/test/images/hero.png differ diff --git a/nadclient-js/test/images/hero2.png b/nadclient-js/test/images/hero2.png new file mode 100644 index 00000000..c7eb7202 Binary files /dev/null and b/nadclient-js/test/images/hero2.png differ diff --git a/nadclient-js/test/images/monster.png b/nadclient-js/test/images/monster.png new file mode 100644 index 00000000..ef7cc0de Binary files /dev/null and b/nadclient-js/test/images/monster.png differ diff --git a/jetclient-js/test/jetclient.html b/nadclient-js/test/nadclient.html similarity index 77% rename from jetclient-js/test/jetclient.html rename to nadclient-js/test/nadclient.html index 0dd4827c..6949e8f1 100644 --- a/jetclient-js/test/jetclient.html +++ b/nadclient-js/test/nadclient.html @@ -1,7 +1,7 @@ - +