tomcat 8 javax.websockets doesn't work - java

I have tomcat 8-RC1 installed in order to use javax.websockets to write websocket based applications.
there are examples at http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/ that show exactly the structure of a websocket class so I implemented the following interface:
public interface XpoWebSocket {
#OnOpen
public void onOpen(Session session);
#OnClose
public void onClose();
#OnMessage
public void onTextMessage(String message);
public Session getSession();
}
in the line above the class deceleration I also included the following:
#ServerEndpoint(value = "/ServConnect")
public class ServConnect implements XpoWebSocket {
...
so the ServerEndPoint is to point how to access to websocket, the question is what do i need to set in web.xml ? for now the web socket is still not accessible.
I try to define ServConnect as a regular Servlet in web.xml but that doesn't work. it just time out when I try to access the ServConnect location.
what configuration am I missing to let this ServConnect websocket class work ?

The WebSocket spec says that you have to annotate the concrete class. ServConnect will be treated as a WebSocket endpoint but will not receive any events as the annotations on the interface are ignored.
I'd suggest getting your own version of the Echo example working and then expanding from there.

Related

Get HTTPRequest in HttpSessionListener

Due to project requirement I have created a HttpSessionListener in my spring based application.
public class SessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
//some business logic
}
}
I need to set some parameters in request in this class but I am not able to find any way to get http request object in this class. Is there any way to get the http request object here? If no what is the other way too implement it?

Change websocket scope (from application to session/view)

I created a basic web socket with a tutorial.
Here is a configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat");
registry.addEndpoint("/chat").withSockJS();
}
}
And here is the message handling controller:
#MessageMapping("/chat")
#SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
return new OutputMessage("Hello World!");
}
Everything works, but from my investigation, it looks like the WebSockets by default has an application scope (by connecting to the channel I can see all calls, from all users).
What I want to do is to be able to see only calls from the current user session or current view only.
Any ideas on how to apply these configurations?
I was able to solve this puzzle, so I'm sharing with you my findings.
First, I found information that a simple in-memory message broker can not handle this:
/*
* This enables a simple (in-memory) message broker for our application.
* The `/topic` designates that any destination prefixed with `/topic`
* will be routed back to the client.
* It's important to keep in mind, this will not work with more than one
* application instance, and it does not support all of the features a
* full message broker like RabbitMQ, ActiveMQ, etc... provide.
*/
But this was misleading, as it can be easily achieved by #SendToUser annotation.
Also, the important thing that now on the client-side, you need to add an additional prefix /user/ while subscribing to the channel, so the solution would be:
On the server-side: change #SendTo("/topic/messages") into #SendToUser("/topic/messages").
On the client-side: /topic/messages into the /user/topic/messages.

simpMessagingTemplate doesn't send message from client to server

I want to exchange messages by web sockets between 2 java apps.
I have the following server configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/queue", "/topic");
registry.setUserDestinationPrefix("/user");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//todo remove handshake handler when authorization is implemented
registry.addEndpoint("/ws").setAllowedOrigins("*").setHandshakeHandler(new TestHandshakeHandler()).withSockJS();
}
}
and inside class marked with #Controller I have wrote following theme:
#MessageMapping("/consumer/client/add")
public void addClientRequest(String msgReq) {
logger.info(msgReq);
}
and inside clien I do connect and in sime bean I wrote following:
#Autowired
private SimpMessagingTemplate simpMessagingTemplate;
...
simpMessagingTemplate.convertAndSend("/app/consumer/client/add", new StubObject("message"));
But after sending from client method addClientRequest doesn't invoke.
Please advice ways to troubleshot this issue.
Actually I don't understand issue. Maybe I send to wrong destination or I have issue with configuration or path is wrong or something else.
P.S.
I know that I can extend StompSessionHandlerAdapter
and obtain session from there but looks like it is the bad style and should be another way to achieve it
P.S.2
Inside class WebSocketTcpConnectionHandlerAdapter(inner class inside WebSocketStompClient) I see private volatile WebSocketSession session;
I want to obtain this object to send messages
I don't think it was designed to be used like this.
I think you must use a specific websocket client. This one for exemple :
http://www.programmingforliving.com/2013/08/jsr-356-java-api-for-websocket-client-api.html
This code :
#MessageMapping("/consumer/client/add")
public void addClientRequest(String msgReq) {
logger.info(msgReq);
}
Will NOT connect to a websocket client and wait to have messages. It expect a client to connect throught it and send messages.

