Accueil > Jetty, WebSockets > WebSockets with Embedding Jetty [step4]

WebSockets with Embedding Jetty [step4]


In [step3] we have created Chat WebSocket on server side and start the Jetty server with a Java main by using Embedding Jetty.

In this article we will create a chat WEB Application which hosts chat.html. The chat WEB Application will be started on the 8080 port with Tomcat 6 by using Eclipse WTP Adaptor. This WEB Application will use the javax.servlet.ServletContextListener ChatServerServletContextListener for LifecycleListener :

  1. when the WEB Application starts, the Embedding Jetty starts on the 8081 port. Chat WebSocket on server side will be available at ws://localhost:8081/.
  2. when the WEB Application stops, the Embedding Jetty stops.

Here a scheme which shows you the architecture of the chat application hosted by Tomcat Server (8080 port) and WebSocket managed with Jetty Server (8081 port) :

This schema shows you that:

  • HTTP request will be used on the 8080 port (ex : display the chat.html) to use Tomcat Server which doesn’t support WebSocket.
  • WebSocket request will be used on the 8081 port (ex : click on the « Join » button to join the chat) to use Jetty Server which supports WebSocket.

Download

You can download chat-webapp.zip which contains Eclipse WTP Dynamic Web Project chat-webapp which is a the chat WEB Application configured with Tomcat 6 for WTP Tomcat Adaptor explained in this article.

Initialize WEB Application

In this section we will create and initialize an Eclipse WTP Dynamic Web Project chat-webapp to add Jetty-WebSocket JARs, chat.html and ChatWebSocketHandler :

  1. Create a WEB Application with Dynamic Web Project with name chat-webapp. In my case I have used WTP Tomcat Adaptor with Tomcat 6.
  2. Copy chat.html in the /WebContent folder of the WEB Application.
  3. Copy Jetty-WebSocket JARs in the /WEB-INF/lib folder without servlet-api-2.5.jar because Tomcat already defines this JAR.
  4. Copy/Paste the ChatWebSocketHandler in the WEB Application.

Your workspace looks like this:

Create Listener

In this section we will create an implementation of javax.servlet.ServletContextListener to start and stop Jetty Server when WEB Application starts and stops.

ChatServerServletContextListener

Create org.samples.websockets.embeddingjetty.ChatServerServletContextListener like this:

package org.samples.websockets.embeddingjetty;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;

/**
 * Application Lifecycle Listener implementation for start/stop Embedding Jetty
 * Server configured to manage Chat WebSocket with {@link ChatWebSocketHandler}.
 * 
 */
public class ChatServerServletContextListener implements ServletContextListener {

	private Server server = null;

