Server implementation of channel handlers

Now, let's start the rest of the implementation of our real-time communication on the server side. As introduced earlier, we build the communication using a channel-based pattern, but the default API that WebSocketHandler provides doesn't have the concept of the channel. It defines a generic interface. We will need to extend it.

As mentioned earlier, our implementation of this interface is WebSocketRequestDispatcher. It is inspired by Spring MVC's DispatcherServlet. Inside the handleTextMessage() method of WebSocketRequestDispatcher, we will ask ChannelHandlerResolver to find the channel handler that is registered to handle the message sent to the specified channel. Once the channel handler is located, we will use corresponding ChannelHandlerInvoker to invoke the channel handler's action method that is bound to process the message. When the channel handler or the action method isn't found, the server will send an error message to the client. Otherwise, the action method of the channel handler will take over the processing of the message.

The following is a diagram to show WebSocketRequestDispatcher and its dependencies:

Figure 12.9: WebSocketRequestDispatcher and its dependencies

We will not dig into the details of these classes. You can find them in the commit record. Instead, let's take a look at the handler of the com.taskagile.web.socket.handlers.BoardChannelHandler board channel, which looks like the following:

@ChannelHandler("/board/*")
public class BoardChannelHandler {

@Action("subscribe")
public void subscribe(RealTimeSession session, @ChannelValue String
channel) {
log.debug("RealTimeSession[{}] Subscribe to channel `{}`",
session.id(), channel);
SubscriptionHub.subscribe(session, channel);
}

@Action("unsubscribe")
public void unsubscribe(RealTimeSession session, @ChannelValue String
channel) {
log.debug("RealTimeSession[{}] Unsubscribe from channel `{}`",
session.id(), channel);
SubscriptionHub.unsubscribe(session, channel);
}
}

As you can see, this BoardChannelHandler is a simple Java class. You don't need to extend any base class or implement any interface. All you need to do is to apply the @ChannelHandler annotation at the class level and apply the @Action annotation to the methods that will process the request.

The two parameters passed in the subscribe() action method and the unsubscribe() action method are passed by ChannelHandlerInvoker. This is inspired by the way that Spring MVC passes parameters to controllers' methods. If you do not need the invoker to pass the RealTimeSession instance or the channel, you simply do not add it as a parameter of the action method.

As you might remember, in the subscribe() method of RealTimeClient, the message we send to the server has two parameters, action, and channel:

subscribe (channel, handler) {
...
const message = {
action: 'subscribe',
channel
}
this._send(message)
...
}

The channel parameter will match the one we specify in @ChannelHandler("/board/*"). The action parameter will match the value we specify in @Action("subscribe"). You can create actions other than subscribe and unsubscribe in the channel handler.

Due to the scope of this book, we will only implement the real-time update of adding a new card. In a future version of TaskAgile, we will add the rest of the real-time updates. You can find the details of how to perform the real-time update of adding a new card in the frontend in the following commit record:

Figure 12.10: Implementing real-time update of adding card commit
..................Content has been hidden....................

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