Optimizing connectivity for users in China with reverse proxy

The game I am currently working on is a mobile strategy game. We have a server cluster located in the US to serve players around the world. It should suffice the needs – players in Europe and Oceania will experience a latency around 50 to 200 ms, but there is rarely any packet loss, so it is totally playable. Unfortunately it is a whole different story for players in China.

And really it has nothing to do with the censorship. Basically, China has the most internet users, but its global bandwidth is so limited. At peak time, many users can’t even visit foreign sites, let alone playing games on foreign servers. Dedicated players find their own solutions by subscribing to VPN-like accelerators, or using the value-added services called NOS (previously known as Global Delicate Network, 国际精品网, offered by the largest ISP, China Telecom). Those solutions utilize reserved global bandwidth, for example the CN2 backbone, which is primarily used by transnational corporations. The thing is, you can not expect every potential user of yours to have such service. So what about that we find a server that uses such reserved global bandwidth, and make it a reversed proxy for our servers in the US?

Preparation and Client

The first thing is to enable alternative connections in client. We want to enable players in China to choose to connect to the reverse proxy while keeping users in the rest of the world unchanged. Our approach is that when a user opens the game, it retrieves all possible connections, including the server cluster itself and reverse proxies – we call them nodes. On the client side, it determines whether the player is in China, if so, it reveals the node options to the user. All data will then be sent to and receive from the chosen node.

Reverse Proxy Solutions

There are many reverse proxy solutions. I have listed a few:

HTTP TCP UDP
iptables
NGINX
Apache
HAProxy

I will use HAProxy on Ubuntu 14.04 as an example:

Install HAProxy:

apt-get update
apt-get install haproxy

Configure the reverse proxy. Add the following to the config file /etc/haproxy/haproxy.cfg:

listen gameproxy 0.0.0.0:1337
mode tcp
option tcplog
server gameserver 123.123.123.123:1337

Start HAProxy using the config:

haproxy -f /etc/haproxy/haproxy.cfg

Done. Now this node works as if it were the server itself.

Also, instead of implement a reverse proxy yourself, there are similar services you can purchase, such as VnetLink. It provides fast and cheap services. However its uptime isn’t as good, and its pricing model gives me big headache.

 

Quick access to MySQL using R

Package RMySQL turns R to a powerful MySQL client. Below are the simple steps to use it:

Install and load RMySQL:

install.packages("RMySQL")
library(RMySQL)

Connect to a MySQL database:

connection = dbConnect(MySQL(), host = "localhost", username = "root", password ="password", dbname = "databasename")

If you do not know the database name, you can omit it for now and use the following to find out all databases assigned to this user:

dbGetQuery(connection, "show databases")

To send queries:

# This sends the query but the result stays in MySQL server.
query = dbSendQuery(con, "query")  

# Retrieve n rows of the result, and put it in a data.frame. If n is set to -1, it will retrieve all rows.
data = dbFetch(query, n)  

# Clear the query on MySQL server side.
dbClearResult(query) 

Another function allows you to do all the three steps – query, fetch and clear at once:

data = dbGetQuery(con, "query")

A good practice is always remembering to disconnect:

dbDisconnect(connection)