	/**
	 * Start Embedding Jetty server when WEB Application is started.
	 * 
	 */
	public void contextInitialized(ServletContextEvent event) {
		try {
			// 1) Create a Jetty server with the 8091 port.
			this.server = new Server(8081);
			// 2) Register ChatWebSocketHandler in the Jetty server instance.
			ChatWebSocketHandler chatWebSocketHandler = new ChatWebSocketHandler();
			chatWebSocketHandler.setHandler(new DefaultHandler());
			server.setHandler(chatWebSocketHandler);
			// 2) Start the Jetty server.
			server.start();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/**
	 * Stop Embedding Jetty server when WEB Application is stopped.
	 */
	public void contextDestroyed(ServletContextEvent event) {
		if (server != null) {
			try {
				// stop the Jetty server.
				server.stop();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

web.xml

Declare the ChatServerServletContextListener listener in the web.xml like this:

<listener>
	<listener-class>org.samples.websockets.embeddingjetty.ChatServerServletContextListener</listener-class>
</listener>

Here the full web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>chat-webapp</display-name>
	<welcome-file-list>
		<welcome-file>chat.html</welcome-file>
	</welcome-file-list>
	<listener>
		<listener-class>org.samples.websockets.embeddingjetty.ChatServerServletContextListener</listener-class>
	</listener>
</web-app>

Your workspace looks like this :

Play with chat application!

Start Tomcat Server, open a Google Chrome and go to the http://localhost:8080/chat-webapp/chat.html URL to play with the chat application :

Limitation with Embedding Jetty

The Embedding Jetty is a simple solution to support WebSocket on server side for any Java server. The 2 requirements with this solution are :

  • the Java server must support servlet 2.5 API because Embedding Jetty needs this JAR.
  • port of the Java Server and the Embedding Jetty must be different otherwise it will have a conflict.

Embedding Jetty problem with same port than Java Server

Testing the second point (Embedding Jetty with same port of the Java Server) is very easy. After modifying the port of the Embedding Jetty of the ChatServerServletContextListener like this :

...
this.server = new Server(8080);
...

If you restart your Java Server (in my case Tomcat 6) and go to the http://localhost:8080/chat-webapp/chat.html URL, you will have 404 error :

The 404 error is thrown by the Embedding Jetty Server. It means that Embedding Jetty Server overrides the Java Server Tomcat 6.

Another problem with Embedding Jetty

I had discussion with Greg Wilkins the creator of the Jetty-WebSocket about the Embedding Jetty to manage WebSockets like I have suggested you. He tell me that they are another problems. With a separate server you will get something that looks like :

         +---HTTP------> Websphere -----> Req/Resp Application code
        /                                              ^
       /                                               |
Browser                                             Some link
       \                                               |
        \                                              v
         +---Websocket-> Jetty ---------> Messaging Application code
-----------------------------------------------------------------------------------------

You also get problems that HTTP and websocket are going to different hosts, so it is hard to share cookies and other security issues.

Jetty Proxy seems to be the solution?

The solution who he has suggested me is to use Jetty Proxy. Using a proxy, you can make the Jetty server the main server for all connections, but have the application logic on the Java Server (Tomcat, WebShpere…) :

Browser====HTTP/Websocket=====>Jetty----HTTP----> Websphere ----> Application
  • Jetty would pass normal HTTP requests through to the Java Server (Tomcat, WebShpere…) WEB Application.
  • Jetty would pass received WebSocket messages to the Java Server (Tomcat, WebShpere…) WEB Application as HTTP requests.

To send a WebSocket message, the WebSocket application would make a HTTP request to Jetty, which would then send the WebSocket message.

I have not studied Jetty Proxy but if I can do something, I will create a new article about that.

Conclusion

This article shows you that it’s easy to support WebSocket for any Java Server by using Embedding Jetty. However it exists some limitations like port problem, cookies and security that Greg Wilkins has explained. Jetty Proxy could be a solution but I have not studied that.

Catégories :Jetty, WebSockets
  1. août 28, 2011 à 5:55

    Isn’t the Jetty WebSockets implementation server agnostic? Since it is initiated via standard servlets and it accepts incoming requests via the doGet() method, I’m not sure why anyone would embed Jetty into a third-party server to just use the websocket implementation. Can the implementation be used outside of Jetty?

    • août 28, 2011 à 9:45

      Hi,

      To support WebSocket, Server must manage asynchronysous response. Servlet 3 specify that, but I’m not sure that a lot of JEE Server (WebSphere, WebLogic, etc….) implements this feature.
      More WebSocket manage ws protocol, so I don’t know if all JEE Server can support this protocol?
      After studying several implementation of WebSocket, I found that Jetty solution was very easy to implement and it works with any JEE Server. I don’t think that Jetty implementation can be used outside of Jetty (but I have never tested).

      Hope that Servlet 3 specification will be implemented soon (for manage asynchronysous response) for the all JEE Server to benefit from WebSocket.

      Regards Angelo

  2. décembre 11, 2011 à 8:06

    Thanks a lot Angelo, your four part tutorial on websockets really helped me to quickly get get started.

  3. Mai 13, 2013 à 10:20

    nice write up. enjoyed it.

  1. juillet 26, 2011 à 3:06

Laisser un commentaire