I have been working for the past several years on a simple UDP packet server that I plan to use for a hobbyist video game. I originally wrote the server in C++ using standard sockets with UDP. (my last version of which can be seen here)
My C++ architecture was basically the following:
- UDP Packets containing serialized game data that were decoded based on an opcode.
- One blocking collector thread dedicated to pulling packets directly from the socket, and then passing the packet to a worker thread for handling.
- [X] Worker threads that check the packet opcode, cast the packet to the corresponding packet type, and then call a handler function based on the type.
This seems to me like a very standard starting point for developing a server achitecture, and it seemed to work fairly well. After a while I got a little tired of the growing complexity of my code and wondered if there is a better language that I could be using for developing the server. This led me to Go, and I became interested in learning the language and trying to build my server with it.
I have basically gotten the new version of the server (seen here) up to the same level of functionality that my C++ server had, and I am reaching a few pivotal design decisions that I want some experienced advice on:
Currently my server is basically a clone of what I was doing in C++:
- I have almost identical packet types for the same purpose.
- One collector goroutine that simply waits for packets on the socket, and places them into a go chan.
- [X] handler goroutines that wait for a packet to arrive on the chan and handle them according to their packet type.
Is the right way to do it in Go? I am still learning the intricacies of goroutines and haven’t even set up mutexes/semaphores for the database etc… I’m hoping some advice here will point me in the right direction before I get to far into this architecture.
That being said, it is functional, and I might be already following good design! I look forward to your responses.