WebSocket is a web technology providing full-duplex communications channels over a single TCP connection. WebSocket is designed to be implemented in web browsers and web servers, but it can be used by any client or server application. In this tutorial we will use a Java server and a JavaScript client.
We start with the Java server. Start by downloading the Jetty distribution files, at the time of writing the latest version was jetty-distribution-9.0.5.v20130815. Unzip this file and copy the lib directory to a place where your Java application (which we will build in a moment) can find it. Now create a Java project and start with the WebSocketTest class file:
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.websocket.server.WebSocketHandler; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; public class WebSocketTest { public static void main(String[] args) throws Exception { Server server = new Server(8080); WebSocketHandler wsHandler = new WebSocketHandler() { @Override public void configure(WebSocketServletFactory factory) { factory.register(MyWebSocketHandler.class); } }; server.setHandler(wsHandler); server.start(); server.join(); } }
Now create the MyWebSocketHandler class:
import java.io.IOException; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; @WebSocket public class MyWebSocketHandler { @OnWebSocketClose public void onClose(int statusCode, String reason) { System.out.println("Close: statusCode=" + statusCode + ", reason=" + reason); } @OnWebSocketError public void onError(Throwable t) { System.out.println("Error: " + t.getMessage()); } @OnWebSocketConnect public void onConnect(Session session) { System.out.println("Connect: " + session.getRemoteAddress().getAddress()); try { session.getRemote().sendString("Hello Webbrowser"); } catch (IOException e) { e.printStackTrace(); } } @OnWebSocketMessage public void onMessage(String message) { System.out.println("Message: " + message); } }
The server side of things is now done. The client is written in Javascript with some HTML to make it work. The index.html file looks like this:
<!DOCTYPE html> <html> <body> <h1>WebSocket test</h1> <script src="index.js"></script> </body> </html>
And the referenced index.js looks like this:
var ws = new WebSocket("ws://127.0.0.1:8080/"); ws.onopen = function() { alert("Opened!"); ws.send("Hello Server"); }; ws.onmessage = function (evt) { alert("Message: " + evt.data); }; ws.onclose = function() { alert("Closed!"); }; ws.onerror = function(err) { alert("Error: " + err); };
Now startup the server side by running the main of the WebSocketTest class and startup the client by pointing your webbrowser to the index.html file. If your browser is new enough to support WebSocket, you should see that the client and the server connect with each other and that the server sends a message to the client and vice versa. On the client:
On the server:
If we wait long enough, a timeout will occur, resulting in the following message on the client:
and this on the server:
Thanks for sharing! There are a couple of examples for seting up a websocket server, but your’s is pretty simple and easy to begin with.
can you mail me you example full android project file?
l try form your example code, but I finally crash in phone.
Thank you.
Hi,
I just followed the above instruction but, I’m getting below exception,
” WebSocket connection to ‘ws://localhost:8989/WS/’ failed: Error during WebSocket handshake: Unexpected response code: 200 ”
Could some one please help me regarding the same?
Thanks in Advance,
-Kamesh
MY GOODNESSSSS
Thank you so very much Sir! I’ve searched for something like this for god knows how long… many websocket and jetty example out there, but for me who’s total newbie in web programming and fucked up understanding in backend programming, a neat simple example and up-to-date (thank you very much for using Jetty 9.x…) like this is so… *sobs* Again, thank you so very much Sir! ( TvT)
not working for android mobile(4.4 version, chrome browser).
Got it working eventually by changing the port to 8081.
Its as if Jetty was listening on 8080 and doing nothing with the client connection (like jetty didnt not get told of a handler).
I wasnt running Jetty by specifying a main class, but using the “java -jar start.jar” and deploying a webapp.
How do I run it main class method + as well as have the webapp with index.html etc deployed?
Or do I have to split it up? Tutorial makes it sound like one deployable artefact should work.
Still confused…unless I split it into two.
Pingback:Netbeans Jetty Override Added and Removed
Thanks for the tutorial.
It’s working for me with Chrome but not with Firefox / IE.
Both browsers are using WebSocket Version 13.
In FF the connection is immediately closed after it is established (@OnWebSocketConnect is called, @OnWebSocketClose immediately after it). The close reason is 1001 or sth. 1005.
Any ideas?
thx for help.
Thank you very much for your tutorial: it’s valuable and effective.
Good job indeed!
Andy C.
I’m experimenting with your code: it is very instructive, thank you again.
A question regarding “MyWebSocketHandler” class: in your code, the Server sends a msg back to the Client inside the “onConnect” method, using “session”.
Instead, how can I send a msg back to the Client inside the “onMessage” method? In this method, “session” seems not to be available.
Any suggestion?
Thank you very much for your help.
Bye,
Andy C.
Use:
@OnWebSocketMessage
public void onMessage(Session session, String message) {
System.out.println(“Message: ” + message);
ModelTask task = EngineTaskFacade.getInstance().runModel(message);
try {
session.getRemote().sendString(“Echo”);
} catch (IOException e) {
e.printStackTrace();
}
}
Thank you very much.
I would just like to add the necessary maven dependencies:
org.eclipse.jetty
jetty-server
9.3.0.M2
org.eclipse.jetty
jetty-servlet
9.3.0.M2
jar
org.eclipse.jetty.websocket
websocket-api
9.3.0.M2
org.eclipse.jetty.websocket
websocket-server
9.3.0.M2
Use :
@OnWebSocketMessage
public void onMessage(Session session, String message) {
System.out.println(“Message: ” + message);
try {
session.getRemote().sendString(“Echo”);
} catch (IOException e) {
e.printStackTrace();
}
}
Hi than you for the tutorial
I am in doubt about how to add the jetty libs. to the project
should I
1:rightclick/build path/configure buildpath/libraries/add library?
2: copy paste the libs into one of my folders
regards martin
Hi
When I try to run the program, it cannot find the Server. I get a classnotfoundException.
could someone please give me a clue?
Hey great example! I’m trying to get a Jetty Server to talk to Unity 5 via websocket sharp. Managed to send PNG files to the client and added them as a texture, but can’t get the darn client to send a string to request the files. Anyone come across this? I can send to the server using websocket.send (ws.send here) from a browser using javascript, but get the feeling like I need to mess around with the encoding and manually transmit packets of bytes to the server, anyway just guessing. Anyone know the format that .Send uses to transmit packages? Handshake works fine.
thank you sir
You are rock!!!!
good simple example
Hello,
I just downloaded jetty-distribution-9.4.2.v20170220. and got following compilation errors:
Would you know they have done any breaking change?
Exception in thread “main” java.lang.Error: Unresolved compilation problems:
The method start() is undefined for the type WebSocketClient
The type org.eclipse.jetty.websocket.api.Session cannot be resolved. It is indirectly referenced from required .class files
The method connect(Object, URI, ClientUpgradeRequest) from the type WebSocketClient refers to the missing type Session
The method awaitClose(int, TimeUnit) is undefined for the type IgnitionAdapter
The type org.eclipse.jetty.util.component.ContainerLifeCycle cannot be resolved. It is indirectly referenced from required .class files
The type org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope cannot be resolved. It is indirectly referenced from required .class files
The method stop() is undefined for the type WebSocketClient
at com.tesla.hermes.ignitionadapter.IgnitionAdapter.main(IgnitionAdapter.java:27)
Worked like chram.!!!
Thank you sir…
Good Example,
Wondering would this work when Users behind Proxies , Firewalls and CDN ?
Excellent! A lot of thanks!
Where are the import libraries such as org.eclipse.jetty.websocket.api.annotations.WebSocket