Integrating Concurrent Editing
Oxygen XML Web Author provides the ability for teams to edit and review content
        concurrently. The concurrent editing feature can be enabled either with the built-in
      Share Editing Session action or by integrating the concurrent editing
      support in a CMS using the available API. The Share Editing Session
      action works by allowing the user to share their editing session by using the
       Share
        Editing Session toolbar button and then sending the retrieved URL to other
      collaborators and then all of them can edit and review the same document simultaneously.
Share
        Editing Session toolbar button and then sending the retrieved URL to other
      collaborators and then all of them can edit and review the same document simultaneously.
Enabling the Share Editing Session Action
To enable the  Share Editing
          Session action, the following conditions must be met:
Share Editing
          Session action, the following conditions must be met:
- The Concurrent Editing Plugin must be enabled in the Administration Page (it is bundled with the Oxygen XML Web Author installers and is enabled by default).
- The sharedSessionCompatibleloading option must be set totrueby the CMS connector plugin. Note that the built-in connectors (for e.g. the Git connector) have this option by default configured.
For the feature to work correctly, when a concurrent session is active, the CMS connector plugin should ensure that:
- Any save/commit action is disabled for session guests.
- Any check-in/check-out actions are disabled for session guests.
- The document is editable for guests even though they do not have a lock for it.
var mgr = editor.getEditingSupport().getConcurrentEditingManager();    
if (mgr && !mgr.isCreator()) {      
      ...
} - Concurrent editing does not work if Oxygen XML Web Author is deployed on multiple servers behind a load balancer.
- 
            Oxygen XML Web Author uses Web Sockets to propagate changes in real time between collaborators. If you are using a reverse proxy, some additional configuration may be required to enable Web Socket connections to the ./wsendpoint of the application.For example, NGINX requires the following configuration for the /oxygen-xml-web-author/ws path:location /oxygen-xml-web-author/ws { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_pass http://web-author:8080; }As another example, when using Apache HTTP server as a reverse proxy, a system administrator needs to enable the following modules: - 
                rewrite
- 
                proxy_http
- 
                proxy_wstunnel
 Also, a configuration should be added similar to this:ProxyPass /oxygen-xml-web-author http://<internal-host>:8080/oxygen-xml-web-author ProxyPassReverse /oxygen-xml-web-author http://<internal-host>:8080/oxygen-xml-web-author RewriteEngine on RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/oxygen-xml-web-author/?(.*) "ws://<internal-host>:8080/oxygen-xml-web-author/$1" [P,L]When using the IIS web server as a reverse proxy, you need to configure it according to this tutorial. 
- 
                
- Some customizations can cause problems if used in situations with
            high activity or a large number of users simultaneously. These possible limitations
            include:- The onChangeproperty for the combo box form control is not supported in concurrent editing sessions.
- Inline CSS actions (for example, when used in an
                oxy_buttonform control).
- Editable combo boxes on the floating toolbar.
- Quick fixes that come from XML Schema or DTD.
 
- The 
Disabling the Share Editing Session Action
To remove the  Share Editing
            Session action from the toolbar, simply disable the Concurrent
              Editing Plugin in the Administration Page.
Share Editing
            Session action from the toolbar, simply disable the Concurrent
              Editing Plugin in the Administration Page.
CMS-owned Concurrent Editing Sessions
Aside from using the  Share Editing
          Session action, a more integrated concurrent editing approach is to have a
        concurrent editing room owned by the CMS.
Share Editing
          Session action, a more integrated concurrent editing approach is to have a
        concurrent editing room owned by the CMS. 
A concurrent editing room contains multiple editors, each working on the same document,
          with all changes synchronized in real time. Each editor corresponds to a browser tab and
          is represented by an AuthorDocumentModel in the API.
The CMS needs to ensure that there is at most one concurrent editing room for one document.
- Ensuring that aside from the Web Author users, no other users are modifying the file. The CMS can use a "service" account to hold the "lock" on the edited file, or to do a check-out.
- Creating the concurrent editing room.
- Adding new editors in the room.
- Specifying the Save Strategy.
- Closing the room.
Creating a Concurrent Editing Room
When an user opens a document in an editor, the CMS needs to create a concurrent editing room for that document if one is not already created.
The recommended way for a CMS to create a concurrent editing room is by using the Java API:
import ro.sync.ecss.extensions.api.webapp.ce.RoomsManager;
String roomId = RoomsManager.INSTANCE.createRoomFromDocument(authorDocumentModel) This can be called in the
          ro.sync.ecss.extensions.api.webapp.access.WebappEditingSessionLifecycleListener.editingSessionStarted()
          listener. 
Note that the roomId is automatically stored in the editing context and
          it can be obtained when needed by calling: String roomId =
            authorDocumentModel.getAuthorAccess().getEditorAccess().getEditingContext(),getAttribute(Room.ROOM_ID_ATTRIBUTE).
Adding New Editors in a Room
When a user tries to open a document in an editor that the CMS already created a room
          for, it can link the editor to the existing room by using the
          ro.sync.ecss.extensions.api.webapp.access.WebappEditingSessionLifecycleListener.editingSessionAboutToBeStarted()
          listener. In the implementation of this listener, the ID of the existing room has to be
          added to the sessionAttributes map using the
          ro.sync.ecss.extensions.api.webapp.ce.Room.ROOM_ID_ATTRIBUTE key.
Saving a Concurrent Editing Session
When saving a concurrently edited document, the application uses a save
            strategy that can be specified when creating the room by calling
          ro.sync.ecss.extensions.api.webapp.ce.RoomFactory.createRoom(AuthorDocumentModel,
            SaveStrategy).
The save strategy specifies how the changes are grouped when writing the changed document to the CMS. For example, if multiple users made changes to the document opened in the room since the last save, the save strategy can choose to save the final version to the CMS or to save intermediate versions, with every version containing changes from a single editor.
- ro.sync.ecss.extensions.api.webapp.ce.GroupChangesForSinglePeerStrategy- It facilitates tracking precise authorship of changes, as each written revision contains changes by only one author.Note:The- URLConnection openConnection(URL documentUrl, PeerContext author)method's- authorparameter can be used to determine the user that authored the version of the file that is going to be written in the returned- URLConnection.
- ro.sync.ecss.extensions.api.webapp.ce.GroupChangesForMultiplePeersStrategy- It facilitates a minimum number of writes to the file server per save.Note:The- URLConnection openConnection(URL documentUrl, PeerContext committer, List<PeerContext> authors)method has two parameters:- committer- It can be used to identify the user that triggered the save.
- authors- It can be used to identify the users that authored the version of the file that is going to be written in the returned- URLConnection.
 
GroupChangesForMultiplePeersStrategy.openConnection and
          GroupChangesForSinglePeerStrategy.openConnection (rather than relying
          on user credentials by calling url.openConnection) to prevent request
          failures due to expired or invalidated credentials.Closing the Room
A programmatically created room is not closed automatically when the
          last user leaves or closes the browser tab. The room should be closed explicitly using
          Room.close() when all the users have left and all the changes are
          saved. To identify when a room becomes empty, you can use
          WebappEditingSessionLifecycleListener.editingSessionStarted and
          WebappEditingSessionLifecycleListener.editingSessionClosed.
The WebappEditingSessionLifecycleListener.editingSessionStarted is
          called each time a tab with a Web Author editor is opened.
The WebappEditingSessionLifecycleListener.editingSessionClosed is called
          when the editing session closes. This happens in the following cases:
- When the user closes the tab or browser cleanly.
- If the tab or browser is not closed cleanly:- When the user's session expires (by default, this happens after 12 hours).
- When using the always.send.keepalive option and the timeout is reached.
 
To access the room object, you can use
          RoomsManager.INSTANCE.getRoom(roomId).
WebappEditingSessionLifecycleListener.editingSessionClosed (rather
            than relying on user credentials) to prevent request failures due to expired or
            invalidated credentials.