Notifications
Article
Tutorial: Creating an Emote system using Unity & AWS
Updated a month ago
3.6 K
0
A Tutorial on Unity and Amazon Web Services
Networking seems to be a daunting topic, maybe it shouldn't be. In this article I will walk you through the basics of networking and how to create a simple one-on-one in-game communication system in Unity that uses an Amazon Web Services (AWS) EC2 server. Think of a game such as hearthstone,
But before we start, let's go through the basics. What is AWS? How does networking work? Where do I start?
If you have any questions or would like me to personally walk you through any part of this tutorial, feel free to ping me on twitter: @galal_mounir, or book some one-on-one time with me on Unity Live Help.

Networking Basics

Networking, in its simplest form, is simply connecting two or more machines together and sending information back and forth. To better understand how it works, let's assume Alice wants to tell Bob something. She has two options, either go to Bob and tell him directly (Client to Client), or tell Carol to pass the message to Bob (Client to Server to Client). Now let's assume that there are 10 different participants in the room and Alice wants to tell Bob something, while Dave wants to tell Erin something different, and Frank wants to broadcast something entirely unrelated to all participants. Things can get very messy and loud with even more participants. In such case, a Client to Client system (topology) would not be suitable. Instead, a centralized coordinated topology must be in place. Hence, Carol acts as the centralized entity, receiving messages from all participants in the room, and forwarding the messages to the correct destinations. In this example, Carol becomes the Server, with all the other participants being Clients. In some cases, Carol can also act as a client (if she wants to tell a participant something), making her a Client and a Server (Host). In networked games, the first person to create/join a room is usually also the Host.
If you have any questions or would like me to personally walk you through any part of this tutorial, feel free to ping me on twitter: @galal_mounir, or book some one-on-one time with me on Unity Live Help.
Now that we got the basics behind us, let's take a look under the hood and dig deeper into how everything works.

How to Create a Carol (Server)

First, let's identify the roles of Carol:
  • Create a room in which participants can join
  • Continuously listen for new participants wanting to join
  • Continuously listen for incoming messages
  • Forward the messages to the correct destinations
  • Perform some logic (optional)
Let's dig into each one of those roles and identify how it can be implemented. First, Carol needs to create a room so that Alice and Bob can join and start communicating/playing. To achieve such functionality, Carol needs to have an address for the room (Server Address). Once a participant joins, Carol needs to setup a unique direct connection/link with each one (Socket Connection). There are numerous ways to implement a socket server, however, for this tutorial we will be using Socket.IO.
Before we start implementing Socket.IO, we have two options:
  1. Use our local development machine to host the Socket.IO server.
  2. Setup a remote server to host our Socket.IO server.
