Skip to content
fullphat edited this page Jun 25, 2019 · 69 revisions
  1. Introduction
  2. Overview
  3. Messages
  4. Forwarding
  5. Subscriptions
  6. Security

Introduction

SNP is a platform-agnostic network protocol used to transmit notifications between computers on the same network, or even across the Internet. It's highly extensible, supports encryption, and is both easy to read and easy to implement.

Key Features

  • TCP-based
  • No complex client or server infrastructure required
  • Supports signing (authorisation) and encryption
  • Easy to understand and troubleshoot
  • Can use standard tools to test
  • Wide platform and language support
  • Client and server can be on different machines, different platforms and different networks

Variants

There are two variants of SNP:

  • SNP: A simple TCP-based protocol
  • WebSNP: Previously known as SNP/HTTP, this protocol utilises HTTP GET requests to communicate with Snarl

WebSNP is probably the more suitable to use if you're starting out given how easy it is to implement a client that uses HTTP.

Here's an example using C#:

using (WebClient client = new WebClient())
{
    client.Encoding = Encoding.UTF8;
    string reply = client.DownloadString("http://192.168.1.16:8888/v1/notify?title=WebSNP Test&text=Just a test...&icon=!misc-alien");
}

And one using curl:

curl 'http://192.168.1.16:8888/v1/notify?title=WebSNP Test&text=Just a test...&icon=!misc-alien'

The above both generate the following notification:

Demo

Communication Overview

Communication takes place between a client and a server, with the client initiating the request and the server responding to the request appropriately. The client and server may be on the same host, on different hosts on the same network, or on different hosts on different networks. In all cases, the process is the same:

  1. The client opens a connection to the server
  2. The client issues a request
  3. The server takes action and issues an appropriate response
  4. The client then closes the connection

A client should always act accordingly based on the response it receives, as the response may differ even if the request remains the same. For example: a client may generate a series of notifications, which the end user eventually mutes. Once the client detects subsequent notifications have been muted, it should cease to send further notifications.

In addition to handling error responses from the server, a client must handle connection and data transfer errors itself as well. Typically, applications will use a library to handle their notifications, and the library will handle these types of error.

Messages

Three types of message are currently defined:

  • Request
  • Response
  • Signal

Request

A Request is sent from a client to a server and either requires the server to take some sort of action, or provide some information. The server may choose to accept or reject the request; either way, the server will reply with a Response message indicating success or failure.

The client may include additional information and metadata in a request. How this is implemented is protocol-specific.

Example SNP 3.1 Request:

SNP/3.1 NOTIFY
title: Hello, world!
text: Notifications are easy...
icon: !system-info
END

Example WebSNP Request:

GET /v1/notify?title=Hello, World! HTTP/1.1
Host: 192.168.1.16:8888
User-Agent: curl/7.54.0
Accept: */*

Response

A Response is received by a client from a server in reply to a previous Request. The response will typically indicate the result (success or failure) of a previous Request and may provide further information (for example, extended error information in the case of a failure) and metadata depending on the nature of the request.

Example SNP 3.1 Response:

SNP/3.1 SUCCESS
host: cs30
server: Snarl 5.1.0
END

Example WebSNP Response:

{
  "Meta": {
    "Success": true,
    "Code": 252,
    "Text": "Created",
    "Message": "",
    "Host": "GANYMEDE",
    "Server": "Snarl 5.1.0"
  },
  "Content": {
    "Value": 452
  }

Signal

In addition to the above request-response cycle, Snarl provides the ability for applications to receive messages sent asynchronously. These messages are known as signals and can be received by the client separately, and at any time. The most common signal is when Snarl notifies that a user has interacted with a notification in some way. Other signals include the notification disappearing without user interaction, or a subscribed-to server notifying that it is no longer offering subscriptions.

infoSee the individual protocol documentation for further details as implementation of signals typically differs between protocols.

Note that not all protocols support signals - check the individual protocol information for more details.

These messages can be received at any time due to the asynchronous nature of when a notification may expire, or when the user may react to a notification. Signals may be received on a listening TCP port or POSTed to a URL, either of which is specified by the client when the request that created the notification was sent. Out of cycle messages do not need to be responded to.

Security

Security covers two parts: authorisation and encryption. Authorisation ensures the receiving server trusts incoming messages from a particular client by validating that they both share a common secret (typically a password); encryption protects the contents of the message from inspection during its journey from the client to the server.

infoMessages can include authorisation without including encryption, however the reverse is not true, as encrypted messages rely on the key created during the authorisation process.

Authorisation

To authorise a message, the password must be translated into a key hash using a supported hash algorithm and salt value. See the Developer Guide for details on how to generate these values. This information is then included with the request when it is sent to the server.

noteNote that authorisation is not the same as authentication. Authentication applies to individual application registrations and ensures that one application cannot spoof notifications from another application.

Encryption

Encrypting a message requires both authorisation and a valid encryption algorithm and initialisation value. These are then used to encrypt the request content itself. Typically the content is encrypted into a byte array which is then hex-encoded as a single line, however the actual implementation is protocol-specific.