Skip to content

Commit

Permalink
Made follow mode more robust.
Browse files Browse the repository at this point in the history
  • Loading branch information
barnabasmolnar committed Dec 12, 2023
1 parent 9517936 commit 01e78bf
Showing 1 changed file with 39 additions and 4 deletions.
43 changes: 39 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ try {
allowEIO3: true,
});

// we want to keep track of the last position of the followed user's scene
// bounds so that we can send it to the new follower without having to
// make an interaction on the scene
const withLatestSceneBounds = new Map<
string,
{ data: ArrayBuffer; iv: Uint8Array }
>();

io.on("connection", (socket) => {
ioDebug("connection established!");
io.to(`${socket.id}`).emit("init-room");
Expand Down Expand Up @@ -77,6 +85,9 @@ try {
socket.on(
"server-volatile-broadcast",
(roomID: string, encryptedData: ArrayBuffer, iv: Uint8Array) => {
if (roomID.startsWith("follow_")) {
withLatestSceneBounds.set(roomID, { data: encryptedData, iv });
}
socketDebug(`${socket.id} sends volatile update to ${roomID}`);
socket.volatile.broadcast
.to(roomID)
Expand All @@ -89,19 +100,43 @@ try {
switch (payload.action) {
case "follow":
await socket.join(roomID);
const sockets = await io.in(roomID).fetchSockets();

if (sockets.length === 1) {
io.to(payload.userToFollow.clientId).emit("broadcast-follow");
// Immediately send the latest scene bounds to the new follower
// without having to wait for a scene interaction
const latestSceneBounds = withLatestSceneBounds.get(roomID);
if (latestSceneBounds) {
io.to(socket.id).emit(
"client-broadcast",
latestSceneBounds.data,
latestSceneBounds.iv,
);
}

const sockets = await io.in(roomID).fetchSockets();
const followedBy = sockets.map((socket) => socket.id);

// Notify the user to follow that someone has followed them
// More precisely, send the list of users that are following them
// so that they can make decisions based on that
io.to(payload.userToFollow.clientId).emit(
"follow-room-user-change",
followedBy,
);

break;
case "unfollow":
await socket.leave(roomID);
const _sockets = await io.in(roomID).fetchSockets();
const _followedBy = _sockets.map((socket) => socket.id);

io.to(payload.userToFollow.clientId).emit(
"follow-room-user-change",
_followedBy,
);

// cleanup
if (_sockets.length === 0) {
io.to(payload.userToFollow.clientId).emit("broadcast-unfollow");
withLatestSceneBounds.delete(roomID);
}

break;
Expand Down

0 comments on commit 01e78bf

Please sign in to comment.