Both options are feasible and cost next to nothing to implement, however, each has their pros and cons. Assuming you will use your local machine to host a server, you will need to maintain the server yourself, open up ports on your router (if you want your server to be available online), maintain a static IP address, and keep your machine running 24/7. On the other hand, setting up a remote server removes all of these burdens while costing you as low as a couple of bucks a month. You can use a cloud service such as Amazon's AWS, Google Cloud, or Microsoft's Azure.
To start creating a server you need to create an account on https://aws.amazon.com/. Once the account is created and you're signed in, you should be able to see the region in which your workspace is located on the top right. Based on your geographical location, you can switch to the closest region. Afterwards, you should be able to see a list of services in the tab on the top left, choose EC2, and click on "Launch Instance". The first step to creating your cloud server is to choose an image (Operating System) to run on the server. A standard option (free as well) is the "Amazon Linux 2 AMI (HVM), SSD Volume Type". Choose that image and then click you can click on "Review and Launch" or you can further customize your settings. Once you're ready, click launch and you will be greeted with a pop up asking to "Select an existing key pair or create a new key pair". Since this is your first time creating a key pair, choose "Create a new key pair", choose a proper name and click "Download Key" button. This downloads a key file to your machine, we will use this file to remotely access the server. KEEP THIS FILE SAFE!!!. There's no way to retrieve this file if you lose it, and you will LOSE access to the remote server. I cannot stress this enough. DO NOT LOSE THIS FILE. Once you download the file, click on the "Launch Instances" button.
Now the fun part starts, to connect to your new server you can either connect remotely using an SSH client, or user Amazon's browser-based SSH. If you opt-in for using an SSH client, on Windows you need to use an application such as Putty. On Mac, you can use the standard Terminal (available with the MacOS installation). For a cross platform solution, I use Termius, you can use it on Windows, Mac, Linux, iOS, and Android. Whichever program you use, you will need to use the .pem file we downloaded earlier. For now, let's connect using Amazon's web-based SSH, click on the "Connect" button in the "Instances" dashboard, then choose "EC2 Instance Connect", and click "Connect".
Once you connect, you will be greeted with a black screen with white text, very reminiscent of the command-line days before Windows and Mac were a thing. This screen is where we will spend most of our time getting the server up and ready. (Disclaimer: One of the issues with the online SSH is that it sometimes stops responding if it is left unattended for some time.)
To start creating our Socket.IO server, we need to choose a language to use. Socket.IO was originally created for JavaScript, so using NodeJS is a natural option for many developers, therefore, you can find multiple tutorials online walking you through how to setup a NodeJS Socket.IO server. For the sake of completeness, I will show you how to quickly set one up. If this is your first time using Linux, let's go through some of the most common commands we will be using.

Linux Commands Cheat Sheet

  • ls (list) lists the files and folders in the current active directory
ls #lists the files and folders in the current directory
ls /usr/ #lists the files and folders inside the "usr" directory
  • cd (change directory) changes the current active directory to a different one
cd .. #Changes the current active directory one level up
cd ./ #Changes the current active directory to the root directory
  • mkdir (make directory) creates a new folder in the currently active directory
mkdir TestFolder #Creates a new folder called "TestFolder"
  • curl (client URL) used to access a specific web link and download a file
curl https://www.google.com #Opens Google and prints the pure reply from the server
  • sudo (super user do) used to run a specific command with admin privileges
sudo mkdir TestFolder #Creates a new folder called "TestFolder" as admin
  • yum (Yellowdog Updater, Modified) used to download and install applications on a linux machine
yum -y install nodejs #installs nodejs
  • npm (Node Package Manager) used to download and install packages for NodeJS
npm install socket.io
  • nano is a text editor used in linux to create/modify text files
nano server.js

Getting Started with NodeJS

First, let's install NodeJS on our new server, run the following two commands to download and install NodeJS.
curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - sudo yum -y install nodejs
Next, we need to create a project folder and start writing some code. Run the following commands to create a new folder called "MyNewServer" in the default directory then change the active directory to the new one. (Hot Tip: when typing in linux, press the "tab" key on your keyboard to autocomplete what you are typing).
mkdir MyNewServer cd MyNewServer
Now that we are inside our new folder, let's start creating our actual server and run it. The first thing we need to do is install Socket.IO. Run the following command to download Socket.IO and create our project dependencies and modules.
npm install --save socket.io
Now that the project is setup and the dependencies are ready, let's create a new JavaScript file and start coding our first server. Run the following command to create a new file called "server.js" and open a text editor to start typing.
nano server.js
Once the text editor is open, let's code in a simple HTTP server that listens on port 12345 and replies with a simple message "I am Alive!". Paste in the following code in the editor then save and exit by pressing Ctrl+X and then Y.
var app = require('http').createServer(handler) var io = require('socket.io')(app); app.listen(12345); console.log("Server up and ready!"); function handler (req, res){ res.writeHead(200); res.end("I am Alive!"); }
Now, that you are back to the console view, run the following command to start the server. You should see a message printed on the screen saying Server up and ready!. You can now go to a browser, put in the link to your server and see your browser say I am Alive!. However, there are a couple of things we need, for starters, what the is the link to the server and how do you find it?
node server.js
To find the server address go back to the EC2 console, click on the running instance, and look for the IPv4 Public IP. This is your server address, copy and paste it into a browser window and.... Nothing happens. There are two reasons for this:
  1. You need to specify the port in you address.
  2. You need to let your server accept incoming connections on this port.
