How to connect websocket with a mobile application? - spring

I need for a mobile application to add websocket to the backend for chat implementation. I found an example https://github.com/callicoder/spring-boot-websocket-chat-demo, but here the chat is not for a mobile application, I don’t quite understand how to request a chat? should add api, but where?
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
I have an addEndpoint, should I write api in it?
Since my application does not work with the browser, how to replace .withSockJS ()?
#RestController
#RequestMapping(name = "api/chat")
public class ChatController {
#MessageMapping("/chat.sendMessage")
#SendTo("/topic/public")
public ChatMessage sendMessage(#Payload ChatMessage chatMessage) {
return chatMessage;
}
#SendTo("/topic/public")
public ChatMessage addUser(#Payload ChatMessage chatMessage,
SimpMessageHeaderAccessor headerAccessor) {
headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
return chatMessage;
}
}
or the data should come through this api?
I do not understand how to receive data in websocket via api from a mobile application in order to save it

Related

Is there a way to send websocket message from regular method in spring

I am building web application. There are admin and user roles provided. When user making some action admin is recieving a message that something happened. Websocket connection establishing when user logged. Is there a way to not create ws connection for user and use only HHTP protocol to sending message and send WS message from controller method only?
Now i have theese settings:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOriginPatterns("*").withSockJS();
}
}
#Controller
public class NotificationController {
#MessageMapping("/notification")
#SendTo("/topic/test")
public Notification getNotification(Notification notification) {
return notification;
}
}
Yes it is possible.
You have to inject SimpleMessagintTemplate, with #Autowire or with constructor.
private final SimpMessagingTemplate simpMessagingTemplate;
public ConstructorName(SimpMessagingTemplate simpMessagingTemplate){
this.simpMessagingTemplate = simpMessagingTemplate;
}
In your controller, or function where you want to send the message to the client use the convertAndSendToUser function.
simpMessagingTemplate.convertAndSendToUser("userId","/private", messageData);
On javascript client side.
var Sock = new SockJS('http://localhost:8080/ws');
stompClient = over(Sock);
stompClient.connect({}, onConnected, onError);
stompClient.subscribe('/topic/' + userId + '/private', onMessageReceived);

There is an endpoint connection error problem implementing the websocket with spring boot

This is my WebSocketConfig.
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/pub");
registry.enableSimpleBroker("/sub");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket").setAllowedOriginPatterns("*").withSockJS();
}
}
This is my SocketController:
#Controller
public class SocketController {
#MessageMapping("/comm/message")
#SendTo("/sub/test")
public Message message(Message message) {
return message;
}
}
I am testing the socket through Chrome's Web Socket Test Client and Advanced Rest Client, but my connection endpoint ws://localhost:8080/socket returns the error.
Is there anything I set wrong?
connecting try tool and endPoint
return message

Large messages failing on Stomp Controller in Spring Boot

I have a stomp controller in a spring boot application, When ever i send a message which exceeds 256kb it fails to enter the controller. I don't see any error messages. Is there any setting where I can configure it to allow larger messages.
Here is my controller
#Component
#Controller
public class DiscussionController {
#MessageMapping("/discussion")
public void post(DiscussionMessage message) {
}
}
Here is my config file
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer{
private final Logger log = LoggerFactory.getLogger(WebSocketConfig.class);
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("topic");
config.setApplicationDestinationPrefixes("ngdesk");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ngdesk-websocket").setAllowedOrigins("*").withSockJS();
}
}
You need to configure the web-socket transport, e.g.:
#Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setMessageSizeLimit(512 * 1024); // 512K
}

ConvertAndSendToUser SpringStomp Sockjs not working SimpMessagingTemplate

I want to send notification to specific user. My client side code is:
stompClient.connect({},function (frame) {
stompClient.subscribe('user/queue/notification', function(response){
alert(angular.fromJson(response.body));
});
Here's my server configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/queue");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/myWebSocketEndPoint")
.setAllowedOrigins("*")
.withSockJS();
}
}
Here's my server message-sender:
#Component
public class MenuItemNotificationSender {
public void sendNotification(MenuItemDto menuItem, String username) {
String address = "/queue/notification";
System.out.println(username);
messagingTemplate.convertAndSendToUser(username,address, menuItem);
}
}
The messages are sent correctly, to the correct username, but why client doesn't receive them?

Spring Stomp #SubscribeMapping("/user/...") with User Destination doesn't work

I need to react on a user destination subscription.
Example:
A user subscribes to /user/messages, because he wants to receive all incoming messages. Now I'd like to look up any messages for this user, which were created while he was offline, and then send them to that user.
Working code:
Client code:
stompClient.subscribe('/user/messages', function(msg){
alert(msg.body);
});
Server code:
template.convertAndSendToUser(p.getName(), "/messages", "message content");
What I need:
It seems like it's not possible to catch an user destination subscription on server side, i.e.:
#SubscribeMapping("/user/messages")
public void test(Principal p) {
sendMessagesThatWereReceivedWhileUserWasOffline();
}
What I tried:
#SubscribeMapping("/messages")
public void test(Principal p) { ... }
This works, if the client subscribes to /app/messages, but it won't get called for /user/messages.
My Configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp").withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/queue", "/topic");
registry.setUserDestinationPrefix("/user");
}
#Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
return true;
}
// all other methods left empty
}
Using Spring 4.1.
I can't imagine that this isn't possible. What have I missed / done wrong?
Thank you :)
Define the user prefix also as an application prefix, and you'll then be able to map the subscription in your controller. Configuration:
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app", "/user");
registry.enableSimpleBroker("/queue", "/topic");
registry.setUserDestinationPrefix("/user");
}
Controller:
#SubscribeMapping("/messages")
public void test(Principal p) {
sendMessagesThatWereReceivedWhileUserWasOffline();
}

Resources