Skip to content

@jettro /ChatMessageInbound.java
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
This gist describes a web project that makes use of Tomcat features to create a WebSocket sample
package wsapp;
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.WsOutbound;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
/**
* This class represents a client, each client has a link to the repository that contains all clients
*/
public class ChatMessageInbound extends MessageInbound {
private ClientsRepository repository;
public ChatMessageInbound(ClientsRepository repository) {
this.repository = repository;
}
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
repository.sendMessageToAll(message);
}
@Override
protected void onBinaryMessage(ByteBuffer message) throws IOException {
// no-op
}
@Override
protected void onOpen(WsOutbound outbound) {
repository.sendMessageToAll(CharBuffer.wrap("New client connected"));
repository.addClient(this);
}
@Override
protected void onClose(int status) {
repository.removeClient(this);
repository.sendMessageToAll(CharBuffer.wrap("Lost a client"));
}
}
package wsapp;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* This repository takes care of registering connected clients and of course removing them when they
* disconnect.
*/
public class ClientsRepository {
private List<ChatMessageInbound> clients = new ArrayList<>();
/**
* Add a new client to the repository.
*
* @param messageInbound ChatMessageInbound that is the actual client
*/
public void addClient(ChatMessageInbound messageInbound) {
this.clients.add(messageInbound);
}
/**
* Removes the provided client from the repository.
*
* @param messageInbound ChatMessageInbound that is the actual client
*/
public void removeClient(ChatMessageInbound messageInbound) {
clients.remove(messageInbound);
}
/**
* Send a message to all clients.
*
* @param message CharBuffer containing the message to send to all clients
*/
public void sendMessageToAll(CharBuffer message) {
try {
for (ChatMessageInbound client : clients) {
CharBuffer buffer = CharBuffer.wrap(message);
client.getWsOutbound().writeTextMessage(buffer);
client.getWsOutbound().flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset=UTF-8>
<title>Tomcat WebSocket Chat</title>
<script>
var ws = new WebSocket("ws://localhost:8080/wschat/WsChatServlet");
ws.onopen = function(){
};
ws.onmessage = function(message){
document.getElementById("chatlog").textContent += message.data + "\n";
};
function postToServer(){
ws.send(document.getElementById("msg").value);
document.getElementById("msg").value = "";
}
function closeConnect(){
ws.close();
}
</script>
</head>
<body>
<textarea id="chatlog" cols="50" rows="10" readonly></textarea><br/>
<input id="msg" type="text" />
<button type="submit" id="sendButton" onClick="postToServer()">Send!</button>
<button type="button" id="endButton" onClick="closeConnect()">End</button>
</body>
</html>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.gridshore</groupId>
<artifactId>websocket-test</artifactId>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<properties>
<tomcat.version>7.0.42</tomcat.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>${tomcat.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>WsChatServlet</servlet-name>
<servlet-class>wsapp.WebsocketChatServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WsChatServlet</servlet-name>
<url-pattern>/wschat/WsChatServlet</url-pattern>
</servlet-mapping>
</web-app>
/**
* Chat servlet that creates the MessageInbound instances and creates the repository that manages all the
* clients.
*/
public class WebsocketChatServlet extends WebSocketServlet {
private ClientsRepository repository;
@Override
public void init() throws ServletException {
super.init();
repository = new ClientsRepository();
}
@Override
protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest httpServletRequest) {
return new ChatMessageInbound(repository);
}
}
@Dgiffone

Hi Jettro, very cool and above all easy and fast.
Just a doubt: ClientsRepository clients attribute supposed to be thread unsafe. Is that correct?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.