libreoffice-online/loolwsd/protocol.txt
Ashod Nakashian 83307291ec Document id argument of tile and tilecombine
Change-Id: Ia43ceae31936f68d2bed04b5291a25eeffc637b3
Reviewed-on: https://gerrit.libreoffice.org/24676
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-05 11:37:24 +00:00

330 lines
11 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
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.
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().
takeedit
Request for an edit lock. If successful, client will receive an 'editlock: 1'
message meaning editlock is granted.
See 'editlock:' message in server -> client.
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'.
pong
Sent instead of a PONG frame as reply to a PING frame. A comment
in our code says "Technically, we should send back a PONG control
frame. However Firefox (probably) or Node.js (possibly) doesn't
like that and closes the socket when we do."
server -> client
================
loolserver <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.
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
editlock: <1 or 0>
Informs the client of any change in ownership of edit lock. A value of '1'
means client can edit the document, and '0' means that client can only view
the document. This message always follows the 'status:' message after a
document is loaded, so that client has this information as soon as it loads
the document.
Note that only one client can have the editlock at a time and
others can only view.
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, like the "loadtest" program in the loolwsd sources).
status: type=<typeName> parts=<numberOfParts> current=<currentPartNumber> width=<width> height=<height> [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. }
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:
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.
pong
See above.
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.