aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2020-06-20 23:50:46 +0200
committerTom Smeding <tom.smeding@gmail.com>2020-06-20 23:50:46 +0200
commitbc3ce98673a961bf6886efe1f63345a80d8a9f3b (patch)
tree218b0c8f08bdc363515ea403e947b5e6aede559e
parent970bbda9c884e36c7148a7d921d67c8253c13cdb (diff)
Add protocol description
-rw-r--r--TODO.txt2
-rw-r--r--protocol.md161
2 files changed, 163 insertions, 0 deletions
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..554ee05
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,2 @@
+- Somehow communicate (push? poll?) to room members whether a particular user is currently _active_, not just online.
+- A session is marked inactive 2 minutes after the latest activity on that session. Make the number "2" configurable and not a hard-coded constant.
diff --git a/protocol.md b/protocol.md
new file mode 100644
index 0000000..aa6de82
--- /dev/null
+++ b/protocol.md
@@ -0,0 +1,161 @@
+# tomsg protocol
+
+The underlying transport of the protocol is a plain TCP socket. The individual
+messages are all line-based; this means that a single message, both
+client->server and server->client, always ends with a newline (ASCII 10)
+character.
+
+Preliminary definitions:
+- A _string_ is a series of non-zero bytes. To allow for clients written in
+ languages that automatically parse strings as UTF-8, argument strings should
+ always be valid UTF-8. However, the server currently does not care.
+- A _word_ is a string without spaces (ASCII 32) or newlines. Note that the
+ empty string is also a valid word.
+
+There are three kinds of messages: commands from the client, command responses
+from the server, and push messages from the server (not to be confused with push
+_notifications_). These three kinds are described below.
+
+In the syntax descriptions below, `<name>` indicates an argument called "name";
+the angle brackets are not part of the syntax. The type of the argument may be
+indicated with the notation `<name:type>`; possible types are `i64` (a 64-bit
+signed integer in decimal notation), `word` (a word), and `string...` (a string
+stretching until the end of the line).
+
+A message from client to server consists of a _tag_, a space, the command name,
+a space, and finally the arguments to the command. The tag is a word, and may be
+arbitrarily chosen by the client; it will be returned by the server in its
+response to the client's message, so that the client can easily link requests
+and responses.
+
+All client commands, if not syntactically invalid, will be replied to with a
+server response.
+
+A _response_ from the server will be in one of the following forms:
+- `<tag> ok`
+ - The message from the client was successfully processed.
+- `<tag> number <num:i64>`
+ - A numeric value was returned.
+- `<tag> error <message:string...>`
+ - The client's message was successfully parsed, but handling resulted in an
+ error described in the message.
+- `<tag> list <count:i64> words...`
+ - A list of words was returned. The number of words returned is given in
+ `<count>`; the words themselves are space-separated further arguments to
+ `list`.
+- `<tag> pong`
+ - Response to the client's `ping` command.
+- `<tag> history <count:i64>`
+ - Response to the client's `history` command; is followed by exactly `<count>`
+ messages of type `history_message` with the same tag. The messages are
+ returned in reverse chronological order (newest first).
+- `<tag> history_message <index:i64> <roomname:word> <user:word> <timestamp:i64> <msgid:i64> <message:string...>`
+ - Part of the response to the client's `history` command. Index 0 is the
+ newest message; index (`<count>` - 1) (from the `history` response) is the
+ oldest message in the fragment requested. Timestamps are microseconds since
+ the UNIX epoch. The message id for each message is globally unique for the
+ entire server.
+
+A command is identified by its name, which can be found in the list below. Its
+arguments are zero or more words, except if for the command in question the last
+argument is of type `string...` (in which case it may contain spaces and
+ranges until the end of the line).
+
+- `<tag> register <user:word> <pass:string...>`
+ - Register a new user on the server. The password may contain spaces.
+ - Returns `ok` or `error`.
+- `<tag> login <user:word> <pass:string...>`
+ - Logs in as the specified user.
+ - Returns `ok` or `error`.
+- `<tag> logout`
+ - Logs out of the user the client is currently logged in as. If the client is
+ not logged in, does nothing.
+ - Returns `ok`.
+- `<tag> list_rooms`
+ - Lists all rooms the user is a member of.
+ - Returns `list` or `error`.
+- `<tag> list_members <roomname:word>`
+ - Lists all members of the given room, if the user is also a member.
+ - Returns `list` or `error`.
+- `<tag> create_room`
+ - Creates a new room, and enters the room. The id of the room is returned to
+ the client. Returns an error if the client is not logged in.
+
+ Also marks the current session as active.
+ - Returns `name` or `error`.
+- `<tag> invite <roomname:word> <user:word>`
+ - Invites the given user to the given room, if the client is currently a
+ member of that room. The invited user is immediately added to the room.
+
+ If the invite succeeds, the invited user receives a `_push invite` push
+ message on all its sessions, and all current room members receive a
+ `_push join` push message on all their sessions (except the session the
+ `invite` message was sent from).
+
+ Also marks the current session as active.
+ - Returns `ok` or `error`.
+- `<tag> send <roomname:word> <message:string...>`
+ - Sends a message to the given room. All room members receive a
+ `_push message` push message on all their sessions (except the session the
+ `send` message was sent from).
+
+ Also marks the current session as active.
+ - Returns `ok` or `error`.
+- `<tag> history <roomname:word> <number:i64>`
+ - Requests the last `<number>` messages in the given room, if the client is a
+ member of the room. In the `history` response, `<count>` will be at most
+ `<number>`, and may be less if the room does not yet have `<number>`
+ messages. Each message will be returned in a `history_message` response
+ after the `history` response, in reverse chronological order.
+ - Returns `history`, followed by zero or more `history_message`.
+- `<tag> history_before <roomname:word> <number:i64> <msgid:i64>`
+ - Same as `history`, except the returned messages are the last `<number>`
+ strictly before the timestamp of the message with id `<msgid>`.
+ - Returns `history`, followed by zero or more `history_message`.
+- `<tag> ping`
+ - Asks for a `pong` response.
+ - Returns `pong`.
+- `<tag> is_online <user:word>`
+ - Returns with how many sessions the given user is currently online.
+ - Returns `number` or `error`.
+- `<tag> firebase_token <token:word>`
+ - Adds the given Firebase token to the account of the current user. This is
+ used for new-message push notifications for Android-based clients.
+ - Returns `ok` or `error`.
+- `<tag> delete_firebase_token <token:word>`
+ - Removes the given Firebase token from the account of the current user.
+ - Returns `ok` or `error`.
+- `<tag> user_active <active:i64>`
+ - Marks the user as active (if `active` > 0) or inactive (if `active`
+ <= 0) on the current session. This does not influence whether the user is
+ marked active on any of the other sessions on which they are currently
+ logged in.
+
+ A session is automatically marked inactive 2 minutes after the latest
+ activity on that session.
+
+ This is used for Firebase notifications: a user will only receive Firebase
+ notifications if they are marked inactive on all their sessions, or if they
+ have no active sessions.
+ - Returns `ok` or `error`.
+
+Push messages from the server are formatted like responses with tag `_push`.
+These are not sent in response to a particular client message, but are sent by
+the server due to other events. Some have already been mentioned above, but all
+are listed below.
+
+- `_push online <numonline:i64> <user:word>`
+ - When user X logs in or logs out in a session, all sessions of all members
+ (excluding user X) of all rooms user X is a member of receive a `_push
+ online` push message stating that `<user>` (user X) is now online with
+ `<numonline>` sessions.
+- `_push message <roomname:word> <user:word> <timestamp:i64> <message:string...>`
+ - Sent to all sessions of all members of a room in which a message is
+ posted, except the session that sent the message.
+- `_push invite <roomname:word>`
+ - Sent to all sessions of the invited user after an `invite` command.
+- `_push join <roomname:word> <user:word>`
+ - Sent to all sessions of all members of a room (except the session sending
+ the `invite` command) in which a new user entered.
+- `_push ping`
+ - Sent by the server once in a while. Please ignore.