NAME

mercury - A message broker for WebSockets

VERSION

version 0.016

SYNOPSIS

mercury broker [-l <listen>]

DESCRIPTION

This is a message broker that enables some common messaging patterns over WebSockets.

WebSockets are a powerful tool, enabling many features previously impossible, difficult, or ugly for web developers to implement. Where once only an HTTP request could get data from a server, now a persistent socket can allow the server to send updates without the client needing to specifically request it.

Server-side Communication

WebSockets do not need to be a communication channel purely between browser and server. The Mojolicious web framework has excellent support for WebSockets. Using that support, we can communicate between different server processes.

This solves the problem with client-to-client communication in a parallelized web server where all clients may not be connected to the same server process. The server processes can use a central message broker to coordinate and pass messages from one client to another.

Message Bus

A message bus allows for all connected peers to send and receive messages in a group.

Requesting a WebSocket from the URL /bus/fry joins the peer-to-peer message bus topic fry. All peers joined to the same topic will receive all the messages published to that topic by other peers.

This is useful for sharing state changes between multiple peers, for example, in a forking web app server like Hypnotoad or Starman.

Pub/Sub Messaging

The pub/sub pattern allows for 1-to-many delivery of messages from one publisher to any number of active subscribers.

Requesting a WebSocket from the URL /sub/leela creates a subscription to the topic leela. Requesting a WebSocket from the URL /pub/leela allows sending messages to the leela topic, which are then received by all the subscribers.

Topics are heirarchical to allow for broad subscriptions without requring more sockets. A subscription to the topic wong receives all messages published to the topic wong or any child topic like wong/amy or wong/leo.

This pattern is useful for keeping clients informed of backend processes, tapping into an event or logging stream.

Push/Pull

Push/pull deals out messages in a round-robin manner. Pushers send messages which are handled by a single puller.

Handlers request WebSockets from the URL /pull/bender. Senders request WebSockets from the URL /push/bender. Senders send messages which will be received by a single handler.

This pattern is useful for load balancing incoming updates, or creating processing pipelines using multiple push/pull endpoints.

Example App

In development mode (the default), the broker provides an example application to test the messaging patterns.

You can change the mode by using the -m flag to the mercury broker command or the MOJO_MODE environment variable.

CONFIGURATION

You can have an optional configuration file mercury.conf in the current working directory. The configuration file is a Perl hash, with the broker configuration in the broker key, like so:

# mercury.conf
{
    broker => {
        listen => "http://*:4000",
        allow_origin => [
            'example.com',
        ],
    },
}

The individual configuration keys are:

listen

# mercury.conf
{
    broker => {
        listen => "http://*:4000",
    },
}

You can set the default for the -l|--listen option in the configuration file.

allow_origin

# mercury.conf
{
    broker => {
        allow_origin => [
            'example.com',
        ],
    },
}

Instead of CORS (used by Ajax), WebSockets send an Origin header with the initial handshake. This header contains the protocol, host, and port used by the page requesting the socket.

As a basic security measure, you can configure the allowed origin values with the allow_origin configuration key. When this is set, only WebSocket handshakes with an Origin header matching one of the values will be allowed. If there is no Origin header, or the header does not match, the connection will be denied with a 401 Unauthorized response.

allow_origin key can be a single string, or an array of strings, containing a string to match against the incoming Origin header. The * character is a wildcard.

Each of the following examples will match the origin http://www.example.com:3000.

example.com
*.example.com
*://www.example.com
http://www.example.com:*

This is not a comprehensive security measure. The server is trusting that the client is not lying about its Origin. The client can claim any origin it wants.

USAGE

Mojolicious

To use Mercury to communicate between Mojolicious server processes, use Mojo::UserAgent's websocket method.

Dancer

To use Mercury inside of a Dancer or Dancer2 app, you can use AnyEvent::WebSocket::Client with the Twiggy PSGI server.

Catalyst

Like Dancer, you can use AnyEvent::WebSocket::Client and Twiggy to use Mercury in your Catalyst app.

JavaScript

For simple applications that only need some peer-to-peer message passing, you can directly connect clients to Mercury.

SEE ALSO

The Mercury web site
Mojolicious::Plugin::Mercury

You can use this plugin to create your own message broker with custom authentication and logging, custom messaging patterns, and more.

socket.io

A JavaScript WebSocket messaging library (client and server). For a socket.io-compatible server written in Perl, see PocketIO.

zeromq

A socket library that provides communication patterns for scalability. The inspiration to build Mercury (Mercury requires only Perl 5.10 or higher). For a Perl API to ZeroMQ, see ZMQ::FFI.

nanomsg

A socket library that provides communication patterns for scalability. The successor to ZeroMQ. The inspiration of the features provided by Mercury. For a Perl API, see NanoMsg::Raw.

AUTHOR

Doug Bell <preaction@cpan.org>

CONTRIBUTORS

  • Joel Berger <joel.a.berger@gmail.com>

  • Justin Hunter <justin.d.hunter@gmail.com>

  • Mohammad S Anwar <mohammad.anwar@yahoo.com>

  • William Lindley <wlindley@wlindley.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2018 by Doug Bell.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.