Identifying seperate websocket requests + spring boot - java

I am implementing WebSockets for the first time using spring boot. I would like some clarifications on web socket management.
Could I know an efficient way to differentiate separate WebSocket
requests from the client and respond back correctly to the exact
client who made that request? So when a request is received, we will
put that session to a sessionMap in
afterConnectionEstablished() and remove from the map when session is
closed in afterConnectionClosed().
Now, upon getting a request, the service would build a response to
give back to the socket. I would like to know how can I get the key
(map id) to check if that session is available in the sessionMap and
write to the socket if it is available and session.isopen
Should the WebSocket request have a unique ID in the request to
match? So that only upon receiving it back, the client should be
populating the data. Could anyone tell me how it is normally done?

Related

How can a particular thread be notified in Spring Boot

I have a REST service defined in Spring Boot, which exposes a synchronous REST API, to be invoked by a user from a Web based UI. The service is expected to provide a real time response.
The service talks to an external endpoint in an asynchronous fashion. That is:
- A single one - way outbound message for the request
- A single one - way inbound message for the response
How can I combine the two messages to provide an impression of a synchronous behavior? I am thinking of a few approaches like:
The Rest Service posts a request to the endpoint. Once the endpoint responds, the response is added to a ConcurrentHashMap. The Rest Service queries the HashMap every few milliseconds and once it finds the right response it exits with a valid HTTP reason code.
It is akin to polling and I am thinking if we can avoid that.
The Rest Service posts a request to the endpoint. Once the endpoint responds, the waiting thread in the Rest Service is notified. However the waiting thread should conclude only if the right response is received (i.e. matching correlation Ids etc.)
Is this possible?
I realize that this is similar to a JMS Queue Request Response scenario, where each JMS queue request opens up a listener on the response queue with a message selector criteria.
However in this case I have to implement this using HTTP.
Any thoughts on this are welcome. I am fully convinced I am missing something very basic, but am not sure what.
Thanks a lot!

Spring #ResponseBody can not use session

I have angular2 app and use Tomcat with spring for getting data. I don't want any page reloads or redirects, all I need is data, so all responses from server have #ResponseBody annotations.
My problem is, that because of this annotation I can not get users session variable. When I log in I create session, store user data in it but can not get it with next call.
#JsonIgnoreProperties(ignoreUnknown = true)
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public String login(HttpServletRequest REQ, #RequestBody String BODY) throws Exception
{
...check if all ok...
REQ.getSession().setAttribute("user", user);
... return user data...
}
Is there any other way I can send my data back to client, together with the data needed, to be able to use session.
Edit:
Problem is not on server side but client. Angular is not sending cookie JSESSIONID at cross domain requests by default.
First check your request/response (for example in Chrome dev tools). Tomcat creates new cookie named JSESSIONID to bind client with server session object, so look for this one in your login method response header. Then make sure you are sending this cookie back to your server in next request. Session creation has nothing to do with Spring or #ResponseBody, its lifetime is managed by container (Tomcat).
Also, if you are making cross domain requests, check this answer.
Anything you put on the session context isn't available to clients, it's only available to the server. see this stack overflow post for a good explanation on how servlets work, and specifically the part on how session state works.
As you can see, it works by adding a session-cookie to the response which contains a session-Id. The server stores the session state under that id in memory, and when a future request comes with that session-id, it makes the session state available again to the future request.
If your next requests do not have access to the session state, it's quite possible that the session-cookie isn't propagated properly. I suggest you check that first. It should be in the response where you log in, and should be posted in further requests to the server.

webservice client session management

So I am building this Webservice client and the Webservice (server) requires that I maintain a session and use a unique key, (not the JSESSIONID) generated by the client, only for that session. So I did the obvious.
((BindingProvider)service).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
Now this works great and I store the unique key and JSESSIONID is part of the headers etc.
The problem I have is that when I want to create a new session. So, another user logs in, I create a new unique key, authorize the user and get a new JSESSIONID. The authorization call seems to still add the other JSESSIONID to the headers and so the Webservice rejects the call. I am not sure how to tell my client service to create a new session? Do I just go new Service.getPort() and use that instance (doesn't seem best practice)? Can I create a Spring bean with a prototype scope (didn't seem to work but maybe I have scoped the wrong bean)? I even tried removing the JSESSIONID from the headers but it never seems to exist when I handle the message. If you need any thing (logs/traces/code) just shout and I'll edit the post.

concurrent request to jersey rest service

I am developing a very simple REST web service with Eclipse, Tomcat7 and Jersey implementation, with a connection to MySQL.
Looking to the jersey documentation i know that every request create a new object of the root resource class. But i dont know if every request is independet, for example if one request have to wait a long time, the server will accept more request normaly?
The problem is :
I have 2 main classes, 1 class implements Jersey with annotations(Proxy.java), and other class that connects to a BD(Notificator.java), there is only one instance of this class (Singleton) in order to use only 1 Connection object. The classes who implements Jersey use this class. So, if one of the request is blocked , i dont know if the others will run because they are using the same (Notificator.java) instance.
The relation is N instances of(Proxy.java) uses the only one (Notificator.java) witch have one Connection to a MySQL.
Jersey is developed on top of servlets. There is a new thread for each of the incoming request. Your code is creating a bottleneck for all the threads as there is a contention for single available connection object. If you have multiple requests then only one request will be using that connection and others have to wait. If the wait is not too long then there is no problem. But if wait is more than the HTTP REQUEST TIMEOUT then your other requests may end up as TIMED OUT.
I understand that you may be having single connection bottleneck due to some business requriement/ complication. So in all such cases where we cannot process all the requests simulataneously and there can be variety of reasons for it, then we should create our web services as Asynchronous. Asynchronous web services work on the model of SUBMIT REQUEST-> REQUEST ACCEPTED(will be processed asynchronously) and JOB URL returned for polling-> CLIENT POLLS till the JOB IS NOT COMPLETED.
Hope it helps!
Try database connection pooling, more on this here:
http://en.wikipedia.org/wiki/Connection_pool
How to establish a connection pool in JDBC?

HttpConnection maintaining Session

I'm consuming some web services done in java using a Rest architecture, my client it's a mobile application that uses HttpConnection to retrieve the data. In order to control authentication and authorization I'm using cookies, managed by a #SessionScoped class, however I don't know how to make the session persist through requests. The problem basically is that I inject the Session manager in other services that are #RequestScoped, however since the session is not persisted I always retrieve differente instances for the #SessionScoped class, thus deleting all the cookies or records I had before. Looking at the request headers I noticed the cookie JSESSIONID, I think this is sent by tomcat in order to persist session, so tried already to send the same cookie in the next request, however I got no results.
The comments were right... to persist a session you just have to send the JSESSIONID cookie back to server in the next request, the problem in this case was that HttpConnection in JavaME only has the setRequestProperty method to include a header value, now if you set the same value two times it overwrites the last one. Since I was using a custom cookie and the JSessionID cookie, I setted them in the following way:
connection.setRequestProperty("Cookie","sessionId="+ApplicationPreferences.getIn‌​stance().getSessionCookieHeader());
connection.setRequestProperty("Cookie","JSESSIONID="+ApplicationPreferences‌​.getInstance().getJavaSessionCookieHeader());
When the correct way to do it is concatenate the cookie strings and then setting a Cookie header with them all:
String myCookies="sessionId="+ApplicationPreferences.getInstance().getSessionCookieHead‌​er()+";"+"JSESSIONID="+ApplicationPreferences.getInstance().getJavaSessionCookieHeade‌​r();

Categories