[TIP] Sending UDP requests to AWS Server


Hi there 🙂

In this quick tip I’ll show how to send a udp request to your Amazon EC2 server instance and then receive a reply from there. Simply put, you can use this to check if your AWS servers are online or not when player is logging in.

So what are we covering today? Well, we will write a simple UDP server in Node.js and run it on AWS EC2 server. This server will be listening on EC2’s IP on a specific port. Then in Unreal Engine 4, we will use the FUDPPing::UDPEcho method to ping the above server ip and port and see if we get a reply. Let’s get started.

Part 1 – Amazon EC2

Before we continue I assume you already have an EC2 instance running with Node.js installed. You don’t require any additional IDE to write our UDP server but if possible I highly suggest downloading and installing Sublime Text (literally you will fall in love with that text editor).

Ok, so here is the UDP server code.

NOTE: Make sure the port you are using is open in Firewall (inbound and outbound) and in EC2 security group. Otherwise you might face connection issues.

PS: If you have trouble copying the below code then get it from GitHub: https://gist.github.com/ryanjon2040/f29787b866316357016971b9c9c363bb


// port to listen to
var PORT = xxxxx; // Change to your port number

// Host will be your private DNS
var HOST = 'ip-xxx-xx-xx-xxx.your-region.compute.internal';

// Load datagram module
var dgram = require('dgram');

// Create a new instance of dgram socket
var server = dgram.createSocket('udp4');

/**
Once the server is created and binded, some events are automatically created.
We just bind our custom functions to those events so we can do whatever we want.
*/

// Listening event. This event will tell the server to listen on the given address.
server.on('listening', function () {
    var address = server.address();
    console.log('UDP Server listening on ' + address.address + ":" + address.port);
});

// Message event. This event is automatically executed when this server receives a new message
// That means, when we use FUDPPing::UDPEcho in Unreal Engine 4 this event will trigger.
server.on('message', function (message, remote) {
    console.log('Message received from ' + remote.address + ':' + remote.port +' - ' + message.toString());
    server.send(message, 0, message.length, remote.port, remote.address, function(err, bytes) {
	  if (err) throw err;
	  console.log('UDP message sent to ' + remote.address +':'+ remote.port + '\n');
	});
});

// Error event. Something bad happened. Prints out error stack and closes the server.
server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`);
  server.close();
});

// Finally bind our server to the given port and host so that listening event starts happening.
server.bind(PORT, HOST);

Save this file as *.js (e.g: My UDP Server.js) to any location (for the sake of this tip let’s save it to Desktop).

Q: Where to look for Private DNS server and Public IP?

A: Select your instance from your AWS EC2 console and under description
you can get your private DNS server name and public ip (we will use this later in UE4).


Now open your notepad and type the below code and save it as a *.bat file.

@echo off
start node "C:\Users\Administrator\Desktop\My UDP Server.js"

If you have node.js properly installed and the above file exists then you should see a window like this.

Congrats! You now have your own UDP server listening for messages. 🙂

Part 2 – Unreal Engine 4:

Now let’s start writing our C++ code that pings the above UDP server. Before we begin lets make sure we have our necessary dependencies, so let’s open YourProjectName.Build.cs file found in your ProjectName/Source/ProjectName folder. Inside that file add the below line if it’s not there.

PrivateDependencyModuleNames.AddRange(new string[] { "Http", "Icmp" });
NOTE: The HTTP may not be required for your project but I just included it anyway.

For my project I put all the online related stuff (checking for servers, player login, matchmaking etc.) in GameInstance class since its persistent as long as the game is running. For this tip, I’ll be using custom game instance class.

To create a new game instance class, start your Unreal Project and add a new Game Instance class.

Once the class has been added lets add our “server checking” method. Add the below code to your header file:

NOTE: If you have trouble copying below code then get it from Github: https://gist.github.com/ryanjon2040/5ff19a50b9c25ad5713abbf369d7b247

#include "Icmp.h"

/* Delegate to bind our custom function when we receive a reply from our EC2 UDP server */
FIcmpEchoResultDelegate PingReult;

/* Sends a UDP echo to the given server and waits for a reply */
UFUNCTION(BlueprintCallable)
void CheckIfServerIsOnline(FString ServerPublicIP, FString ServerPort);

/* Delegate called when we get a reply from our EC2 UDP server */
void OnServerCheckFinished(FIcmpEchoResult Result);

Once our declarations are added lets create the definitions in source (.cpp). Open your custom game instance class cpp file and add the definitions:

NOTE: If you have trouble copying below code then get it from Github: https://gist.github.com/ryanjon2040/21cbb0397f7ea520d23bd0ce66109a39


void UYourGameInstance::CheckIfServerIsOnline(FString ServerPublicIP, FString ServerPort)
{
	/* First bind our OnServerCheckFinished function to PingResult.
	* When we get any reply from UDP server PingResult will be called
	* and when PingResult is called the binded method (OnServerCheckFinished) is also called. */
	PingReult.BindUObject(this, &UYourGameInstance::OnServerCheckFinished);

	/* Our UDP server public ip and port we have to ping.
	* Port should be the exact same port we defined on UDP server node.js file on EC2 server */
	const FString Address = FString::Printf(TEXT("%s:%d"), *ServerPublicIP, ServerPort);

	// Finally just ping.
	FUDPPing::UDPEcho(Address, 5.f, PingReult);
}

void UYourGameInstance::OnServerCheckFinished(FIcmpEchoResult Result)
{
	// Unbind the function. Its no longer required.
	PingReult.Unbind();

	// Simply set a status.
	FString PingStatus = "Ping Failed";

	// Do your stuff based on the result.
	switch (Result.Status)
	{
		case EIcmpResponseStatus::Success:
			PingStatus = "Success";
			break;
		case EIcmpResponseStatus::Timeout:
			PingStatus = "Timeout";
			break;
		case EIcmpResponseStatus::Unreachable:
			PingStatus = "Unreachable";
			break;
		case EIcmpResponseStatus::Unresolvable:
			PingStatus = "Unresolvable";
			break;
		case EIcmpResponseStatus::InternalError:
			PingStatus = "Internal Error";
			break;
		default:
			PingStatus = "Unknown Error";
			break;
	}

	// Simple log
	UE_LOG(LogTemp, Display, "Ping Result is " + PingStatus);
}

Now all that is left to do is call CheckIfServerIsOnline whenever you want. Inside OnServerCheckFinished you can also call custom Blueprint Implementable Events based on the PingResult.

Advertisements

About Satheesh (ryanjon2040)

Genuine Unreal Engine user

Posted on May 6, 2017, in Quick Tips, Unreal Engine 4 and tagged , , , , , , , , , , , . Bookmark the permalink. 8 Comments.

  1. Adrian Popoviciu

    Hello. Thank you for this tutorial, but I am stuck on it. (Newbie to networking)…
    Where did you get FIcmpEchoResult, FIcmpEchoResultDelegate, FUDPPing::UDPEcho, etc? I have no idea what header/plugin I need for those…Can you point me in the right direction? I tried searching them on google but I get nothing relevant and/or this tutorial. Have a nice day!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: