Other Interesting Features

In any successful development ecosystem, a tension always exists between currency and stability. We’ve tried to walk as closely to currency as we could without stepping over. Still, exciting things are happening, many of which weren’t ready to include in this text. These are some exciting features you may want to use in your next project.

Supporting Internationalization with Gettext

In version v1.1, Phoenix added integration with Gettext, an internationalization (i18n) and localization (l10n) system commonly used for writing multilingual programs. Gettext can automatically extract translations from your source code, reducing the burden on the developer. Furthermore, since the Gettext standard is used by so many communities, you can take advantage of a rich set of tooling for both developers and translators.

When you ran mix phx.new rumbl, Phoenix generated a RumblWeb.Gettext module at lib/rumbl_web/gettext.ex. You can see it in use in the lib/rumbl_web/views/error_helpers.ex file, used to translate the error messages coming from Ecto. Since programmers often organize translations into namespaces called domains, Phoenix places Ecto messages in the errors domain by default.

The translations for different languages are in the priv/gettext directory. There you’ll find a default template for Ecto messages called errors.pot. A translation for each language is placed in directories such as priv/gettext/en/LC_MESSAGES.

To learn more about the integration between Phoenix and Gettext, we recommend this fantastic article by Rebecca Skinner entitled “Internationalization using Gettext in the Phoenix framework.”[36] For general information, check out the Gettext documentation.[37]

Next, we’ll move from internationalization to intercept and handle, a couple of functions that make it easier to manage channel messages.

Intercepting on Phoenix Channels

When you broadcast a message, Phoenix sends it to the Publish and Subscribe (PubSub) system, which then broadcasts it directly to all user sockets. We call this approach fastlaning because it completely bypasses the channel, allowing us to encode the message once. Phoenix Channels also provide a feature called intercept, which allows channels to intercept a broadcast message before it’s sent to the user.

For example, maybe we’d like to let the video’s creator edit all of its annotations. For such a feature, we could append an is_editable field to the annotation map when we broadcast it so the frontend can adapt accordingly. Using intercept, we could build this feature like this:

 intercept [​"​​new_annotation"​]
 
 # For every new_annotation broadcast,
 # append an is_editable value for client metadata.
 def​ handle_out(​"​​new_annotation"​, msg, socket) ​do
  %{​video:​ video, ​user_id:​ user_id} = socket.assigns
  push socket, ​"​​new_annotation"​,
  Map.merge(msg, %{​is_editable:​ video.user_id == user_id})
  {​:noreply​, socket}
 end

For each event that we specify in intercept, we must define a handle_out clause to handle the intercepted event. You can also intercept an event and choose not to push it at all, in case you want to make sure that some clients don’t receive specific events.

intercept is a nice feature, but you need to be careful. Imagine that you have 10,000 users watching a video at the same time. Instead of using intercept, you could write a few extra lines of code to include a :video_user_id field in the message, letting the client decide whether the message is editable. For that implementation, Phoenix would encode the broadcast once and send the message to all sockets.

With the intercept implementation, Phoenix would send the message to the first 10,000 channel processes, one for each client. While processing the intercept, each channel would independently modify the intercepted message and push it to the socket to be encoded and sent. The cost of intercept is 10,000 extra messages, one per channel, as well as encoding those messages 9,999 times—again, once per channel—compared to the one-time encoding of the implementation without intercept. For those reasons, we recommend using intercept with care.

On the other hand, intercept can be tremendously useful when we’re evolving code. Imagine building a new version of the annotations feature in the future, with new frontend and backend code, including a different payload when new annotations are broadcast. However, imagine that you also have old clients that can take a while to migrate. You could use the new annotation-broadcast format throughout the new code and use intercept to retrofit the new_annotation broadcast into the old one. For these cases, intercept would be an ideal solution. You’d pay a temporary performance price to make your code easier to build and understand.

For more information on intercept and handle, check the Phoenix documentation on channels.[38] Next, we’ll move on to live code reload.

Understanding Phoenix Live Reload

One of the features we used throughout the entire book was Phoenix Live Reload, which allows us to see changes propagated to the browser as soon as we save them to the filesystem. Phoenix Live Reload is composed of:

  • A dependency called file_system that watches the filesystem for changes

  • A channel that receives events from the file_system application and converts them into broadcasts

  • A plug that injects the live-reload iframe on every request and serves the iframe content for web requests

There isn’t much to Live Reload, and that’s exactly why we recommend that you to study its source code to learn more about how simple it is to extend Phoenix. If the feature is something you might want to customize, consider reading more or even following the project. You can find the source code in our Phoenix Live Reload GitHub project.[39]

While we’re on the subject of customization, let’s see how you might customize the Phoenix PubSub adapter.

Phoenix PubSub Adapter

By default, Phoenix PubSub uses distributed Erlang to ensure that broadcasts work across multiple nodes. This requires all machines to be connected together according to the Erlang Distribution Protocol. Setting up distributed Erlang is straightforward, but it might not be directly supported in some deployment platforms.

You needn’t worry, though. Phoenix PubSub is extensible—it supports multiple adapters. One is the Redis adapter,[40] maintained by the Phoenix team, which empowers the PubSub system by using Redis as its message-distribution mechanism. You can use one of these options or even write your own.

You’ve seen how to customize Phoenix messaging on the server side. Some interesting things are happening on the client side too.

Phoenix Clients for Other Platforms

In our channels chapter, you saw how we customized the Phoenix transport to work with our ES6 code. Phoenix Channels support the nearly ubiquitous JavaScript and also a wide range of other clients and platforms, including C#, Java, Objective-C, and Swift.[41]

All these clients use WebSockets, but don’t forget that Phoenix Channels are transport agnostic. If you have special requirements, as in embedded software or working on special platforms, you can always use a custom protocol to talk to Phoenix.

The Phoenix project has surpassed our expectations in its first few years, but we’re even more excited about what’s coming next. In the next few sections, we offer a preview, listing those we expect the soonest first. Be careful, though. We offer no guarantees!

By far the most anticipated change is Phoenix Liveview. Let’s take a peek.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.119.170