Architecture
#
OverviewRealtimely takes full advantage of the capabilities of AWS AppSync. The GraphQL endpoint generated by AppSync is connected by Apollo Client and the state is managed by React.
#
Backend#
DynamoDBDynamoDB is a key-value store scalable NoSQL database.
There are HashKey and SortKey as keys of DynamoDB, and DB design is done so that this combination is unique.
RealtimeCursor
and OnlineUser
have the following schema.
HashKey | SortKey |
---|---|
URL#{URL} | UserId#{UserId} |
The actual values are entered in {URL} and {UserId}. For this key, the mouse cursor position (X, Y) and user information are saved as attributes. In other words, the latest data is always associated with this key and updated, so time-series data is not retained. This DB design is efficient and high performance because Realtimely's interest is always "now".
#
AppSyncAppSync is a managed service for GraphQL servers. They have a feature to automatically generate GraphQL schema and resolver by connecting with DynamoDB table. Realtimely uses the automatically created schema and resolver with a little customization.
The following two resolvers are mainly used. (XXX is the table name)
- createXXX
- onCreateXXX
createXXX
creates the resource and adds it to the DynamoDB table. The default resolver is implemented so that an error will occur if the same key exists, but it is customized and updated if the same key exists. Also, deleteTime is calculated from the current time.
onCreateXXX
monitors the mutation of createXXX
, and when this mutation is executed, the resource generated there is notified by Subscrition (Websocket). This allows you to deliver the created/updated data to the frontend.
#
Frontend#
Apollo ClientIt employs the Apollo Client to communicate with the AppSync endpoint.
#
ReactRealtimely manages state with React.
Send the latest resource (for example, cursor position) with createXXX
and receive the resource created with onCreateXXX
.
Received resources are managed in a list, and those that exceed the deleteTime are discarded to keep them up to date.
By calling createXXX
again within deleteTime, it will not disappear from the managed list.
Conversely, for resources for which createXXX
was not called within the deleteTime, it is determined that the user has already left the screen and will be invisible to other users.