46107dd0c8
This replaces addview/remview/remallview messages in the protocol with 'viewinfo' message which is sent whenever there is any change in the view information. Let the client deal with what information is redundant to it. Change-Id: Ic470ea88a94ff281a0ae021014a9fba1b876f648
496 lines
16 KiB
Text
496 lines
16 KiB
Text
All communication consists of messages that are one line of
|
|
human-readable UTF-8 text (with no terminating newline), optionally
|
|
followed by a single newline and arbitrary (potentialy even binary)
|
|
data.
|
|
|
|
The WebSocket distinction between 'text' and 'binary' frames has no
|
|
meaning for us for messages that don't contain additional binary data;
|
|
such messages can be either 'binary' or 'text' from the WebSocket
|
|
point of view even if we require them (the single line) to be
|
|
UTF-8. In other words, an implementation is free to send such a
|
|
single-line message as a WebSocket 'binary' frame, and the receiving
|
|
implementation must treat that equally as if it was a 'text' frame.
|
|
|
|
The WebSocket protocol says that 'text' frames are to be "interpreted"
|
|
as UTF-8, so it is probably best to indeed use 'binary' frames for
|
|
messages that contain optional non-UTF-8 data.
|
|
|
|
The protocol is not a request-response one. Messages may be sent in
|
|
either direction at any time, either in response to some message, or
|
|
spontaneously. For 'tile' messages, the client may send a bunch of
|
|
tile requests without waiting for return messages. The server may send
|
|
tiles proactively (guessing what the client might need). Etc.
|
|
|
|
client -> server
|
|
================
|
|
|
|
canceltiles
|
|
|
|
All outstanding tile messages from the client to the server are
|
|
dropped and will not be handled. There is no guarantee of exactly
|
|
which tile: messages might still be sent back to the client.
|
|
|
|
downloadas name=<fileName> id=<id> format=<document format> options=<SkipImages, etc>
|
|
|
|
Exports the current document to the desired format and returns a download URL
|
|
The id identifies the request on the client.
|
|
|
|
getchildid
|
|
|
|
Requests the child id so that it knows where the files needs to be sent when it is
|
|
inserted in the document
|
|
|
|
gettextselection mimetype=<mimeType>
|
|
|
|
Request selection's content
|
|
|
|
paste mimetype=<mimeType>
|
|
<binaryPasteData>
|
|
|
|
Paste content at the current cursor position.
|
|
|
|
insertfile name=<name> type=<type>
|
|
|
|
Inserts the file with the name <name> into the document, we currently support type = 'graphic'
|
|
|
|
key type=<type> char=<charcode> key=<keycode>
|
|
|
|
<type> is 'input' or 'up', <charcode> and <keycode> are numbers.
|
|
|
|
load <pathname>
|
|
|
|
Deprecated.
|
|
|
|
load [part=<partNumber>] url=<url> [timestamp=<time>] [options=<options>]
|
|
|
|
part is an optional parameter. <partNumber> is a number.
|
|
|
|
timestamp is an optional parameter. <time> is provided in microseconds
|
|
since the Unix epoch - midnight, January 1, 1970.
|
|
|
|
options are the whole rest of the line, not URL-encoded, and must be valid JSON.
|
|
|
|
loolclient <major.minor[-patch]>
|
|
|
|
Upon connection, a client must announce the version number it supports.
|
|
Major: an integer that must always match between client and server,
|
|
otherwise there are no guarantees of any sensible
|
|
compatibility. This is bumped when API changes.
|
|
Minor: an integer is more flexible and is at the discretion of either party.
|
|
Security fixes that do not alter the API would bump the minor version number.
|
|
Patch: an optional string that is informational.
|
|
|
|
mouse type=<type> x=<x> y=<y> count=<count>
|
|
|
|
<type> is 'buttondown', 'buttonup' or 'move', others are numbers.
|
|
|
|
renderfont font=<font>
|
|
|
|
requests the rendering of the given font.
|
|
The font parameter is URL encoded
|
|
|
|
requestloksession
|
|
|
|
requests the initialization of a LOK process in an attempt to predict the user's
|
|
interaction with the document
|
|
|
|
resetselection
|
|
|
|
saveas url=<url> format=<format> options=<options>
|
|
|
|
<url> is a URL, encoded. <format> is also URL-encoded, i.e. spaces as %20 and it can be empty
|
|
options are the whole rest of the line, not URL-encoded, and can be empty
|
|
|
|
selecttext type=<type> x=<x> y=<y>
|
|
|
|
<type> is 'start', 'end' or 'reset', <x> and <y> are numbers.
|
|
|
|
selectgraphic type=<type> x=<x> y=<y>
|
|
|
|
<type> is 'start' or 'end' <x> and <y> are numbers.
|
|
|
|
setclientpart part=<partNumber>
|
|
|
|
Informs the server that the client changed to part <partNumber>.
|
|
|
|
status
|
|
|
|
styles
|
|
|
|
tile part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth>
|
|
tileheight=<tileHeight> [timestamp=<time>] [id=<id>]
|
|
|
|
All parameters are numbers.
|
|
|
|
Note: id must be echoed back in the response verbatim. It is used
|
|
by Impress to render the slide thumbnails. It is only useful to
|
|
loleaflet and will break it if not returned in the response.
|
|
|
|
tilecombine <parameters>
|
|
|
|
Accept same parameters as 'tile' message except parameters 'tileposx' and 'tileposy'
|
|
can be a comma separated list, and number of elements in both must be same.
|
|
|
|
uno <command>
|
|
|
|
<command> is a line of text.
|
|
|
|
partpagerectangles
|
|
|
|
Invokes lok::Document::getPartPageRectangles().
|
|
|
|
clientvisiblearea x=<x> y=<y> width=<width> height=<height>
|
|
|
|
Invokes lok::Document::setClientVisibleArea().
|
|
|
|
useractive
|
|
|
|
Sent when the user regains focus or clicks within the active area to
|
|
disable the inactive state.
|
|
Will send invalidation and update notifications to force refreshing the screen.
|
|
|
|
See 'userinactive'.
|
|
|
|
userinactive
|
|
|
|
Sent when the user has switched tabs or away from the Browser altogether.
|
|
It should throttle updates until the user is active again.
|
|
|
|
See 'useractive'.
|
|
|
|
server -> client
|
|
================
|
|
|
|
loolserver <loolwsd version> <loolwsd git hash> <major.minor[-patch]>
|
|
|
|
Upon connection, the server must announce the version number it supports.
|
|
Major: an integer that must always match between client and server,
|
|
otherwise there are no guarantees of any sensible
|
|
compatibility. This is bumped when API changes.
|
|
Minor: an integer is more flexible and is at the discretion of either party.
|
|
Security fixes that do not alter the API would bump the minor version number.
|
|
Patch: an optional string that is informational.
|
|
|
|
lokitversion <JSON string>
|
|
|
|
JSON string contains version information in format:
|
|
{ProductName: <>, ProductVersion: <>, ProductExtension: <>, BuildId: <>}
|
|
|
|
Eg: {"ProductName": "LibreOffice",
|
|
"ProductVersion": "5.3",
|
|
"ProductExtension": ".0.0.alpha0",
|
|
"BuildId": "<full 40 char git hash>"}
|
|
|
|
contextmenu: <json description of the context menu>
|
|
|
|
When the user right-clicks in the document, the content of the context
|
|
menu is sent back via this callback.
|
|
|
|
The structure of the context menu is a JSON, and looks like:
|
|
|
|
{
|
|
"menu": [
|
|
{ "text": "label text1", "type": "command", "command": ".uno:Something1", "enabled": "true" },
|
|
{ "text": "label text2", "type": "command", "command": ".uno:Something2", "enabled": "false" },
|
|
{ "type": "separator" },
|
|
{ "text": "label text2", "type": "menu", "menu": [ { ... }, { ... }, ... ] },
|
|
...
|
|
]
|
|
}
|
|
|
|
downloadas: jail=<jail directory> dir=<a tmp dir> name=<name> port=<port>
|
|
|
|
The client should then request http://server:port/jail/dir/name in order to download
|
|
the document
|
|
|
|
error: cmd=<command> kind=<kind> [code=<error_code>]
|
|
<freeErrorText>
|
|
|
|
<command> is the command part of the corresponding client->server
|
|
message that caused the error. <kind> is some single-word
|
|
classification
|
|
|
|
<code> (when provided) further specifies the error as forwarded from
|
|
LibreOffice
|
|
|
|
getchildid: id=<id>
|
|
|
|
Returns the child id
|
|
|
|
invalidate: part=<partNumber> x=<x> y=<y> width=<width> height=<height>
|
|
|
|
All parameters are numbers. Tells the client to invalidate any
|
|
cached tiles for the document area specified (in twips), at any
|
|
zoom level.
|
|
|
|
The client should handle either this message or the
|
|
invalidatetiles: message, which has a different syntax, with
|
|
payload directly from the LOK_CALLBACK_INVALIDATE_TILES
|
|
callback. (The latter does not contain a part number, and as the
|
|
protocol is asynchronous, it is unclear whether a client can be
|
|
sure, or find out with certainty, for what part the
|
|
invalidatetiles: message is. The invalidatetiles: message will be
|
|
dropped soon.)
|
|
|
|
nextmessage: size=<byteSize>
|
|
|
|
<byteSize> is the size, in bytes, of the next message, in case it
|
|
is "large". (In practice, nextmessage: messages precede each tile:
|
|
message). Can be ignored by clients using an API that can read
|
|
arbitrarily large buffers from a WebSocket (like JavaScript), but
|
|
must be handled by clients that cannot (like those using Poco
|
|
1.6.0.
|
|
|
|
status: type=<typeName> parts=<numberOfParts> current=<currentPartNumber> width=<width> height=<height> viewid=<viewId> [partNames]
|
|
|
|
<typeName> is 'text, 'spreadsheet', 'presentation', 'drawing' or 'other. Others are numbers.
|
|
if the document has multiple parts and those have names, part names follow separated by '\n'
|
|
|
|
styles: {"styleFamily": ["styles in family"], etc. }
|
|
|
|
statechanged: <key>=<value>
|
|
|
|
Notifies client of state changed events of <key>.
|
|
Eg: 'statechanged: .uno:Undo=enabled'
|
|
|
|
partpagerectangles: <payload>
|
|
|
|
Payload format is the same as LOK_CALLBACK_TEXT_SELECTION.
|
|
|
|
textselectioncontent: <content>
|
|
|
|
Current selection's content
|
|
|
|
tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth> tileheight=<tileHeight> [timestamp=<time>] [renderid=<id>]
|
|
<binaryPngImage>
|
|
|
|
The parameters from the corresponding 'tile' command.
|
|
|
|
Additionally, in a debug build, the renderid is either a unique
|
|
identifier, different for each actual call to LibreOfficeKit to
|
|
render a tile, or the string 'cached' if the tile was found in the
|
|
cache.
|
|
|
|
Each LOK_CALLBACK_FOO_BAR callback causes a corresponding message to
|
|
the client, consisting of the FOO_BAR part in lowercase, without
|
|
underscore, followed by a colon, space and the callback payload. For
|
|
instance:
|
|
|
|
invalidatecursor: <payload>
|
|
|
|
The payload contains a rectangle describing the cursor position.
|
|
|
|
invalidatetiles: <payload>
|
|
|
|
The communication between the parent process (the one keeping open the
|
|
Websocket connections to the clients) and a child process (handling
|
|
one document through LibreOfficeKit) uses the same protocol, with
|
|
the following additions and changes:
|
|
|
|
unocommandresult: <payload>
|
|
|
|
Callback that an UNO command has finished.
|
|
See LOK_CALLBACK_UNO_COMMAND_RESULT for details.
|
|
|
|
invalidateviewcursor:
|
|
|
|
Per-view cursor position invalidation. JSON payload.
|
|
|
|
textviewselection:
|
|
|
|
Per-view text selection bounds. JSON payload.
|
|
|
|
cellviewcursor:
|
|
|
|
Per-view cell cursor position. JSON payload.
|
|
|
|
graphicviewselection:
|
|
|
|
Per-view graphic selection. JSON payload.
|
|
|
|
viewcursorvisible:
|
|
|
|
Per-view cursor visible. JSON payload.
|
|
|
|
viewlock:
|
|
|
|
Per-view lock rectangle. JSON payload.
|
|
|
|
viewinfo: <payload>
|
|
|
|
Message is sent everytime there is any change in view information.
|
|
<payload> consists of an array of JSON objects. Structure of JSON
|
|
objects is like : {"id": <viewid>, "username": <Full Name of the user>}
|
|
|
|
redlinetablechanged:
|
|
|
|
Signals that the redlines table has been modified.
|
|
Redlines are used for tracking changes.
|
|
|
|
|
|
child -> parent
|
|
===============
|
|
|
|
child <id>
|
|
|
|
Must be the first message sent from the child to the parent. The
|
|
parent has passed the id (a 64-bit random number) to the child
|
|
when starting it, so this is how the child identificates itself.
|
|
|
|
curpart: part=<partNumber>
|
|
|
|
Sent to the parent process before certain messages that the parent
|
|
needs to act on in addition to passing them on to the client, like
|
|
invalidatetiles:
|
|
|
|
nextmessage: size=<upperlimit>
|
|
|
|
each tile: message sent from the child to the parent is preceded
|
|
by a nextmessage: message that gives an upper limit on the size of
|
|
the tile: message that will follow. (We assume it is only tile:
|
|
messages that can be "large".) Once we depend on Poco 1.6.1, where
|
|
one doesn't need to use a pre-allocated buffer when receiving
|
|
WebSocket messages, this will go away.
|
|
|
|
saveas: url=<url>
|
|
|
|
<url> is a URL of the destination, encoded. Sent from the child to the
|
|
parent after a saveAs() completed.
|
|
|
|
Admin console
|
|
===============
|
|
|
|
Client can query admin console to get information about currently opened
|
|
documents. Following information about the document is exposed:
|
|
|
|
* PID of the process hosting the document
|
|
* Number of client views opening this document
|
|
* Name of the document (URL encoded)
|
|
* Memory consumed by the process (in kilobytes)
|
|
* Elapsed time since first view of document was opened (in seconds)
|
|
|
|
Admin console can also opt to get notified of various events on the server. For
|
|
example, getting notified when a new document is opened or closed. Notifications
|
|
are commands sent from server to the client over established websocket.
|
|
|
|
Before doing anything, clients must authenticate by providing an auth token with
|
|
'auth' command.
|
|
|
|
client -> admin
|
|
==============
|
|
|
|
auth jwt=<jwtToken>
|
|
|
|
Authenticate the client with provided jwtToken. This is necessary before any
|
|
other command.
|
|
|
|
subscribe <space seperated list of commands>
|
|
|
|
Where list of commands are the ones that client wants to get notified
|
|
about. For eg. 'subscribe adddoc rmdoc'
|
|
|
|
documents
|
|
|
|
Queries the server for list of opened documents. See `documents` command
|
|
in admin -> client section for format of the response message
|
|
|
|
total_mem
|
|
|
|
Queries for total memory being consumed by the server in kilobytes.
|
|
This includes processes - loolwsd, loolforkit, and child processes
|
|
hosting various documents
|
|
|
|
active_docs_count
|
|
|
|
Returns total number of documents opened
|
|
|
|
active_users_count
|
|
|
|
Returns total number of users connected. This is a summation of number
|
|
of views opened of each document.
|
|
|
|
settings
|
|
|
|
Queries the server for configurable settings from admin console.
|
|
|
|
set <setting1=value1> <setting2=value2> ...
|
|
|
|
Sets a particular setting (must be one returned as response to
|
|
`settings` command) to value.
|
|
|
|
There are only 4 configurable settings as of now.
|
|
|
|
mem_stats_size: Number of memory consumed values that server caches
|
|
atmost.
|
|
mem_stats_interval: Time after which server calculates its total memory
|
|
consumption
|
|
cpu_stats_size: Number of cpu usage values that server caches atmost.
|
|
cpu_stats_interval: Time after which server calculates its total cpu
|
|
usage.
|
|
|
|
Note: cpu stats gathering is a TODO, so not functional as of now.
|
|
|
|
kill <pid>
|
|
|
|
<pid> process id of the document to kill. All sessions of document would be
|
|
killed. There is no way yet to kill individual sessions.
|
|
|
|
admin -> client
|
|
===============
|
|
|
|
Commands marked with [*] are notifications that are delivered only if client is
|
|
subscribed to these commands using `subscribe` (see client->admin
|
|
section). Others are just response messages to some client command.
|
|
|
|
[*] adddoc <pid> <filename> <viewid> <memory consumed>
|
|
|
|
<pid> process id hosting the document
|
|
<filename> URL encoded name of the file
|
|
<viewid> string identifying the view of this document
|
|
<memory consumed> RSS of <pid> in kilobytes
|
|
|
|
[*] rmdoc <pid> <viewid>
|
|
|
|
<pid> process id hosting the document
|
|
<viewid> view which was closed
|
|
|
|
[*] mem_stats <memory consumed>
|
|
|
|
<memory consumed> in kilobytes sent from admin -> client after every
|
|
mem_stats_interval (see `set` command for list of settings)
|
|
|
|
InvalidAuthToken
|
|
|
|
This is sent when invalid auth token is provided in 'auth' command. See
|
|
above.
|
|
|
|
NotAuthenticated
|
|
|
|
When client sends an admin command that requires authentication.
|
|
|
|
documents <pid> <filename> <number of views> <memory consumed> <elapsed time>
|
|
<pid> <filename> ....
|
|
...
|
|
|
|
<elapsed time> is in seconds since the first view of the document was opened
|
|
<number of views> Number of users/views opening this(<pid>) document
|
|
Other parameters are same as mentioned in `adddoc`
|
|
|
|
Each set document attributes is separated by a newline.
|
|
|
|
total_mem <memory>
|
|
|
|
<memory> in kilobytes
|
|
|
|
active_docs_count <count>
|
|
|
|
active_users_count <count>
|
|
|
|
settings <setting1=value1> <setting2=value2> ...
|
|
|
|
Current value of each configurable setting.
|
|
|
|
mem_stats <comma separated list of memory consumed values>
|
|
|
|
The length of the list is equal to the value of setting
|
|
mem_stats_size`
|