Broadcast command result back to clients
This is required to tell the clients if the command they issued was successfull or not. In this case 'savetostorage' is the command that we are interested in knowing the success status of. With this, now if the user commands to overwrite the document, dialog boxes of all other users are automatically closed. Can easily more commands in future for this kind of thing. Its similar to unocommandresult, except its not a uno command, but our internal command. Change-Id: I2e7e1fd5edbd55c13ee4bf9bce24284483d6507f
This commit is contained in:
parent
dce714efb8
commit
f4b22bbb3c
5 changed files with 41 additions and 11 deletions
|
@ -221,6 +221,18 @@ L.Socket = L.Class.extend({
|
||||||
this._map.fire('wopiprops', wopiInfo);
|
this._map.fire('wopiprops', wopiInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (textMsg.startsWith('commandresult: ')) {
|
||||||
|
var commandresult = JSON.parse(textMsg.substring(textMsg.indexOf('{')));
|
||||||
|
if (commandresult['command'] === 'savetostorage' && commandresult['success']) {
|
||||||
|
// Close any open confirmation dialogs
|
||||||
|
if (vex.dialogID > 0) {
|
||||||
|
var id = vex.dialogID;
|
||||||
|
vex.dialogID = -1;
|
||||||
|
vex.close(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (textMsg.startsWith('close: ')) {
|
else if (textMsg.startsWith('close: ')) {
|
||||||
textMsg = textMsg.substring('close: '.length);
|
textMsg = textMsg.substring('close: '.length);
|
||||||
msg = '';
|
msg = '';
|
||||||
|
|
|
@ -226,7 +226,10 @@ bool ClientSession::_handleInput(const char *buffer, int length)
|
||||||
{
|
{
|
||||||
int force = 0;
|
int force = 0;
|
||||||
getTokenInteger(tokens[1], "force", force);
|
getTokenInteger(tokens[1], "force", force);
|
||||||
docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true);
|
if (docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true))
|
||||||
|
{
|
||||||
|
docBroker->broadcastMessage("commandresult: { \"command\": \"savetostorage\", \"success\": true }");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -627,6 +627,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId,
|
||||||
|
|
||||||
// So set _documentLastModifiedTime then
|
// So set _documentLastModifiedTime then
|
||||||
_documentLastModifiedTime = _storage->getFileInfo()._modifiedTime;
|
_documentLastModifiedTime = _storage->getFileInfo()._modifiedTime;
|
||||||
|
|
||||||
// After a successful save, we are sure that document in the storage is same as ours
|
// After a successful save, we are sure that document in the storage is same as ours
|
||||||
_documentChangedInStorage = false;
|
_documentChangedInStorage = false;
|
||||||
|
|
||||||
|
@ -662,11 +663,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId,
|
||||||
{
|
{
|
||||||
LOG_ERR("PutFile says that Document changed in storage");
|
LOG_ERR("PutFile says that Document changed in storage");
|
||||||
_documentChangedInStorage = true;
|
_documentChangedInStorage = true;
|
||||||
// Inform all clients
|
broadcastMessage("error: cmd=storage kind=documentconflict");
|
||||||
for (const auto& sessionIt : _sessions)
|
|
||||||
{
|
|
||||||
sessionIt.second->sendTextFrame("error: cmd=storage kind=documentconflict");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1418,6 +1415,17 @@ void DocumentBroker::closeDocument(const std::string& reason)
|
||||||
terminateChild(reason, false);
|
terminateChild(reason, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DocumentBroker::broadcastMessage(const std::string& message)
|
||||||
|
{
|
||||||
|
assertCorrectThread();
|
||||||
|
|
||||||
|
LOG_DBG("Broadcasting message [" << message << "] to all sessions.");
|
||||||
|
for (const auto& sessionIt : _sessions)
|
||||||
|
{
|
||||||
|
sessionIt.second->sendTextFrame(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DocumentBroker::updateLastActivityTime()
|
void DocumentBroker::updateLastActivityTime()
|
||||||
{
|
{
|
||||||
_lastActivityTime = std::chrono::steady_clock::now();
|
_lastActivityTime = std::chrono::steady_clock::now();
|
||||||
|
|
|
@ -339,6 +339,9 @@ public:
|
||||||
/// Sends the .uno:Save command to LoKit.
|
/// Sends the .uno:Save command to LoKit.
|
||||||
bool sendUnoSave(const std::string& sessionId, bool dontTerminateEdit = true, bool dontSaveIfUnmodified = true);
|
bool sendUnoSave(const std::string& sessionId, bool dontTerminateEdit = true, bool dontSaveIfUnmodified = true);
|
||||||
|
|
||||||
|
/// Sends a message to all sessions
|
||||||
|
void broadcastMessage(const std::string& message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// Shutdown all client connections with the given reason.
|
/// Shutdown all client connections with the given reason.
|
||||||
|
|
|
@ -334,6 +334,10 @@ tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<
|
||||||
a hash of the tile contents, and can be included by the client in
|
a hash of the tile contents, and can be included by the client in
|
||||||
the next 'tile' message requesting the same tile.
|
the next 'tile' message requesting the same tile.
|
||||||
|
|
||||||
|
commandresult: <payload>
|
||||||
|
This is used to acknowledge the commands from the client.
|
||||||
|
<payload> is { command: <command name>, success: 'true' }
|
||||||
|
|
||||||
Each LOK_CALLBACK_FOO_BAR callback except
|
Each LOK_CALLBACK_FOO_BAR callback except
|
||||||
LOK_CALLBACK_INVALIDATE_TILES causes a corresponding message to the
|
LOK_CALLBACK_INVALIDATE_TILES causes a corresponding message to the
|
||||||
client, consisting of the FOO_BAR part in lowercase, without
|
client, consisting of the FOO_BAR part in lowercase, without
|
||||||
|
@ -343,12 +347,12 @@ message as documented above.) For instance:
|
||||||
|
|
||||||
invalidatecursor: <payload>
|
invalidatecursor: <payload>
|
||||||
|
|
||||||
The payload contains a rectangle describing the cursor position.
|
The payload contains a rectangle describing the cursor position.
|
||||||
|
|
||||||
The communication between the parent process (the one keeping open the
|
The communication between the parent process (the one keeping open the
|
||||||
Websocket connections to the clients) and a child process (handling
|
Websocket connections to the clients) and a child process (handling
|
||||||
one document through LibreOfficeKit) uses the same protocol, with
|
one document through LibreOfficeKit) uses the same protocol, with
|
||||||
the following additions and changes:
|
the following additions and changes:
|
||||||
|
|
||||||
unocommandresult: <payload>
|
unocommandresult: <payload>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue