EDIT: removed reference to C# as the only accepted answer is about Java. If someone needs information about websocket server implementation in C#, ask a new
The accepted answer is 3 years old, with the recent release of JEE7, now every Web Containers that implement servert 3.1 will support websocket via standard API (javax.websocket) package.
The following code show example how to implement websocket using JEE7:
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/chat")
public class ChatServer {
private static final Logger LOGGER =
Logger.getLogger(ChatServer.class.getName());
@OnOpen
public void onOpen(Session session) {
LOGGER.log(Level.INFO, "New connection with client: {0}",
session.getId());
}
@OnMessage
public String onMessage(String message, Session session) {
LOGGER.log(Level.INFO, "New message from Client [{0}]: {1}",
new Object[] {session.getId(), message});
return "Server received [" + message + "]";
}
@OnClose
public void onClose(Session session) {
LOGGER.log(Level.INFO, "Close connection for client: {0}",
session.getId());
}
@OnError
public void onError(Throwable exception, Session session) {
LOGGER.log(Level.INFO, "Error for client: {0}", session.getId());
}
}
Example in details here.
Web Container that support Websocket:
The Vert.x option is also worth considering.
Creating a ws server can be as simple as
vertx.websocketHandler(new Handler<ServerWebSocket>() {
public void handle(ServerWebSocket ws) {
// A WebSocket has connected!
}
}).listen(8080);
or
vertx.createHttpServer().websocketHandler(new Handler<ServerWebSocket>() {
@Override
public void handle(final ServerWebSocket ws) {
logger.info("ws connection established with " + ws.remoteAddress());
ws.dataHandler(new Handler<Buffer>() {
@Override
public void handle(Buffer data) {
JsonObject item = new JsonObject(data.toString());
logger.info("data in -> " + item.encodePrettily());
// if you want to write something back in response to the client
//ws.writeTextFrame(...);
}
});
}
}).listen(port, new Handler<AsyncResult<HttpServer>>() {
@Override
public void handle(AsyncResult<HttpServer> event) {
logger.info("ws server is up and listening on port " + port);
}
});
For more details look here http://vertx.io/docs/vertx-core/java/#_websockets
So one can write his own WebSocket server with Vert.x, package it as FatJar, and run it on its own.
Or you can embed Vert.x env. in your app, and deploy your verticle (that implements the ws server) programmatically.
Another alternative is JBoss's web server Undertow. Which is easily embeddable in applications.
Add these dependencies:
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<version>${version.io.undertow}</version>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
<version>${version.io.undertow}</version>
</dependency>
And here's a sample ws server:
Undertow server = Undertow.builder()
.addHttpListener(8080, "localhost")
.setHandler(path()
.addPrefixPath("/myapp", websocket(new WebSocketConnectionCallback() {
@Override
public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) {
channel.getReceiveSetter().set(new AbstractReceiveListener() {
@Override
protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) {
final String messageData = message.getData();
for (WebSocketChannel session : channel.getPeerConnections()) {
WebSockets.sendText(messageData, session, null);
}
}
});
channel.resumeReceives();
}
}))
.build();
server.start();
JETTY
I've spent the past week mauling over how to make a WebSocket server. Finally got something to work hope this helps. It uses libraries from Jetty (jars).
File WebRTC_IceServer.java
package com.evanstools;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.websocket.server.*;
public class WebRTC_IceServer{
public static void main(String[] args){
try{
////////////////////////
if(args.length == 0){
System.out.printf("%s%n","WebRTC_IceServer [port]");
return;
}
Server server = new Server(Integer.parseInt(args[0]));
WebSocketHandler.Simple webSocketHandlerSimple = new WebSocketHandler.Simple(WebsocketPOJO.class);
server.setHandler(webSocketHandlerSimple);
server.start();
server.join();
////////////////////////
}catch(Exception w){w.printStackTrace();}
}
}
File WebsocketPOJO.java
package com.evanstools;
import org.eclipse.jetty.websocket.api.annotations.*;
import org.eclipse.jetty.websocket.api.Session;
//The class must be not abstract and public.
@WebSocket
public class WebsocketPOJO{
//Flags one method in the class as receiving the On Connect event.
//Method must be public, not abstract, return void, and have a single Session parameter.
@OnWebSocketConnect
public void onWebSocketConnect(Session session){
System.out.printf("%s%n","test client connected");
}
//Flags one method in the class as receiving the On Close event.
//Method signature must be public, not abstract, and return void.
//The method parameters:
////Session (optional)
////int closeCode (required)
////String closeReason (required)
@OnWebSocketClose
public void OnWebSocketClose(Session session,int closeCode,String closeReason){}
//Flags up to 2 methods in the class as receiving On Message events.
//You can have 1 method for TEXT messages, and 1 method for BINARY messages.
//Method signature must be public, not abstract, and return void.
//The method parameters for Text messages:
////Session (optional)
////String text (required)
//The method parameters for Binary messages:
////Session (optional)
////byte buf[] (required)
////int offset (required)
////int length (required)
@OnWebSocketMessage
public void onWebSocketMessageString(Session session, String text){}
//Flags one method in the class as receiving Error events from the WebSocket implementation.
//Method signatures must be public, not abstract, and return void.
//The method parameters:
////Session (optional)
////Throwable cause (required)
//@OnWebSocketError
//Flags one method in the class as receiving Frame events from the WebSocket implementation after they have been processed by any extensions declared during the Upgrade handshake.
//Method signatures must be public, not abstract, and return void.
//The method parameters:
////Session (optional)
///Frame (required)
//The Frame received will be notified on this method, then be processed by Jetty, possibly resulting in another event, such as On Close, or On Message. Changes to the Frame will not be seen by Jetty.
//@OnWebSocketFrame
}
Apache Tomcat 8.0 implements WebSockets 1.1 API (JSR-356). You can even play with examples after installing by navigating to examples folder: there are echo chat and snake game.
For Java, check out this informative post. Copy-paste from there:
Out of these options, I guess Jetty and Resin are the most mature and stable. However, always good to do your own testing.
Take a look at the Bristleback Framework. It is a high level overlay for commonly used Java Websocket Servers, like Jetty, Netty or Tomcat. If you like Spring Framework, you must definitely try Bristleback!
Disclaimer: I'm a contributor in Bristleback Framework project.