Websocket with jetty 9 and osgi
See [Servlet with Jetty 7 and OSGI](Servlet with Jetty 7 and OSGI) for working with servlets.
For Websockets and Jetty 9, here's what I did to connect a simple Jetty WebSocket client to a Jetty WebSocket server. I wanted to host the server in an OSGI container.
First off, I downloaded the Jetty 9 distribution, then drug all of the jetty-distribution-9.1.0.v20131115/lib/*.jar into the Eclipse Repositories view Local repository (this view comes with bndtools). This allowed me to quickly add the Jetty bundles as available build and runtime bundles for this example.
I created a new OSGI bnd project called mybundle and a few files:
MyWebSocket.java - where you do your WebSocket implementation.
package example;
@WebSocket
public class MyWebSocket {
@OnWebSocketMessage
public void onText(Session session, String message) {
if (session.isOpen()) {
System.out.printf("Echoing back message [%s]%n", message);
session.getRemote().sendString(message, null);
}
}
}
MyWebSocketServlet.java - Upgrades standard HTTP GET to websocket connection.
package example;
public class MyWebSocketServlet extends WebSocketServlet {
@Override
public void configure(WebSocketServletFactory arg0) {
arg0.register(LanternWebSocket.class);
}
}
WEB-INF/web.xml - inside bundle. This was easiest means to "register" servlet with Jetty. Maybe in the future something like the felix whiteboard bundle will be available to detect an available WebSocket rather than including this web.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<javaee:display-name>WebSocket Test Application</javaee:display-name>
<servlet>
<servlet-name>WebSocketTest</servlet-name>
<servlet-class>example.MyWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WebSocketTest</servlet-name>
<url-pattern>/echo/*</url-pattern>
</servlet-mapping>
</web-app>
bnd.bnd
Export-Package: example
Service-Component: \
*
-buildpath: \
osgi.core,\
osgi.cmpn,\
biz.aQute.bnd.annotation,\
${junit},\
org.eclipse.jetty.websocket.api,\
org.eclipse.jetty.websocket.client,\
org.eclipse.jetty.websocket.common,\
org.eclipse.jetty.websocket.javax.websocket,\
org.eclipse.jetty.websocket.javax.websocket.server,\
org.eclipse.jetty.websocket.server,\
org.eclipse.jetty.websocket.servlet,\
org.eclipse.jetty.http,\
javax.websocket-api,\
org.eclipse.jetty.deploy,\
org.eclipse.jetty.io,\
org.eclipse.jetty.osgi.boot,\
org.eclipse.jetty.security,\
org.eclipse.jetty.server,\
org.eclipse.jetty.servlet,\
org.eclipse.jetty.util,\
org.eclipse.jetty.webapp,\
org.eclipse.jetty.xml,\
javax.servlet-api
Bundle-Version:0.0.0.${tstamp}
-includeresource: WEB-INF/web.xml=${project}/web.xml
run.bndrun
-runfw:org.apache.felix.framework;version='[4.2.1,4.2.1]'
-runee:JavaSE-1.7
-runsystemcapabilities: ${native_capability}
-resolve.effective: active
-runbundles: \
javax.servlet-api;version='[3.1.0,3.1.1)',\
mybundle;version=latest,\
org.apache.felix.configadmin;version='[1.6.0,1.6.1)',\
org.apache.felix.gogo.command;version='[0.12.0,0.12.1)',\
org.apache.felix.gogo.runtime;version='[0.10.0,0.10.1)',\
org.apache.felix.gogo.shell;version='[0.10.0,0.10.1)',\
org.apache.felix.log;version='[1.0.1,1.0.2)',\
org.apache.felix.metatype;version='[1.0.4,1.0.5)',\
org.apache.felix.scr;version='[1.6.2,1.6.3)',\
org.apache.felix.webconsole;version='[3.1.8,3.1.9)',\
org.eclipse.jetty.deploy;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.http;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.io;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.osgi.boot;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.security;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.server;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.servlet;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.util;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.webapp;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.websocket.api;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.websocket.common;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.websocket.server;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.websocket.servlet;version='[9.1.0,9.1.1)',\
org.eclipse.jetty.xml;version='[9.1.0,9.1.1)',\
osgi.cmpn;version='[5.0.0,5.0.1)',\
osgi.enterprise;version='[4.2.0,4.2.1)',\
osgi.residential;version='[4.3.0,4.3.1)'
-runrequires: \
osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.shell)',\
osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)',\
osgi.identity;filter:='(osgi.identity=org.apache.felix.webconsole)',\
osgi.identity;filter:='(osgi.identity=org.apache.felix.configadmin)',\
osgi.identity;filter:='(osgi.identity=org.apache.felix.metatype)',\
osgi.identity;filter:='(osgi.identity=org.apache.felix.log)',\
osgi.identity;filter:='(&(osgi.identity=osgi.cmpn)(version>=4.2))',\
osgi.identity;filter:='(&(osgi.identity=org.apache.felix.scr)(version>=1.6.0))',\
osgi.identity;filter:='(osgi.identity=mybundle)',\
osgi.identity;filter:='(osgi.identity=org.eclipse.jetty.osgi.boot)',\
osgi.identity;filter:='(osgi.identity=org.eclipse.jetty.websocket.server)'
## Uncomment if you need to change the HTTP port
#-runproperties: org.osgi.service.http.port=8080
-runvm:-Djetty.home.bundle=org.eclipse.jetty.osgi.boot
I used the example WebSocket Client code from here to test the WebSocket server code - http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html
the clienttest bnd.bnd file -- I included the bnd.bnd I used to build the code from the client example. I basically just added the jetty bundles to the buildpath.
Private-Package: \
org.example
Service-Component: \
*
-buildpath: \
osgi.core,\
osgi.cmpn,\
biz.aQute.bnd.annotation,\
${junit},\
org.apache.felix.http.api,\
org.apache.felix.http.jetty,\
org.apache.felix.http.whiteboard,\
org.eclipse.jetty.deploy,\
org.eclipse.jetty.http,\
org.eclipse.jetty.io,\
org.eclipse.jetty.osgi.boot,\
org.eclipse.jetty.security,\
org.eclipse.jetty.server,\
org.eclipse.jetty.servlet,\
org.eclipse.jetty.util,\
org.eclipse.jetty.webapp,\
org.eclipse.jetty.websocket.api,\
org.eclipse.jetty.websocket.client,\
org.eclipse.jetty.websocket.common,\
org.eclipse.jetty.websocket.javax.websocket,\
org.eclipse.jetty.websocket.javax.websocket.server,\
org.eclipse.jetty.websocket.server,\
org.eclipse.jetty.websocket.servlet,\
org.eclipse.jetty.xml
Bundle-Version:0.0.0.${tstamp}
To test
- Run the run.bndrun to start the server
- Run the SimpleEchoClient in eclipse as a Java app. First argument to the SimpleEchoClient app should be something like this ws://localhost:8080/mybundle/echo/sdf