A master server using Haskell and Scotty

This tutorial will guide you through the process of setting up an HTTP master server for your game. The server will be programmed in Haskell, using the Scotty web server library. The code is available in the a GitHub repository.

Setting up

I'm going to assume you're developing on Windows, but want to deploy your master server to, for example, a Heroku account or virtual private server. In this case, or even if you're developing on Linux and don't want to have to go through the process of installing the right Haskell compiler and other tools on your main computer, I highly recommend using Vagrant.

Once you've installed Vagrant and VirtualBox, all you'll need to do is vagrant up and you'll have a Linux box all set up and ready to go. On Windows, you'll probably also want to install git, and use Git Bash, which includes a unix-like command shell and some useful programs like ssh.

Project structure

  • Vagrantfile and .vagrant
  • Haskell files
  • Repository

Vagrant and provisioning

  • Virtual machine
  • Mounted dir
  • Provisioning
  • Provision script

Your first vagrant up!

Setting up a Haskell project

  • Cabal, cabal-install, cabal init, and sandboxes

Now, finally, we can start writing some code! Let's make a new file called Main.hs where we'll write our server. To start with, we'll just write the most basic program in Haskell, to make sure our compiler is working and correct. Type this into Main.hs:

If you've never used Haskell before, I hope you can still understand what's going on! This is the classic 'hello world' program, which just prints "Hello, world!" to the terminal. Let's try running it. Type cabal run into the command-line, and you should see the compilation, linking, and finally "Hello, world!"

Building a server

Now that we have a working environment, we can start writing our master server. We'll go through it in a few steps, gradually building up the functionality we need. First, we'll build a really simple server to test Scotty, the library we'll be using, and get a feel for how things will work.

Baby steps: echo server

For a first foray into using Scotty, we'll build a very simple echo server. It will have two possible actions. If you visit its home page in a browser (i.e. GET it), it will just print a static message. If you POST some data to /echo, it will echo that data back to you.

For explanation of what GET and POST are, have a read of this tutorial. Briefly, GET means you just want a view of some data, whereas POST signifies that you want to modify some data in the server. In our case, our POST action won't modify any data - we're just using it to learn how to get data out of a POST request.

Modify Main.hs so it looks like this:

Now instead of printing a message, we have a simple web server!

Those first few lines define a compiler extension, then import Scotty and a useful function from the Text library. Then we define a main function which launches a Scotty web server on port 3000, with two routes: get "/" and post "/echo".

If you try compiling this, you'll see that Scotty fails to import! We need to use cabal-install to pull down the library from Hackage, Haskell's package archive. To do this, we'll modify hackell-master-server.cabal to pull in the libraries we need:

  build-depends:       scotty, text,
                       base >=4.7 && <4.8

This says that we want to use the Scotty and Text libraries. Now, from your command-line, run cabal install —only-dependencies, and you should see a lot of files being compiled. Once that's finished, try cabal run again. You should see a successful compilation, and then a message from Scotty saying that your server is running! Now you can visit localhsot:3000 in your browser, and you should see the message we told our server to respond with.

To test the POST route, you'll need to use some javascript, or a REST console.

Local testing

  • Modify Vagrant for port forwarding

Building the master server

Listing games

Storing games

Forgetting games

Deployment

  • Heroku, buildpack
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License