Centrifugo v2.0 released. Built on top of new real-time messaging library for Go language

Alexander Emelin
5 min readOct 2, 2018

--

Several months ago I published an article about Centrifugo v2 plans. In that article I mentioned that Centrifugo v2 will have several interesting changes and will be based on new library for Go language called Centrifuge.

Now I can finally say — Centrifugo v2 released! It was a nine months sprint of spare time work on new version and there were many challenging tasks during this time so I glad I brought it to the end.

When I was developing first Centrifugo versions I had no idea how popular and useful it will become. As the time passed I received a lot of reports about successful Centrifugo integrations. Most of stories came from Python and PHP developers. The version 2 was aimed to solve several protocol design inconveniences and concentrate on even simpler integration process.

Centrifugo v2

Despite the fact that code base was rewritten drastically Centrifugo v2 serves the same purpose as Centrifugo v1. This is a real-time messaging server. It’s language-agnostic thus can be used in conjunction with application written in any programming language. Centrifugo runs as separate service and keeps persistent Websocket or SockJS connections from your application clients (from web browsers or other environments like iOS/Android apps). When you need to deliver event to your clients in real-time you publish it to Centrifugo API and Centrifugo then broadcasts event to all connected clients interested in this event. Clients indicate their interest to concrete messages subscribing to channels (or in other words topics). So Centrifugo is basically a client-facing PUB/SUB server.

New documentation has more detailed description of server.

Some highlights of v2:

  • Cleaner and more structured client-server protocol defined in Protocol Buffers schema. Protocol is more compact because some fields with default values that were sent previously now omitted
  • Binary Websocket support (Protobuf). Protobuf allows to transfer data in much more compact and performant way than before. Of course JSON is still the main serialization format and developer can decide which format to use
  • JWT for authentication and private channel authorization instead of hand-crafted HMAC sign. This means that there is no need in extra libraries to generate connection and subscription tokens. There are plenty of JWT libraries for all languages
  • Prometheus integration and automatic export of stats to Graphite. Now Centrifugo easily integrates in modern monitoring stack — no need to manually export stats
  • Refactored Javascript (ES6), Go and gomobile client libraries
  • Simplified HTTP API and support for GRPC for server API
  • New presence_stats API command to get compact presence information - how many clients and unique users in channel
  • Structured logging with coloured output during development
  • Mechanism to automatically merge several independent messages into one frame to reduce write system calls amount thus be more performant under load
  • Better message recovery algorithm to fix several recovered flag false positives
  • Goreleaser for automatic releases to Github

At moment we have no client libraries for native mobile development (iOS and Android). But I hope this will change at some point in future with the help of open-source community.

Introducing Centrifuge library

As already mentioned Centrifugo v2 is now based on new Centrifuge library for Go language. Library provides almost all features Centrifugo has out of the box and some things beyond— like custom authentication via middleware, custom subscription permission management, asynchronous bidirectional message passing, builtin RPC calls etc.

Several reasons that motivated me to segregate Centrifugo core into separate library are:

  • Centrifugo users are mostly programmers in languages other than Go — i.e. developers who write backend side in language that do not support concurrency out of the box (Python, PHP, Ruby). This results in a situation where developers using Centrifugo can’t help a lot with improving project, debugging performance issues, fixing bugs. Having core in separate library adopted somewhere by Go developers can improve this because as soon as library evolves and improves Centrifugo itself should benefit too.
  • Centrifugo design fits good to scenarios when clients just need a stream of messages from server side. This covers many use cases but not very good for scenarios when low-latency bidirectional communication between client and server required (browser multiplayer games for example). This still won’t be resolved for Centrifugo as it’s design has not been changed but now works for those who using Go library as it supports two-way communication and tightly integrates with backend code.
  • And I was asked several times about using Centrifugo as library so this seemed like a good moment to start working on this.

Interesting thing that clients for Centrifugo server also work with custom server that uses Centrifuge library.

In many cases you can consider Centrifuge lib as socket.io analogue. There are many differences but the idea is the same — real-time bidirectional communication between application clients and backend to build games, chats, collaborative tools, live charts and counters etc. Actually there are lots of solutions for this kind of tasks.

Library supports the same transports as Centrifugo server:

  • Websocket
  • SockJS provided HTTP fallbacks (xhr-streaming, server-sent events etc)

If your message payload is JSON you can use any of these transports, if you want to transfer binary payloads then you should use Websocket with Protobuf protocol.

As said in previous article I also considered GRPC bidirectional streaming for client-to-server transport but after making some measurements I have not found any benefit it can give compared to Websocket with Protobuf protocol. So I decided to not introduce GRPC streaming for now.

I should mention that Centrifuge library design was influenced a lot by the fact that it is a core of Centrifugo server. So some things inside new library will be familiar to Centrifugo users and the same things can seem not very obvious for new users. But still library is quiet generic and can solve many real life problems.

There are some examples in library repo — please take a look if you are interested.

What’s next

This is a short preview of new server and library. While Centrifugo v2 has been released Centrifuge library is still considered a work in progress. I am not sure will the library be accepted by community or not as it’s quiet big and feels more like a framework Go programmers prefer to avoid (actually me too). So I’ll wait for feedback here.

And I hope to hear new stories about Centrifugo v2 integrations.

--

--