{"id":22615616,"url":"https://github.com/marcellodesales/myeye-game-tcp-client-server","last_synced_at":"2025-03-29T00:42:35.694Z","repository":{"id":142072865,"uuid":"59702528","full_name":"marcellodesales/myeye-game-tcp-client-server","owner":"marcellodesales","description":"Implementation of a Game server using TCP protocol","archived":false,"fork":false,"pushed_at":"2016-05-25T22:41:05.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-03T10:46:22.694Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcellodesales.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-25T22:40:44.000Z","updated_at":"2016-05-25T22:41:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"e7499c1d-1d8d-4d5a-978b-702f43fc8d47","html_url":"https://github.com/marcellodesales/myeye-game-tcp-client-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Fmyeye-game-tcp-client-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Fmyeye-game-tcp-client-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Fmyeye-game-tcp-client-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcellodesales%2Fmyeye-game-tcp-client-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcellodesales","download_url":"https://codeload.github.com/marcellodesales/myeye-game-tcp-client-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246122247,"owners_count":20726822,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-08T19:08:30.352Z","updated_at":"2025-03-29T00:42:35.687Z","avatar_url":"https://github.com/marcellodesales.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Myeye Game Server\n\nA simple game server using TCP protocols.\n\n* Implementation by Marcello de Sales (marcello.desales@gmail.com).\n\n# Building \n\nI have developed the server-side considering the requirements. I have used Gradle as the build system (http://www.gradle.org) if you need to rebuild the jar or run the JUnit test cases from the console. However, the jars must be provided in this zip under \"build/libs\" in this revision.\n\n\"gradle clean\" - cleans the binary (before running test cases)\n\"gradle jar\" - generates jar\n\"gradle test\" - run the test cases\n\"gradle dependencies\" - verifies dependencies\n\"gradle runServer\" - runs the server\n\"gradle eclise\" - generates the Eclipse artifacts (.project and .classpath).\n...\n\nCopy the dependency to Google Guava \ncp /home/marcello/.gradle/caches/artifacts-4/com.google.guava/guava/c12498cf18507aa6433a94eb7d3e77d5/jars/guava-10.0.1.jar build/libs/\n\n# Design\n\nGiven that, an immutable POJO was designed to hold the data of messages. Since the data types can be mapped directly to the Java primitive types, it was simple to produce the \"marshaling\" of a given instance with the types using the Java NIO API.\n\n- Version (1 byte) -\u003e Java Byte (8 bit integer)\n- Message Type (2 byte integer) -\u003e Java Short (16 bit integer)\n- User ID (4 byte integer) -\u003e Java Integer (32 bit integer)\n- Payload (variable length ASCII string) (unbound-length String)\n\nThe POJO was named GameMessage and is composed by those properties. In order to simplify data input, I have wrapped Message Type and Version into 2 other Enum types: MessageType and MessageVersion. Although the semantics might be incorrect, I considered Message Type the type a messages during the game (INITIALIZE_GAME, PAUSE_GAME...) that carries a default payload, whereas a customized message (ACTION) that could be used for carrying custom payload ASCII messages. However, protocols can be developed with those as well as usual.\n\nThe class GameMessageService is a class that provides the Factory methods for new instances of the related class, as well as the methods to marshal and unmarshal messages. This class is Unit-tested to assure that the marshal/unmarshal will work propertly.\n\nThe Server-side was implemented using a multi-threaded approach with a Thread-pool of size 50. This can handle a good number of requests of messages to be logged. Each client request is handled by an instance of the class GameMessageRequestHandler, which is responsible for receiving the bytes of binary message transmitted by the client, unmarshal the message instance and send the received message to the GameMessageLogger. All client request handlers will concurrently add new GameMessage instances to the Blocking Queue of this single thread.\n\nThere would be a lot of changes to handle specific corner cases, specifically related to the size of the payload (as I don't have knowledge of that, I'm using 4K).\n\nThe Client-side was implemented to exercise the server-side. A state-machine was created to add some knowledge about what messages can be transmitted to the server (again, this is my own assumption :D). The same GameMessageService is used here to marshal the message instance. Other adaptations of the client would depend on specific requirements.\n\n# Running the Client\n\nTo Run the solution\n- First unzip the contents of the zip file to \"DIR\".\n\n*************************************** Running the server:\n1. cd to \"DIR\"\n2. Start the server\n\nmarcello@oahu:/development/workspaces/open-source/myeye$ ./startServer \nMYEYE Game Server running, waiting connections on 192.168.190.138:2020\nDeveloped by Marcello de Sales (marcello.desales@gmail.com)\n\n*************************************** Running The client\n1. cd to \"DIR\"\n2. Start the client\n\nmarcello@oahu:/development/workspaces/open-source/myeye$ ./startClient \nMYEYE Game Client running, will connect to 192.168.190.138:2020\nDeveloped by Marcello de Sales (marcello.desales@gmail.com)\n\n##### Game Session Information ####\nYour User ID is '1401523655'\n\n### Game versions ###\nONE(1)\nTWO(2)\n-\u003e What version would you like to play?\n\nThe values displayed on the options are needed to be entered by the user. Note that there's NO validation on those!!! :) Here's a Client session...\n\n### Game versions ###\nONE(1)\nTWO(2)\n-\u003e What version would you like to play? 1\n\n##### Sending Message #####\nSending GameMessage{Message Version=ONE(1), Message Type=INITIALIZE_GAME(8), UserID=1401523655, Payload=INITIALIZE_GAME at Thu Dec 01 18:46:23 PST 2011}\nBINARY: [1, 0, 8, 83, -119, -115, -57, 73, 78, 73, 84, 73, 65, 76, 73, 90, 69, 95, 71, 65, 77, 69, 32, 97, 116, 32, 84, 104, 117, 32, 68, 101, 99, 32, 48, 49, 32, 49, 56, 58, 52, 54, 58, 50, 51, 32, 80, 83, 84, 32, 50, 48, 49, 49]\nSent!\n\n\n##### Game Options ####\nACTION(16)\nPAUSE_GAME(64)\nTERMINATE_GAME(128)\n-\u003e What do you want to do? 128\n\n##### Sending Message #####\nSending GameMessage{Message Version=ONE(1), Message Type=TERMINATE_GAME(128), UserID=1401523655, Payload=TERMINATE_GAME at Thu Dec 01 18:46:39 PST 2011}\nBINARY: [1, 0, -128, 83, -119, -115, -57, 84, 69, 82, 77, 73, 78, 65, 84, 69, 95, 71, 65, 77, 69, 32, 97, 116, 32, 84, 104, 117, 32, 68, 101, 99, 32, 48, 49, 32, 49, 56, 58, 52, 54, 58, 51, 57, 32, 80, 83, 84, 32, 50, 48, 49, 49]\nSent!\n\n\nGame terminated! Good bye!\n\n# Running the Server\n\n===================== SERVER SIDE ============================================\n\nmarcello@oahu:/development/workspaces/open-source/myeye$ ./startServer \nMYEYE Game Server running, waiting connections on 192.168.190.138:2020\nDeveloped by Marcello de Sales (marcello.desales@gmail.com)\n\nThread Pool [ 50 , 50 ]\nThe Largest Pool size: 2\n# of active threads: 1\n# of maximum pool size:50\nHandling client request Client [/192.168.190.138:59028]\nLogging message from Logger Thread\nLogged request of Client [/192.168.190.138:59028] in 55 ms\nGameMessage{Message Version=TWO(2), Message Type=INITIALIZE_GAME(8), UserID=1533448286, Payload=INITIALIZE_GAME at Thu Dec 01 18:41:04 PST 2011}\n\nThread Pool [ 50 , 50 ]\nThe Largest Pool size: 3\n# of active threads: 1\n# of maximum pool size:50\nHandling client request Client [/192.168.190.138:59029]\nLogging message from Logger Thread\nLogged request of Client [/192.168.190.138:59029] in 44 ms\nGameMessage{Message Version=TWO(2), Message Type=ACTION(16), UserID=1533448286, Payload=Super crazy}\n\nThread Pool [ 50 , 50 ]\nThe Largest Pool size: 4\n# of active threads: 1\n# of maximum pool size:50\nHandling client request Client [/192.168.190.138:59030]\nLogging message from Logger Thread\nLogged request of Client [/192.168.190.138:59030] in 32 ms\nGameMessage{Message Version=TWO(2), Message Type=PAUSE_GAME(64), UserID=1533448286, Payload=PAUSE_GAME at Thu Dec 01 18:41:23 PST 2011}\n\nThread Pool [ 50 , 50 ]\nThe Largest Pool size: 5\n# of active threads: 1\n# of maximum pool size:50\nHandling client request Client [/192.168.190.138:59031]\nLogging message from Logger Thread\nLogged request of Client [/192.168.190.138:59031] in 50 ms\nGameMessage{Message Version=TWO(2), Message Type=TERMINATE_GAME(128), UserID=1533448286, Payload=TERMINATE_GAME at Thu Dec 01 18:41:28 PST 2011}\n\n^Cmarcello@oahu:/development/workspaces/open-source/myeye$ ^C\nmarcello@oahu:/development/workspaces/open-source/myeye$ ./startServer \nMYEYE Game Server running, waiting connections on 192.168.190.138:2020\nDeveloped by Marcello de Sales (marcello.desales@gmail.com)\n\nThread Pool [ 50 , 50 ]\nThe Largest Pool size: 2\n# of active threads: 1\n# of maximum pool size:50\nHandling client request Client [/192.168.190.138:59072]\nLogging message from Logger Thread\nLogged request of Client [/192.168.190.138:59072] in 66 ms\nGameMessage{Message Version=ONE(1), Message Type=INITIALIZE_GAME(8), UserID=1401523655, Payload=INITIALIZE_GAME at Thu Dec 01 18:46:23 PST 2011}\n\nThread Pool [ 50 , 50 ]\nThe Largest Pool size: 3\n# of active threads: 1\n# of maximum pool size:50\nHandling client request Client [/192.168.190.138:59073]\nLogging message from Logger Thread\nLogged request of Client [/192.168.190.138:59073] in 54 ms\nGameMessage{Message Version=ONE(1), Message Type=TERMINATE_GAME(128), UserID=1401523655, Payload=TERMINATE_GAME at Thu Dec 01 18:46:39 PST 2011}\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcellodesales%2Fmyeye-game-tcp-client-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcellodesales%2Fmyeye-game-tcp-client-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcellodesales%2Fmyeye-game-tcp-client-server/lists"}