This is a Rails Application that uses WebSockets and the react-crossword component to create multiplayer crosswords. You can read a blog post about why I built it and how it works.
You can see a demo at multicrosser.chriszetter.com.
To run this project:
- Install Redis and make sure the server is running
- Run
./bin/setup
to install dependencies - Run
./bin/rails crosswords:load_from_feed
to load the latest crosswords to display on the homepage - Run
./bin/rails server
to start the project
Here's what happens when a player types a character:
- Client:
react-crossword
callssetCellValue
to update the grid
setCellValue
calls theonMove
callback with cell location and valueonMove
callback calls themove
function in the action cable subscription- The
move
function sends the move to the server
- Server:
MovesChannel#move
is run
- The move is recorded in Redis
- The move is rebroadcast to others in the channel
- On all clients:
- The
received
function runs in the Action Cable subscriptions which calls theonReceiveMove
callback onReceiveMove
callssetCellValue
with thetriggerOnMoveCallback
option set tofalse
soonMove
isn't called againsetCellValue
updates the crossword gird
If the move can't be broadcast with Action Cable it's stored in the MoveBuffer
. On reconnection:
- The remote state of the grid will be received from the server and updated
- The moves in the moves buffer will be replayed
When the move MoveBuffer
is replayed, moves will only apply if the cell they change still has the same character in it when the move was made. For example, if you change an 'A' to a 'B' while offline this move will be discarded if someone has since changed the 'A' to a 'C' and broadcast it to the server before you.
The MoveBuffer
uses local storage so will persist if the page is refreshed or the browser is closed.
Crosswords are scraped from the Guardian Crossword pages which contain a JSON representation of each crossword. The crosswords are re-used following their Open Licence Terms.