Broadcasting a message to a single user in a WebSocket application

In the previous section, we saw a WebSocket application of the multiple subscriber model, in which a broker sent messages to a topic. Since all clients had subscribed to the same topic, all of them received messages. Now, you are asked to develop an application that targets a specific user in a WebSocket chat application.

Suppose you want to develop an automated answering application in which a user sends a question to the system and gets an answer automatically. The application is almost the same as the previous one (STOMP over WebSocket and the fallback option in Spring 4), except that we should change the WebSocket configurer and endpoint on the server side and subscription on the client side. The code for the AutoAnsweringWebSocketMessageBrokerConfigurer class is:

@Configuration
@EnableWebSocketMessageBroker
public class AutoAnsweringWebSocketMessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer {
   @Override
   public void configureMessageBroker(MessageBrokerRegistry config) {
      config.setApplicationDestinationPrefixes("/app");
      config.enableSimpleBroker("/queue");
      config.setUserDestinationPrefix("/user");
   }
   @Override
   public void registerStompEndpoints(StompEndpointRegistry registry) {
      registry.addEndpoint("/message").withSockJS();
   }
}

The config.setUserDestinationPrefix("/user") method sets a prefix noting that a user has subscribed and expects to get their own message on the topic. The code for the AutoAnsweringController class is:

@Controller
public class AutoAnsweringController {
    @Autowired
    AutoAnsweringService autoAnsweringService;
    @MessageMapping("/message")
    @SendToUser
    public String sendMessage(ClientInfoBean message) {
        return autoAnsweringService.answer(message);
    }
    @MessageExceptionHandler
    @SendToUser(value = "/queue/errors", broadcast = false)
    String handleException(Exception e) {
        return "caught ${e.message}";
    }
}


@Service
public class AutoAnsweringServiceImpl implements AutoAnsweringService {
    @Override
    public String answer(ClientInfoBean bean) {
        StringBuilder mockBuffer=new StringBuilder();
        mockBuffer.append(bean.getClientName())
                .append(", we have received the message:")
                .append(bean.getClientMessage());
        return mockBuffer.toString();
    }
}

In the endpoint, we use @SendToUser instead of @SendTo("..."). This forwards the response only to the sender of the message. @MessageExceptionHandler will send errors (broadcast = false) to the sender of message as well.

AutoAnsweringService is just a mock service to return an answer to the client message. On the client side, we only add the /user prefix when a user subscribes to the topic (/user/queue/message):

function connectService() {
    var servicePath='/message';
    var socket = new SockJS(servicePath);
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function(frame) {

        setIsJoined(true);
        stompClient.subscribe('/user/queue/message', function(message) {
            renderServerReturnedData(message.body);
        });
        stompClient.subscribe('/user/queue/error', function(message) {
            renderReturnedError(message.body);
        });
    });
}
function sendMyClientMessage() {
    var serviceFullPath='/app/message';
    var myText = document.getElementById('myText').value;
    stompClient.send(serviceFullPath, {}, JSON.stringify({ 'clientName': 'Client-'+randomnumber, 'clientMessage':myText}));
    document.getElementById('myText').value='';
}

The topic user/queue/error is used to receive errors dispatched from the server side.

Note

For more about Spring's WebSocket support, go to http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/websocket.html.

For more about WebSocket communication, refer to Chapter 8, Replacing HTTP with WebSockets from the book Enterprise Web Development, Yakov Fain, Victor Rasputnis, Anatole Tartakovsky, Viktor Gamov, O'Reilly.

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

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