I get a status 200 when connecting to the websocket, but it is an error?

My error shows up in the console of my browser:
"WebSocket connection to 'ws://localhost:32768/DspClusterWebServices/myHandler' failed: Unexpected response code: 200"
I am using Spring Websockets 4.1.5 and Tomcat 8.0.18. My WebSocketConfigurer implementation class looks like:
#Configuration
#Controller
#EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer
{
class MyHandler implements WebSocketHandler
{
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception
{
System.out.println("afterConntectionEstablished called");
}
...implements rest of functions with a System.out.println and false for supportsPartialMessages()
}
}
#Override registerWebSocketHandlers(WebSocketHandlerRegistry registry)
{
registry.addHandler(myHandler(), "myHandler").withSockJS();
}
#Bean
public WebSocketHandler myHandler()
{
return new MyHandler();
}
}
My testWebsocketClient.js tries to connect with this code, but has a error code of 200:
websocket = new WebSocket("ws://localhost:8080/myApp/myHandler");
I cannot figure out what to try next. I thought that this would cause the afterConnectionEstablished(WebSocketSession session) method to fire? Isn't code 200 good?
Please check http://procbits.com/connecting-to-a-sockjs-server-from-native-html5-websocket!
After you append /websocket (to your URL), it will give you the error
Failed to parse Origin header value [null]
;)
, which then will in turn lead you to that link.
You'll have to add .setAllowedOrigins("*") to your addHandler() method, and then it could finally work!
As my another answer:[https://stackoverflow.com/a/53272666/2930417][1]
I use springboot 2 +STOMP。
remove .withSockJS(),then everything is ok.
I don't know the reason,but works for me.
Have a look at the specification . The server should respond with 101 to signal protocol change from http to ws.
Don't know if this is too late but a solution that I stumbled upon is simply appending the string /websocket after the websocket endpoint that you declared in the spring boot server. This will help keep both the forwarding logic and connect and establish a websocket connection.
For those guys like me who use angular + springboot and got this error. please check if you have enabled the redirect or forward all non api endpoint request back to index.html. like:
#RequestMapping(value = "/**/{[path:[^\\.]*}")
public String redirect() {
// Forward to home page so that route is preserved.
return "forward:/index.html";
}
If you do, disable it and you will get 101
Please check that if 'ws://localhost:32768/DspClusterWebServices/myHandler' is correct.

Weblogic Websocket endpoint not working

I'm trying to crete a simple Websocket application based on tutorial here: http://docs.oracle.com/javaee/7/tutorial/doc/websocket004.htm
So the code looks something like this:
#ServerEndpoint("/echo")
public class EchoEndpoint {
#OnMessage
public void onMessage(Session session, String msg) {
try {
session.getBasicRemote().sendText(msg);
} catch (IOException e) { ... }
}
}
I'm running Weblogic 12c. I thought the annotation should be automatically picked up and websocket endpoint created on the address localhost:8888/myApp/echo, but when I try to connect there with this js test: http://www.websocket.org/echo.html, nothing happens. Also when I attach debugger, I see that the EchoEndpoint class was not loaded. What else should I do to make it running? I see nothing else in the Oracle tutorial
The Tyrus library requires a JEE7 container, Weblogic only supports JEE6.
Follow this tutorial to get websockets in Weblogic.
http://docs.oracle.com/middleware/1212/wls/WLPRG/websockets.htm

Categories