Studying the methods of implementing real-time data refresh in the browser, I discovered "
WAMP ", an application-level messaging protocol based on web-based software.
The protocol implements two common high-level templates for data exchange: PubSub and RPC (Remote Procedure Call).
These templates are well known and widely used in various areas of programming and interprocess communication:
- RPC - remote procedure call. In the process involved the client and server. The first sends requests for a procedure call on the server, and the second executes them and sends the result to the client. In a typical web application, this could be, for example, a request to create a comment or to add a post to favorites.
- Publish / Subscribe (PubSub) is a messaging method in which clients “subscribe” to events of interest to them and can generate such events themselves. Sending information to subscribers is engaged in a third party - "broker". In WAMP, a PubSub template is implemented on the basis of "topics", or channels. For example, on the site such channels can be “comments”, “news”, “private messages”.
In the context of web development, the most interesting use of the WAMP protocol is to use the PubSub template. With it, you can easily solve the problem of updating information on a page of a site opened by a user: for example, to display a comment just added or to show a notification of receipt of a new message.
WAMP implementation exists in the form of libraries
for many languages ​​and platforms , including, of course, javascript as an
autobahn project.
As an example of using the protocol, let's try to develop an abstract web application in which the browser will subscribe to the channel with new comments, and the server will send them. On the server, PHP will work with the wonderful
Ratchet library, which, in addition to implementing the web sockets, is able to work with the WAMP protocol.
')
When planning methods of interaction between the client and the server on such a website, it should be remembered that there
are still browsers that do not support web-sites. Although some of the problems with them can be solved by
polyfills , 100% of work in any environment (for example, on android) cannot be achieved with their help. Therefore, it is reasonable, in my opinion, to limit the use of the PubSub template on the client to a subscription to events. The same events will be generated by the server receiving the “old school” ajax requests to create a new comment on behalf of its author. Thus, all clients will be able to add comments (or, in general, generate events), but only those who support web-sites will receive updates in real time.
The client part of the site.
The autobahn library exports the
ab object to the global scope, a full list of methods of which can be found in the
documentation . We are also interested in the
connect method:
ab.connect(
For simplicity, the line “comments” was chosen as the name of the channel, but according to the protocol specification such naming is not correct. Channels must be in URI format, that is, in our case the channel may be called
site.com/comments
site.com/comments
. In turn, the channel URIs can be reduced to “compact URIs” - CURIE. These details are described in more detail on the
specification page.
It is logical that the user doesn’t need all new comments at once on a real site, but only those appearing on the current page are needed. In this case, you can create for example such a channel:
site.com/comments/page/1
site.com/comments/page/1
. Of course, there are no restrictions on the formation of URIs: you can dynamically create channels with any parameters, depending on the tasks.
Server part of the site.
In the example of PHP, ZMQ is responsible for delivering messages from the http server to the server responsible for sending messages to the
websockets . When a new comment is received, the server saves it to the database and sends the message to the ZMQ queue, from which it in turn will be retrieved by the daemon using the Ratchet library mentioned above.
Here is how the implementation of such a function looks like:
To handle client connections and events from the ZMQ server, we need a process that will receive messages and process them. The documentation for the Ratchet library already contains
detailed examples . In particular, you need to pay attention to the Pusher class (in our example, I called it WampProcessor, which seems to be more relevant) - it contains the business logic of the application and sends messages subscribed to the corresponding channels to customers.
The code to start such a process would be something like this:
All methods of the WampProcessor class will be almost identical to what can be seen in the Ratchet documentation; one of them is to select only the event handler - the "
onComment " method:
public function onComment($json) { $comment = json_decode($json, true);
Thus, when creating a new comment, all connected browsers will receive an object with the author and content fields, which it expects to receive a javascript handler.
The messaging process can be observed in the chrome console (“websocket” filter in the “network” tab) or another browser. It can be seen that when connecting to the server, the browser sends a greeting message, and then a list of channels to subscribe.
Conclusion
So, using the WebSockets technology and the WAMP protocol, you can implement a real-time update of information on a web page using the PubSub method.
It can be argued that using nodejs and the library of socket.io would be easier to do this, but in our reality, where PHP is the dominant server platform, the described version is quite viable and even more convenient than other, more “crutch” methods (such as periodic server polling using ajax). It is also relatively easy to implement on an existing site: changes will only need to be made to those parts where any events are generated, and the handler daemon itself can be completely independent.
Key links:
- Wamp - websocket application messaging protocol.
- Authobahn - WAMP implementation on javascript.
- Ratchet - implementation of web sockets and WAMP for PHP.