Skip to content

Pronovix/gopush

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

81 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Requirements

  • Go 1
  • MySQL
  • Mercurial (to download dependencies)

How to run

bin/gopush_server

How to configure

$ cp config.json.sample config.json # first time only
$ vim config.json

Build

Use make and make install as usual. On the developer machines, make is enough. The server executable will be under bin. Automatic tests will run on build.

Database notes

The service will create a table called APIToken on its first launch.

Testing with database

By default, testing skips the MySQL tests. If you want to test with MySQL, use the following command line switches:

  • mysqluser: MySQL user name
  • mysqlpass: MySQL password
  • mysqldbname: Name of the MySQL database to use.

Alternatively, you can create a file called mysql.json in the test directory, which contains the MySQL credentials (see below the configuration format).

How to test manually

  • Start the main server

  • Add a user through http://localhost:8080/admin

  • Copy its private key to a file, say privkey.pem

  • Run the test client and add a notification center $ GOPATH="`pwd`" go run src/testclient/testclient.go --privkey=privkey.pem --mail="test@example.com" --centername="test" --action=new This will return the name of the newly created notification center. It is now ${mail}____${centername}, but it can be changed any time in the future!

  • Start the test server to load the test console $ GOPATH="`pwd`" go run src/testserver/testserver.go --address=localhost:8080/listen

  • Open http://localhost:8081/?center=$NAME_OF_THE_CENTER_YOU_CREATED

  • You can now send notifications $ GOPATH="`pwd`" go run src/testclient/testclient.go --privkey=privkey.pem --mail="test@example.com" --centername="test" --action=notify --message=test

Notes on scalability

Go uses very lightweight thread-like channels, called goroutines. These are multiplexed between real threads. The way now the scheduler works, you have to manually specify how many threads you want to use. The service currently defaults to the number of logical CPUs available. If you want to override this, use the --procs=N command line flag to manually specify how many CPUs the service can use.

The reason why it's important to run it as much logical CPUs as possible is the way how the goroutines gets scheduled. When a goroutine runs, the thread works on that only one goroutine. When the goroutine gets blocked, the scheduler switches to the next goroutine. When a goroutine is running, it won't be sent to the background (unlike processes or threads). It's important to realize that if only one CPU gets utilized, and one goroutine is running for a longer time (generating a key for example), all other goroutines are blocked. To achieve really good and reliable response times, it's important to use as much CPUs as possible.

API Reference

Client

There are two ways for a client to get the notifications.

Using WebSockets (recommended)

The URL is /listen?center=$CENTERNAME. The $CENTERNAME is returned from the service when creating a new notification center (see below).

Javascript example:

    if (window["WebSocket"]) {
        conn = new WebSocket("ws://localhost:8080/listen?center=$CENTERNAME");
        conn.onclose = function(evt) {
            appendLog($("<div><b>Connection closed.</b></div>"))
        }
        conn.onmessage = function(evt) {
            appendLog($("<div/>").text(evt.data))
        }
    } else {
        appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"))
    }

Ping

For older browsers or clients, it might be a good idea to create a loop in JavaScript which checks a given URL for changes.

This method has a serious limitation: only the latest state is available. If the notifications gets produced really fast, this way the client might miss some.

The URL is /ping?center=$CENTERNAME

To circumvent the cross domain policy, this method also supports JSONP. To use it, add the callback= parameter to the request.

Manager

To create, delete notification centers and send messages through them, you have to send POST requests to the service. All POST requests has to be signed. The signing header is:

Authorization: GoPush $RSA_SIGNATURE_HEX_ENCODED

All requests must have a GET parameter called mail which identifies the user.

The signature

The signature is from an RSA key, generated by the service (on the /admin page). The signature format is RSA PKCS#1 v1.5. The hash method is SHA1.

Creating a new notification center

POST /newcenter?mail=$MAIL The body is the identifier of the new notification center.

Response: the name of the service. This name will be used with the clients to get updates from this notification center.

Deleting a notification center

POST /removecenter?mail=$MAIL The body is the identifier of the notification center.

Response: nothing, just 200 on success.

Sending a notification

POST /notify?mail=$MAIL&center=$CENTER_ID The body is the notification message.

Response: nothing just 200 on success.

Configuration Options

Options available in config.json

  • address (string) The address where the server will listen to. Use hostname:port or :port to listen on all hostnames.
  • dbname (string) Name of the MySQL database.
  • dbuser (string) Username for the MySQL database.
  • dbpass (string) Password of the MySQL user.
  • certfile (string) Absolute path to the SSL certificate file. Leave empty if you don't want to use SSL.
  • keyfile (string) Absolute path to the SSL private key. Leave empty if you don't want to use SSL.
  • adminuser (string) Administrator username for the admin page.
  • adminpass (string) Administrator password for the admin page.
  • timeout (integer) After a given timeout (in seconds), notification centers will be killed. Set it to 0 to disable this behavior.
  • usercache (boolean) Use an internal cache for the mail address => public key mappings. Recommended to be turned on, especially in production.
  • broadcastbuffer (integer) Buffer size for the broadcasting channel. Set it to a lower value if you have a lot of notification centers with very few messages. Set it to a higher value if you have a lot of clients and a lot of messages.
  • extralogging (boolean) Turns on very verbose logging. It can be really helpful for development, but turn it off in production.
  • redirectmainpage (string) The main page of the service is a 404 page, which is not a really nice thing. By setting this variable, the service will redirect its main page.

About

A push notification service written in Go.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published