Weekend Project (Part 1): Creating a Real-time Web-based Application using Flask, Vue, and Socket.io

Josh Porter
Hacker Valley Studio
5 min readNov 21, 2017

The full source code for this project can be found here.

Spymaster view on an iPad

This project was originally given life by my friend and coworker Daniel Sprechman. He’s a huge board game fanatic, and has built quite a few personal web adaptations of some of his favorite games, including a crowd favorite, Codenames. You can see some of Daniel’s work here.

Daniel and I discuss his side projects and game ideas all the time, and one day he showed me his web-version of Codenames. It was great, he added awesome features such as adding a third team, using a larger game board, and even using custom dictionaries such as words from Cards Against Humanity — this one would probably make for interesting clues! I loved the idea, but his version had one downfall… the interactions were all manual, meaning the agents and spymasters had to update their boards themselves as the game progressed.

Having done a rather light amount of real-time webapp work in the past, and being fairly new to modern Javascript frameworks, I decided this was a perfect time to learn and reinforce my skills in Vue.js and websockets. I’ve only ever used websockets for server/browser communication in an open source project built by me and a former coworker and new blog writer Ronald Eddings.

We designed and built a modular application/framework for validating nodes on an IPv6-enabled network, called the IPv6 Framework. This application ran a network sniffer using Flask and Scapy on the back-end, and as it received packets that matched our filters, it transmitted a JSON object to the front-end via Socket.io. Nothing too crazy going on here… no rooms, no users; just a server having a nice conversation with the client. That’s about where my experience with websockets ended… until now.

Enough rambling about past projects or how this project came to fruition, let’s get to work and architect this application!

Planning

I don’t know about you, but I hate planning. Instinctually, I just want to dive in and start writing code. Having done this plenty of times, this tactic usually results in plenty of rewriting and refactoring because of poor planning, or lack thereof. So, let’s figure out how this application should look, both front-end and server-side.

To start, we know the application will be built in two distinct parts: the Vue.js front-end, and the Flask back-end. In addition, we’ll be using Vuetify to give our front-end a little personality, as well as socket.io to allow our front-end to talk to our back-end.

Server-side Architecture

When planning out the server, I decided to stick with the original repository’s back-end of Flask. With some Flask-SocketIO experience under my belt, I knew it was fairly easy to get something up and running. Since we’re using Flask to handle our websockets and Vue for the front-end, I ditched the typical Flask approach of rendering templates using Jinja2 — except for serving up the built production code. Instead, Vue will handle all of the display code and Flask was essentially a websocket API.

Client-side Architecture

For our front-end, we will use webpack to host a development server with hot-reload, so we can see our code updates happen real-time in the browser. But that’s not all — with the right configuration, webpack will take modules of code that you use and bundle it into a more compact file. For example, if you want to use Vue but only need a few functions from it, webpack will only package those functions into the compiled javascript file.

Using webpack, we will build a front-end using Vue.js, a light yet robust javascript framework. Vue is typically mentioned in the same sentences as React and Angular, being the lighter, easier to learn alternative to both frameworks. Vue has many features which make it a perfect fit for this project, including model reactivity, easy-to-use templates and components, CSS transition support, flexible routing, and a centralized state management component. These features allow us to write a flexible front-end while maintaining our game data in a manageable fashion.

The final component to our front-end, which ties everything together, is socket.io. Socket.io allows us to communicate data from our server to our clients in real-time. Sure, we can do this in near-real-time using AJAX calls and timeouts, but where’s the fun in that? Socket.io actually provides more than just a transport layer to our application — it also allows all of our clients to receive broadcasts from the server using “rooms.” Think of this as a one-to-many relationship between the server and our clients. When the server broadcasts a message, all of the clients will receive this and update their front-end accordingly. This feature will be used when we make changes to the game board when turns are taken.

Bringing it all together

Whew, the amount of components that define our app are starting to stack up! To make sense of the complexity, here’s a basic diagram depicting how it all connects together. I’d love to say I made this during the “planning” phase, but unfortunately I don’t have that step ironed out just yet. However, this is basically what I pictured in my head when planning the app!

Vue client is built into and served from Flask

That wraps it up for this post — I mostly wanted to give a run-down of what the project is and what this series will cover. Stay tuned for Part 2, where we’ll go over setting up our Flask back-end to support websockets!

Update 2017/12/05 — Learn how to add websocket support to a Flask server in Part 2 of this series!

--

--

Josh Porter
Hacker Valley Studio

Baltimore-based software developer with a passion for clean code, craft beer, and video games. http://codecaffeinated.com