Build a Simple Chat App using Java and Stateful Web Agents

by Brad Johnson, on Jun 24, 2019 12:35:31 PM

Even the most simple chat user interfaces bely a world of architectural complexity. Features like authentication, user presence, chat rooms, user counts, message encryption and countless others represent a significant undertaking. However, with the right tools, building an enterprise-scale chat application is not only possible, it can be done relatively quickly.

This post is a tutorial for building a basic chat application using the open source Swim platform. The app we’ll be referencing was built by Scott Clarke, a UI developer at Swim, and the source code is available on GitHub here. Because this chat application is intended to demonstrate Swim development patterns, as opposed to being a usable product, we have not included features like authentication or compressive user state tracking. While we do include user presence in the chat app, we took the simplest approach possible and just display a user’s local IP address. This app may be simple, but the same patterns we demonstrate here can be used to build a massively scalable version, and can easily be integrated with authentication services or other third-party software.

Before you get started, if you want to read more about the architecture of Swim, I recommend starting here.

Using Web Agents to Build a Simple Chat App

Before we get started, let’s briefly discuss the Swim platform architecture. The fundamental building block of Swim is a Web Agent, which is defined on the Swim Server. Each Web Agent is assigned a unique URI, so that it can be addressed by other agents. Web Agents have Lanes which are like data objects, each being identified by a name unique to that agent. Using Web Agents and Lanes, you can create dynamic models of your application. In the case of this chat app, Web Agents represent users and their messages are published to a Lane.

Get Started: Build a Simple Chat App

If you don’t already have it pulled up, you can find the source code for the Simple Chat App example on GitHub here.

Now that we’re ready to get started, the first thing you’ll want to do is setup your Swim server environment. This will ensure you’re able to run the chat app. Once you’ve setup your Swim server environment, it’s time to setup a Swim Plane. You can think of Planes as a shared context for a group of Web Agents, somewhat analogous to scopes but with more runtime responsibilities. More specifically, every Plane routes messages to the correct Web Agents and lanes, has lifecycle callback functions that are overridable with custom logic, is a Swim handle that can talk to any other Swim handle over WARP, and can define security policies to control access to Swim data.

Simple Chat App Architecture

Within the Swim server we have single Swim Plane called ChatPlane  that manages the routing for two Web Agents. In a real world scenario, you would have additional routes and agents to handle things like authentication, user data, etc. but for this example we are keeping it as minimal as possible while still being usable.

The first Web Agent, called  Rooms , is responsible for managing the list of rooms available on the server. A server will only have one instance of a Rooms Agent and on server startup that Web Agent will automatically create the default public room which all users first start out in. The second Web Agent is called just Room  (singular). This agent manages the list of chat messages as well as the list of users currently in that particular room. The Room Agent is dynamically created for each room created on the server, so one server can have many Room Agents. 

An individual Room is ephemeral; when a room is removed, its Agent also ceases to exist. For more specific information about the server and its agents see the README found in the /server folder of this project. The codebase itself is thoroughly commented and does its best to describe all the important methods and variables used in the code.

Get the Code

In this example, we are also using Swim as our HTTP server and the UI is done using vanilla Javascript, HTML and CSS. In the real world you would likely want to have a separate HTTP server and be using React, Vue, Angular, etc to drive the UI. This is quite simple to do and just requires a configuration change in your Swim resource file to turn off the HTTP server in Swim. The main JS file which drives the UI is chat.js and is found in  /ui/assets/js/chat/.js .

More information about how the UI works can be found in the README under /ui and in the comments of chat.js . You need Java 9+ to run the application and these instructions only cover running in a unix-like environment. Gradle is not required as the project provides a Gradle wrapper to use instead.

Here's how you can get started:

  1. Git clone  https://github.com/swimod/swim-chat-site.git 
  2. Navigate to the server directory with cd swim-chat-site/server
  3. Run app with ./gradlew run  
  4. Navigate to http://127.0.0.1:9001  and you should see the chat application and be defaulted to the 'public' room

Learn More

Share your thoughts about the Swim Simple Chat App below and let us know what you're building using the open source Swim platform.

You can get started with Swim here and make sure to STAR us on GitHub.

Topics:Stateful ApplicationsSWIM AIdistributed computingHTTPweb applicationsWARPweb agentsapistreaming apitutorialjava