bfcf9756f5
UnitPrefork got what I assume is one of those PING frames that ChildProcess::isAlive() sends before the actual reply when it sent the "unit-memdump" message, and did not like it. Uncommenting the line that outputs the "memory stats" message it expects showed: Got memory stats 'PING' Followed by: Assertion `tokens.count() == 2' failed. Fix by factoring out the handling of PING frames, PONG frames, and the pseudo-PONG frames that we send ourselves in reply to PING frames into a new function IoUtil::receiveFrame(). Use that in a couple of places. (Probably should use in many more places.) Getting past this then leads to later cppunit tests again being run, and their failures then again showing up...
325 lines
11 KiB
Text
325 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>]
|
|
|
|
All parameters are numbers.
|
|
|
|
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.
|