A Relay Server based on WebSockets for Online Games made with Unity Personal

As described in my previous post Unity makes it pretty hard for hobby developers to develop their own online games. It is impossible to run a game server created with Unity on an Amazon AWS instance due to the missing batchmode option. As a workaround I implemented a relay server for my current project which is based on WebSockets and allows me to run my own server at home, combined with the benefits of a server in the cloud with a fixed IP address.

The Amazon Cloud (AWS) is ideal for testing your own online game with only a few players. An instance in the “Elastic Compute Cloud” (ec2) is free of charge for a whole year and runs with different operating systems such as Ubuntu or Windows Server 2012. Using such an instance to run a game server would bypass any problems with NAT punchthrough, i.e., port forwarding to access computers behind a home router. This is the primary source of problems if you want to run a server at home.

Unfortunately, these server instances have a serious drawback: they have no graphics cards which means that programs created with Unity cannot be executed. A remedy would be the batchmode option of Unity, but this is an exclusive feature of the Pro version. An alternative is offered by the new Unity Internet Services.  These offer a lobby and a relay server, connecting players in a multiplayer game who then take the server part themselves. However, this service is  free of charge only in the current beta stage and can only now be used by users with a personal license. It is uncertain what costs will arise after this beta period.

With these limitations in mind I have chosen a different solution, a relay server which runs on my ec2 instance, where game server as well as the player clients connect to. The WebSocket protocol has the distinct advantage of using HTTP or HTTPS ports 80 or 443, respectively, which are enabled by default on all home routers and mobile devices. After all, everyone wants to view web pages in his browser. This eliminates at least the problem of NAT punchthrough.

What exactly does this relay server? It receives a connection request from a game server which runs, e.g., at my place. It opens a new session where it stores the connection data and waits for requests from player clients. When a client connects to the relay server, this is communicated to the game server. Game server as well as client now send their RPCs to the relay server which forwards the messages to their respective destinations. This, of course, was the point where the implementation got time-consuming since the RPC and synchronization methods of the Unity network layer could no longer be used. Instead, I had to reimplement the RPC functionality myself.

An implementation of the WebSocket protocol in C# is websocket-sharp which can be downloaded from GitHub. The corresponding DLL is easily compiled and integrated into your own Unity project using Visual Studio. Just move the compiled DLL to the plugins directory in your assets folder. The examples included in websocket-sharp are excellent starting points for realising your own relay server.

Two things have to be noted:

  1. Websocket-sharp uses the socket implementation in the System.Net.Sockets namespace which is blocked on mobile devices by Unity 4.x unless you own a Pro license. The easiest solution, of course, is to switch to Unity 5.x. If this is not an option you can take a look at the asset package Good ol’ Sockets which reimplements the socket functionality for Unity. I haven’t tried it myself, I rather chose the easier way and updated my project to Unity 5.0.
  2. WebSockets are an extension of the HTTP protocol. Unfortunately, not every proxy server on the internet understands this extension as described in this post by Robert Hekkers. This is probably still the case for some mobile providers so that the WebSocket solution may not work on all Smartphones. The solution generally proposed is to use port 443 instead of port 80, even if you are not using encryption, because there is usually no proxy in-between. This is supported by websocket-sharp.

If you intend to develop a multiplayer online game for mobile devices without any budget the approach described above is certainly an option. I hope that I will find the time to bring my relay server into a presentable form so that I can publish it here soon. If you are interested I would appreciate some feedback. It would certainly increase my motivation.

Leave a Reply