Skip to content
This repository was archived by the owner on May 11, 2026. It is now read-only.

Commit 7841315

Browse files
committed
add proper peerjs rtc
1 parent f0ebe1c commit 7841315

12 files changed

Lines changed: 228 additions & 24 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The goal of this project is to port a microservices-based application (a social
66

77
The application being ported is the **Social Network** application from the [DeathStarBench](https://github.com/delimitrou/DeathStarBench) benchmark suite.
88

9+
## Possible Improvements
10+
11+
This project is a POC, and many aspects could be improved. By using a single-page application, we could do away with legacy AJAX and unwanted refreshes. Integrating a proper dependency injection framework would facilitate development. Typing the project with TypeScript would make it more reliable. However, it serves as proof that this kind of project can be migrated. Testing the same approach with a larger-scale C++ project involving more business logic could be a next step.
12+
913
## Server Deployment
1014

1115
To deploy the backend infrastructure, run the Ansible playbooks provided:

convertedClient/di.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {
1616
} from "./script/utils.js";
1717
import { sharedRoomName, personnalRoomName } from "./script/consts";
1818
import PeerjsService from "./script/peerjs-service.js";
19+
import PeerJsReceiverService from "./script/peer-js-receiver-service.js";
20+
import PeerJsSenderService from "./script/peer-js-sender-service.js";
1921

2022
var module = await Module();
2123

@@ -78,11 +80,25 @@ const annuaireService = new AnnuaireService(sharedDoc.clientID, provider);
7880

7981
const loggedUser = sessionStorageUserService.getNullableLoggedUser();
8082
let peerjsService = null;
83+
let peerJsReceiverService = null;
84+
let peerJsSenderService = null;
85+
let synchronizeDbService = null;
8186
if (loggedUser) {
82-
peerjsService = new PeerjsService(Number(loggedUser.userid));
87+
peerJsReceiverService = new PeerJsReceiverService(postStorageHandler);
88+
peerjsService = new PeerjsService(
89+
Number(loggedUser.userid),
90+
peerJsReceiverService,
91+
);
92+
synchronizeDbService = new SynchronizeDbService(
93+
peerjsService,
94+
postStorageHandler,
95+
);
96+
peerJsSenderService = new PeerJsSenderService(
97+
synchronizeDbService,
98+
peerjsService,
99+
);
83100
module.peerjsService = peerjsService;
84101
}
85-
const synchronizeDbService = new SynchronizeDbService(peerjsService);
86102
let shardingService = new ShardingService(
87103
sharedDoc,
88104
persistence,
@@ -91,6 +107,7 @@ let shardingService = new ShardingService(
91107
module,
92108
sessionStorageUserService,
93109
peerjsService,
110+
peerJsSenderService,
94111
);
95112

96113
const di = {

convertedClient/script/consts.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ const sharedDocName = "shared-doc";
33
const sharedRoomName = "shared-room";
44
const personnalDocName = "personal-shared-doc";
55
const personnalRoomName = "personal-shared-room";
6+
const dbSyncTypeMsg = "db-sync";
67

78
export {
89
signalingServerIp,
910
sharedDocName,
1011
sharedRoomName,
1112
personnalRoomName,
1213
personnalDocName,
14+
dbSyncTypeMsg,
1315
};

convertedClient/script/main-js.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import di from "../di.js";
2+
import { dbSyncTypeMsg } from "./consts.js";
23

34
const loggedUser = di.sessionStorageUserService.getLoggedUser();
45
function followHandler(event) {
@@ -55,17 +56,14 @@ async function fillLoggedUser() {
5556

5657
const synchroniseBtn = clone.querySelector(".synchronize-db-user-btn");
5758
if (synchroniseBtn) {
58-
synchroniseBtn.addEventListener("click", (e) => {
59+
synchroniseBtn.addEventListener("click", async (e) => {
5960
e.stopPropagation();
6061
console.log("Synchronizing with user", user.username);
61-
di.module.createPeerJsConnection(loggedUser.userid, user.userId);
62-
const postsDb = di.postStorageHandler.GetAllPostsJsonFormat();
63-
console.log("Sending " + postsDb + " posts to user " + user.username);
64-
// TODO => hack ici, il faudrait réellement rendre synchrone l'appel
65-
setTimeout(() => {
66-
console.log("Sending message to peerjs connection");
67-
di.synchronizeDbService.sendDb(postsDb);
68-
}, 2000);
62+
await di.module.createPeerJsConnection(
63+
loggedUser.userid,
64+
user.userId,
65+
dbSyncTypeMsg,
66+
);
6967
});
7068
}
7169

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { dbSyncTypeMsg } from "./consts";
2+
export default class PeerJsReceiverService {
3+
constructor(postStorageHandler) {
4+
this.postStorageHandler = postStorageHandler;
5+
}
6+
7+
handleMessage(data) {
8+
console.log("PeerJsReceiverService received data : ", data);
9+
console.log("Data type is : ", data.type);
10+
switch (data.type) {
11+
case dbSyncTypeMsg:
12+
this.receiveRemoteDb(data.content);
13+
break;
14+
default:
15+
console.error("type : ", data.type, " not handled");
16+
}
17+
}
18+
19+
receiveRemoteDb(content) {
20+
this.postStorageHandler.StoreRemotePosts(content);
21+
window.location.reload();
22+
}
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { dbSyncTypeMsg } from "./consts";
2+
export default class PeerJsSenderService {
3+
constructor(synchronizeDbService, peerjsService) {
4+
this.synchronizeDbService = synchronizeDbService;
5+
this.peerjsService = peerjsService;
6+
}
7+
8+
sendMessage(type) {
9+
console.log("PeerJsSenderService sends type ", type);
10+
switch (type) {
11+
case dbSyncTypeMsg:
12+
this.sendPostDb();
13+
// TODO => ici devrait faire un tri sur ce qu'on souhaite réellement fermer
14+
this.peerjsService.activePeerJsConnections = {};
15+
this.peerjsService.closeConnection();
16+
break;
17+
default:
18+
console.error("type : ", data.type, " not handled");
19+
}
20+
}
21+
22+
sendPostDb() {
23+
this.synchronizeDbService.sendPostDb();
24+
}
25+
}

convertedClient/script/peerjs-service.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { Peer } from "peerjs";
22

33
export default class PeerjsService {
4-
constructor(peerId) {
4+
constructor(peerId, peerjsReceiverService) {
55
this.peer = new Peer(peerId);
6+
this.peerjsReceiverService = peerjsReceiverService;
67
this.conn = null;
8+
this.activePeerJsConnections = {};
79

810
this.peer.on("connection", (conn) => {
911
console.log("connection from:", conn.peer);
@@ -43,10 +45,7 @@ export default class PeerjsService {
4345
});
4446
this.conn.on("data", (data) => {
4547
console.log("Received message:", data);
46-
// TODO => si on pousse la logique ici, on pourrait tryer sur le type dans un autre service
47-
if (data.type != undefined) {
48-
alert(data.content);
49-
}
48+
this.peerjsReceiverService.handleMessage(data);
5049
});
5150
}
5251

convertedClient/script/sharding-service.js

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import di from "../di.js";
2-
2+
import { createPeerJsConnection } from "./utils.js";
33
export default class ShardingService {
44
constructor(
55
sharedDoc,
@@ -9,6 +9,7 @@ export default class ShardingService {
99
module,
1010
sessionStorageUserService,
1111
peerjsService,
12+
peerJsSenderService,
1213
) {
1314
this.sharedDoc = sharedDoc;
1415
this.persistence = persistence;
@@ -17,6 +18,7 @@ export default class ShardingService {
1718
this.module = module;
1819
this.sessionStorageUserService = sessionStorageUserService;
1920
this.peerjsService = peerjsService;
21+
this.peerJsSenderService = peerJsSenderService;
2022
console.log("ShardingService initialized");
2123
this.provider.awareness.on("change", this.handleAwarenessChange);
2224
}
@@ -79,16 +81,54 @@ export default class ShardingService {
7981

8082
if (clientState?.establish_peer_js_connection != undefined) {
8183
console.log("received establish_peer_js_connection");
84+
if (
85+
this.peerjsService.activePeerJsConnections[
86+
clientState.establish_peer_js_connection.source_user_id
87+
]
88+
) {
89+
console.log(
90+
"active peer js connection for ",
91+
clientState.establish_peer_js_connection.source_user_id,
92+
" already exists",
93+
);
94+
return;
95+
}
8296
const myUserId = this.sessionStorageUserService.getLoggedUser().userid;
8397
if (
8498
clientState.establish_peer_js_connection.targeted_user_id !=
8599
String(myUserId)
86100
) {
87101
return;
88102
}
103+
this.peerjsService.activePeerJsConnections[
104+
clientState.establish_peer_js_connection.source_user_id
105+
] = true;
106+
this.peerjsService.activePeerJsConnections[
107+
clientState.establish_peer_js_connection.targeted_user_id
108+
] = true;
109+
console.log(
110+
"new active peer js connections is ",
111+
this.peerjsService.activePeerJsConnections,
112+
);
89113
const peerId = clientState.establish_peer_js_connection.source_user_id;
90114
console.log("Establishing peer js connection with peer id ", peerId);
91115
this.peerjsService.connectToPeer(peerId);
116+
console.log(
117+
"send message from sharding service : ",
118+
clientState.establish_peer_js_connection.sync_type_msg,
119+
);
120+
await createPeerJsConnection(
121+
clientState.establish_peer_js_connection.targeted_user_id,
122+
clientState.establish_peer_js_connection.source_user_id,
123+
clientState.establish_peer_js_connection.sync_type_msg,
124+
);
125+
console.log(
126+
"send message from sharding service : ",
127+
clientState.establish_peer_js_connection.sync_type_msg,
128+
);
129+
this.peerJsSenderService.sendMessage(
130+
clientState.establish_peer_js_connection.sync_type_msg,
131+
);
92132
}
93133
}
94134

@@ -98,6 +138,18 @@ export default class ShardingService {
98138

99139
if (clientState?.establish_peer_js_connection != undefined) {
100140
console.log("received establish_peer_js_connection");
141+
if (
142+
this.peerjsService.activePeerJsConnections[
143+
clientState.establish_peer_js_connection.source_user_id
144+
]
145+
) {
146+
console.log(
147+
"active peer js connection for ",
148+
clientState.establish_peer_js_connection.source_user_id,
149+
" already exists",
150+
);
151+
return;
152+
}
101153

102154
const myUserId = this.sessionStorageUserService.getLoggedUser().userid;
103155
if (
@@ -107,8 +159,30 @@ export default class ShardingService {
107159
return;
108160
}
109161
const peerId = clientState.establish_peer_js_connection.source_user_id;
162+
this.peerjsService.activePeerJsConnections[
163+
clientState.establish_peer_js_connection.source_user_id
164+
] = true;
165+
this.peerjsService.activePeerJsConnections[
166+
clientState.establish_peer_js_connection.targeted_user_id
167+
] = true;
168+
console.log(
169+
"new active peer js connections is ",
170+
this.peerjsService.activePeerJsConnections,
171+
);
110172
console.log("Establishing peer js connection with peer id ", peerId);
111173
this.peerjsService.connectToPeer(peerId);
174+
await createPeerJsConnection(
175+
clientState.establish_peer_js_connection.targeted_user_id,
176+
clientState.establish_peer_js_connection.source_user_id,
177+
clientState.establish_peer_js_connection.sync_type_msg,
178+
);
179+
console.log(
180+
"send message from sharding service : ",
181+
clientState.establish_peer_js_connection.sync_type_msg,
182+
);
183+
this.peerJsSenderService.sendMessage(
184+
clientState.establish_peer_js_connection.sync_type_msg,
185+
);
112186
}
113187
if (clientState?.user != undefined) {
114188
this.annuaireService.communicateListOfUsers();
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
export default class SynchronizeDbService {
2-
constructor(peerjsService) {
2+
constructor(peerjsService, postStorageHandler) {
33
this.peerjsService = peerjsService;
4+
this.postStorageHandler = postStorageHandler;
45
}
56

6-
sendDb(db) {
7+
sendPostDb() {
8+
const postsDb = this.postStorageHandler.GetAllPostsJsonFormat();
9+
console.log("sendMessage content", postsDb);
710
this.peerjsService.sendMessage({
811
type: "db-sync",
9-
content: db,
12+
content: postsDb,
1013
});
11-
this.peerjsService.closeConnection();
1214
}
1315
}

convertedClient/script/utils.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,62 @@ import * as Y from "yjs";
22
import { WebrtcProvider } from "y-webrtc";
33
import { IndexeddbPersistence } from "y-indexeddb";
44
import di from "../di.js";
5-
5+
import { dbSyncTypeMsg } from "./consts";
66
import { signalingServerIp } from "./consts";
77

8-
function createPeerJsConnection(cur_user_id, target_user_id) {
8+
async function createPeerJsConnection(
9+
cur_user_id,
10+
target_user_id,
11+
sync_type_msg,
12+
) {
913
console.log(
1014
"Create peer js connection with cur_user_id ",
1115
cur_user_id,
1216
"and target_user_id",
1317
target_user_id,
1418
);
1519
console.log("Peer id for connection is ", cur_user_id);
20+
1621
di.module.mainProvider.awareness.setLocalStateField(
1722
"establish_peer_js_connection",
1823
{
1924
targeted_user_id: target_user_id,
2025
source_user_id: cur_user_id.toString(),
26+
sync_type_msg: sync_type_msg,
2127
},
2228
);
29+
30+
return new Promise((resolve, reject) => {
31+
let currentNumberOfCalls = 0;
32+
const maxNumberOfCalls = 10;
33+
34+
const timer = setInterval(() => {
35+
const isConnectionEstablished =
36+
di.peerjsService.activePeerJsConnections[target_user_id] === true;
37+
38+
if (isConnectionEstablished) {
39+
clearInterval(timer);
40+
41+
di.module.mainProvider.awareness.setLocalStateField(
42+
"establish_peer_js_connection",
43+
null,
44+
);
45+
46+
resolve(); //resolve promise
47+
return;
48+
}
49+
50+
currentNumberOfCalls++;
51+
52+
if (currentNumberOfCalls >= maxNumberOfCalls) {
53+
clearInterval(timer);
54+
const errorMessage =
55+
"Number of calls for createPeerJsConnection exceeded";
56+
console.error(errorMessage);
57+
reject(new Error(errorMessage)); // end promise with error
58+
}
59+
}, 2000);
60+
});
2361
}
2462

2563
async function sendFriendRequest(

0 commit comments

Comments
 (0)