Build a direct messaging feature with Web Sockets

by jj

Software Development Journey Overview

Follow this step-by-step software development journey to see real progress updates, challenges overcome, and practical experience.

Progress Updates (5 total)

Update #1: Build a direct messaging feature with Web Sockets

DMing would allow users to share content and ask questions easier to each other. I have something rough but there are a few problems, and Web Sockets to have real time updating is a new tech for me!

Update #2: Basics of Web Sockets working

35% complete
Added a new Lambda function with Dynamo table to save and lookup active connections. Ended up being more straightforward than expected. AWS doc on this is great; I even copied the serverless config file. Realized I can replace POST messages with WS now, and just decide in backend if a user should be WS'd or sent a push. Pretty cool.
Challenges Overcome: A big chunk of time was figuring out why the backend stopped working when I deployed the new WS function. It turns out I didn't have the Nat gateway subnets configured correctly in the serverless file. Resolving this is great- as I now have a more repeatable AWS deployment stack.
Obstacles Faced: Need to implement the backend logic to save the messages from WS then decide to WS or push the user. I also really need to make sure this WS error handling is well done- as WS don't return anything upon sending, so if a sender disconnects- they don't have a way yet of knowing their message didn't send.
Looking Back: 1. Web Sockets don't return anything, so don't expect to print out a return status, but rather, you need to send yourself a message from the backend saying "I got your message!" separately. 2. In the backend, a "route" is defined as "route: $connect", "route: $sendmessage", etc. On the frontend, the same route looks like this: JSON.stringify({ action: 'sendmessage', msg }). So, your backend custom route (like "sendmessage") needs to match your frontend "action".

Update #3: Live messaging

70% complete
DMing is mostly complete. Websockets now replace HTTP for messaging sending. If someone is online, they won't get a push notifications, and just see a message on screen. Else, they get a push. Many optimizations to be made, but it's working pretty well it seems!
Challenges Overcome: Something weird is going on with height: 100% in css styling. I was seeing the chat box overflow across the page. So, just hardcoded the height values of header and bottom nav for now, which is working well. Implemented some basic things that you don't typically think of like: if new message, push that convo to top of sidebar, if chat open and new message, auto scroll to the bottom to see the new message.
Next Steps: Add reliability feedback to handle if message fails to send. Data structure clean up (use Maps for conversations instead of arrays).

Update #4: In-app notifications

80% complete
Added the critical functionality of an alert when a user receives a new message. Previously, web sockets were run only in the messaging route. This unlocks eventually having pop-up messages at the bottom of the page (standard in other socials).
Challenges Overcome: This just required moving the messaging component to the header, or some other global scope of the webpage.

Update #5: Sharing Goals and profiles complete!

100% complete
Implementation was simpler than expected. Just added a type field to messages and created components to display messages of various types.
Challenges Overcome: The share menu was simple- just used the same component to search a user's followers (as can be seen in message menu), and just need to pass a type, either "goal" or "user" for the type of share content. Part two was just displaying the respective shared content, which was just an ngIf statement and two new components for a shared Goal-in-message and shared profile-in-message