Просмотр исходного кода

WIP: Page rooms worked. need to get user for hackmd

Taichi Masuyama 4 лет назад
Родитель
Сommit
61aa401c9c

+ 11 - 20
packages/app/src/client/services/PageContainer.js

@@ -125,6 +125,10 @@ export default class PageContainer extends Container {
     this.setTocHtml = this.setTocHtml.bind(this);
     this.save = this.save.bind(this);
     this.checkAndUpdateImageUrlCached = this.checkAndUpdateImageUrlCached.bind(this);
+
+    this.emitJoinPageRoomRequest = this.emitJoinPageRoomRequest.bind(this);
+    this.emitJoinPageRoomRequest();
+
     this.addWebSocketEventHandlers = this.addWebSocketEventHandlers.bind(this);
     this.addWebSocketEventHandlers();
 
@@ -565,6 +569,13 @@ export default class PageContainer extends Container {
     });
   }
 
+  // request to server so the client to join a room for each page
+  emitJoinPageRoomRequest() {
+    const socketIoContainer = this.appContainer.getContainer('SocketIoContainer');
+    const socket = socketIoContainer.getSocket();
+    socket.emit('join:page', { socketId: socket.id, pageId: this.state.pageId });
+  }
+
   addWebSocketEventHandlers() {
     // eslint-disable-next-line @typescript-eslint/no-this-alias
     const pageContainer = this;
@@ -572,11 +583,6 @@ export default class PageContainer extends Container {
     const socket = socketIoContainer.getSocket();
 
     socket.on('page:create', (data) => {
-      // skip if triggered myself
-      if (data.socketClientId != null && data.socketClientId === socketIoContainer.getSocketClientId()) {
-        return;
-      }
-
       logger.debug({ obj: data }, `websocket on 'page:create'`); // eslint-disable-line quotes
 
       // update remote page data
@@ -587,11 +593,6 @@ export default class PageContainer extends Container {
     });
 
     socket.on('page:update', (data) => {
-      // skip if triggered myself
-      if (data.socketClientId != null && data.socketClientId === socketIoContainer.getSocketClientId()) {
-        return;
-      }
-
       logger.debug({ obj: data }, `websocket on 'page:update'`); // eslint-disable-line quotes
 
       // update remote page data
@@ -602,11 +603,6 @@ export default class PageContainer extends Container {
     });
 
     socket.on('page:delete', (data) => {
-      // skip if triggered myself
-      if (data.socketClientId != null && data.socketClientId === socketIoContainer.getSocketClientId()) {
-        return;
-      }
-
       logger.debug({ obj: data }, `websocket on 'page:delete'`); // eslint-disable-line quotes
 
       // update remote page data
@@ -617,11 +613,6 @@ export default class PageContainer extends Container {
     });
 
     socket.on('page:editingWithHackmd', (data) => {
-      // skip if triggered myself
-      if (data.socketClientId != null && data.socketClientId === socketIoContainer.getSocketClientId()) {
-        return;
-      }
-
       logger.debug({ obj: data }, `websocket on 'page:editingWithHackmd'`); // eslint-disable-line quotes
 
       // update isHackmdDraftUpdatingInRealtime

+ 1 - 0
packages/app/src/server/routes/hackmd.js

@@ -341,6 +341,7 @@ module.exports = function(crowi, app) {
    * @param {object} res
    */
   const saveOnHackmd = async function(req, res) {
+    // TODO: check if i can get user from this req. im sure i can though TAICHI
     const page = req.page;
 
     try {

+ 11 - 5
packages/app/src/server/service/socket-io.js

@@ -1,4 +1,5 @@
 import loggerFactory from '~/utils/logger';
+import { RoomPrefix, getRoomNameWithId } from './utils/socket-io-helpers';
 
 const socketIo = require('socket.io');
 const expressSession = require('express-session');
@@ -7,6 +8,7 @@ const passport = require('passport');
 const logger = loggerFactory('growi:service:socket-io');
 
 
+
 /**
  * Serve socket.io for server-to-client messaging
  */
@@ -41,7 +43,7 @@ class SocketIoService {
 
     await this.setupStoreGuestIdEventHandler();
 
-    await this.setupDefaultSocketRoomsEventHandler();
+    await this.setupDefaultSocketJoinRoomsEventHandler();
   }
 
   getDefaultSocket() {
@@ -126,18 +128,22 @@ class SocketIoService {
     });
   }
 
-  setupDefaultSocketRoomsEventHandler() {
+  setupDefaultSocketJoinRoomsEventHandler() {
     this.io.on('connection', (socket) => {
-      // TODO: check if i can get page information here and use or not
-      // TODO: join page rooms here if possible
+      // TODO: check if i can get page information here and use or not TAICHI
+      // TODO: join page rooms here if possible TAICHI
       const user = socket.request.user;
       if (user == null) {
         logger.debug('Socket io: An anonymous user has connected');
         return;
       }
       // make a room for each user. it leaves automatically
-      // TODO: avoid hard coding by using a utility function
+      // TODO: avoid hard coding by using a utility function TAICHI
       socket.join(`user:${user._id}`);
+
+      socket.on('join:page', ({ pageId }) => {
+        socket.join(getRoomNameWithId(RoomPrefix.PAGE, pageId));
+      });
     });
   }
 

+ 30 - 7
packages/app/src/server/service/system-events/sync-page-status.ts

@@ -5,6 +5,8 @@ import { S2cMessagePageUpdated } from '../../models/vo/s2c-message';
 import { S2sMessageHandlable } from '../s2s-messaging/handlable';
 import { S2sMessagingService } from '../s2s-messaging/base';
 
+import { RoomPrefix, getRoomNameWithId } from '../utils/socket-io-helpers';
+
 const logger = loggerFactory('growi:service:system-events:SyncPageStatusService');
 
 /**
@@ -84,33 +86,54 @@ class SyncPageStatusService implements S2sMessageHandlable {
     const { socketIoService } = this;
 
     // register events
-    this.emitter.on('create', (page, user, socketClientId) => {
+    this.emitter.on('create', (page, user) => {
       logger.debug('\'create\' event emitted.');
 
       const s2cMessagePageUpdated = new S2cMessagePageUpdated(page, user);
-      socketIoService.getDefaultSocket().emit('page:create', { s2cMessagePageUpdated, socketClientId });
+
+      // emit to the room for each page
+      socketIoService.getDefaultSocket()
+        .in(getRoomNameWithId(RoomPrefix.PAGE, page._id))
+        .except(getRoomNameWithId(RoomPrefix.USER, user._id))
+        .emit('page:create', { s2cMessagePageUpdated });
 
       this.publishToOtherServers('page:create', { s2cMessagePageUpdated });
     });
-    this.emitter.on('update', (page, user, socketClientId) => {
+    this.emitter.on('update', (page, user) => {
       logger.debug('\'update\' event emitted.');
 
       const s2cMessagePageUpdated = new S2cMessagePageUpdated(page, user);
-      socketIoService.getDefaultSocket().emit('page:update', { s2cMessagePageUpdated, socketClientId });
+
+      // emit to the room for each page
+      socketIoService.getDefaultSocket()
+        .in(getRoomNameWithId(RoomPrefix.PAGE, page._id))
+        .except(getRoomNameWithId(RoomPrefix.USER, user._id))
+        .emit('page:update', { s2cMessagePageUpdated });
 
       this.publishToOtherServers('page:update', { s2cMessagePageUpdated });
     });
-    this.emitter.on('delete', (page, user, socketClientId) => {
+    this.emitter.on('delete', (page, user) => {
       logger.debug('\'delete\' event emitted.');
 
       const s2cMessagePageUpdated = new S2cMessagePageUpdated(page, user);
-      socketIoService.getDefaultSocket().emit('page:delete', { s2cMessagePageUpdated, socketClientId });
+
+      // emit to the room for each page
+      socketIoService.getDefaultSocket()
+        .in(getRoomNameWithId(RoomPrefix.PAGE, page._id))
+        .except(getRoomNameWithId(RoomPrefix.USER, user._id))
+        .emit('page:delete', { s2cMessagePageUpdated });
 
       this.publishToOtherServers('page:delete', { s2cMessagePageUpdated });
     });
+    // TODO: get user TAICHI
     this.emitter.on('saveOnHackmd', (page) => {
       const s2cMessagePageUpdated = new S2cMessagePageUpdated(page);
-      socketIoService.getDefaultSocket().emit('page:editingWithHackmd', { s2cMessagePageUpdated });
+
+      // emit to the room for each page
+      socketIoService.getDefaultSocket()
+        .in(getRoomNameWithId(RoomPrefix.PAGE, page._id))
+        .emit('page:editingWithHackmd', { s2cMessagePageUpdated });
+
       this.publishToOtherServers('page:editingWithHackmd', { s2cMessagePageUpdated });
     });
   }

+ 8 - 0
packages/app/src/server/service/utils/socket-io-helpers.ts

@@ -0,0 +1,8 @@
+export const RoomPrefix = {
+  USER: 'user',
+  PAGE: 'page',
+};
+
+export const getRoomNameWithId = (roomPrefix: string, roomId: string): string => {
+  return `${roomPrefix}:${roomId}`;
+};