To solve the first one, simple append :12345 to the server address in your browser, it should look something like this: http://18.191.141.15:12345.
Solving the second one is not as straight forward unfortunately. However, it is fairly simple. All you need to do is head back to the EC2 console, from the left navigation bar under NETWORK & SECURITY click on Security Groups. Next, select the security group being used by your server (most probably the only one in there), and in the bottom click on Inbound, then Edit. From here, you need to click on the Add Rule button and add a custom TCP rule with a port range of 12345. And give it a description, in my example I named it MyNewServer. Click save, and go back to your browser and try pasting the server link (with the port number included). Now you should be able to see a message saying I am Alive!.
Congratulations on reaching this stage! you have now successfully hosted a server that can be accessed anywhere in the world! Now let's move on to implementing the Socket.IO part.
What we have so far is a web server, however, we need a socket server. Socket.IO creates sockets between the server and the client. The socket is a constant connection between both machines that remains active until one disconnects. Having a socket is useful in many ways, most importantly, being able to message the client back when a certain event happens.
The first step is to detect when a client connects, run the text editor again to modify the server.js file using the following command.
nano server.js
Then add in the following code and save and exit by pressing Ctrl+X then Y.
io.on('connection', function (socket) { console.log("New Client Connected!"); });
This function gets triggered every time a socket client connects to the socket server.
Now try running the server again using the following command.
node server.js
Testing the connection now is not as straight forward as before. It requires a Socket.IO client to connect rather than a web client. For this reason we will use a tool called Socket.IO Tester. Once you download, install and run Socket.IO Tester, you should be able to add in the server address and click connect. This time, you need to append the server address with /socket.io, effectively making your address look something like this: http://18.191.141.15:12345/socket.io
Once the Socket.IO Tester connects (turns green), your server should print a message saying New Client Connected!
Now, that we tested our server and are sure everything is setup correctly, let's start adding some cool functionalities to our server. Let's start by listening on a certain event from the client and printing the message received to the console screen. To do this, we need to add the following code inside our function:
socket.on('player message event', function (data) { console.log(data); });
This function gets triggered when the connected client on the socket sends an event called player message event and passes in some data. The function then prints the data to the console. We can also make the server forward this message to all the connected clients using an emit call as follows:
socket.broadcast.emit('player message event', data);
Using the broadcast option sends a message with the event name player message event from the server to all the connected clients. Using the socket instead of io will send this message to everyone except the socket in question. That way we can make the server forward a message from client A to client B without sending the message back to client A.
So now our full Socket.IO function looks like this:
io.on('connection', function (socket) { console.log("New Client Connected!"); socket.on('player message event', function (data) { console.log(data); socket.broadcast.emit('player message event', data); }); });
Testing the server is now simple since we are using the Socket.IO Tester. Simply create two tabs one for each client, and connect to the server. You should see the message New Client Connected! printed twice. Now, to test the events, there are two things we need to do. First, we need to listen to an event, to do that, add the event name (player message event) under the Listen for events area and click Add event. Your client is now listening to the event. On the other client, add the event name (player message event) under the Send message area, add the string "Hello from the other side!" and click the send message button. Two things should now happen, first, the server should log the message received Hello from the other side!, and the first client should receive the event with the message Hello from the other side!














If you reached this far, congratulations! you officially have a Socket.IO server that is ready for in-game communication! Of course, this is a very simple server, there are plenty of things we can do to improve this implementation. For starters, we can implement client identification, use separate rooms for different games, implement user login, etc.
If you have any questions or would like me to personally walk you through any part of this tutorial, feel free to ping me on twitter: @galal_mounir, or book some one-on-one time with me on Unity Live Help.
Now, let's move on to the Unity part of it all!

How to Create a Alice/Bob (Client)

Coming Soon!
Galal Hassan
Software Engineer - Producer
9
Comments