Since Tomcat now packages JSR 356 (little name of websocket 1.0 specification) TomEE inherited of it in its last release.
It basically means you can define a server endpoint this way – note: client endpoints are as easy to define:
@ServerEndpoint("/metrics/{name}") public class MetricsEndpoint { @OnMessage public void addMetric(@PathParam("name") String key, String message, Session session) { // TODO } }
This is really efficient! Now you start to think a bit more and realize you have a kind of socket (even if you passed through HTTP) – the session. So after having realized you feel really naked cause you don’t use a protocol anymore and then understood it was what you were looking for (or not) you see another issue: synchronization. Quickly you need to synchronize data between clients, between threads (you don’t control them).
Even if you’ll often end with a Lock, in some cases there is easier options. Think to a singleton case. You can use an @ApplicationScoped bean and CDI will take care of the technical code for you. Hopefully next WebSocket spec version will handle Session (websocket one) scope and maybe request scope (message?). If this is crucial for your app you can already implement it yourself using surely CDI endpoints and interceptors to activate/deactivate contexts.
So now you have endpoints, you contact them through js or java without issues but….what’s the performances? The main issue the old implementation (based on servlets) had was the fact it was binding a thread by client. Now Tomcat uses NIO by default and it changes everything (that’s why last release is a bit longer to stop because it waits a bit to be sure it can stop – Note: this is enhanced on trunk). Relying on NIO and eventing means you can use a single thread of pool shared for all clients and you don’t need a thread by client anymore. This is of course configurable (see http://ci.apache.org/projects/tomcat/tomcat8/docs/web-socket-howto.html) but it already allows a clearly better scalling of your app!
Last note (even if obvious): you need to run in java 7 if you want the websockets to be deployed.
So the conclusion is WebSocket in Tomcat is now production ready and combined with TomEE you can benefit from CDI to simplify the technical layer implied by WebSocket usage.
Last tip: combine WebSocket with CDI events and EJB @Asynchronous methods and you get a pretty highly scalable system!
It didnt work for me I am using java 7 below is details. Help will be really appreciated.
have a simple websocket application which I have deployed on tomcat 7.0.52. I am using JSR 356 API javax.websocket-api-1.0-b08.jar.
My Java server side code is
import javax.websocket.server.ServerEndpoint;
import javax.websocket.*;
@ServerEndpoint(“/hello”)
public class HelloBean {
@OnMessage
public String sayHello(String name)
{
return name + “return”;
}
}
Whenever i try to connect to websocket it throws me error that its close.
On Client end (javascript) : Code is as follows
var ws = new WebSocket(“ws://localhost:8080/hello”);
ws.onopen = function()
{
ws.send(“Message to send”);
};
ws.onmessage = function (evt)
{ // var received_msg = evt.data;
alert(“Message is received…”);
};
ws.onclose = function()
{
// websocket is closed.
alert(“Connection is closed…”);
};
I am not able to understand why it is showing connection is closed message.
You don’t have to provide the api in your app otherwise it will surely not work as expected. In all case a mail to the list (tomcat or tomee) is the best place to get support.