Skip to content

Commit

Permalink
Bael 389 - Chat-like app using the Java API for WebSocket (eugenp#1265)
Browse files Browse the repository at this point in the history
* Project for " A Guide to the Java API for WebSocket" article

* Setting dependencies correctly

* Formatting adjustments

* Removing tomcat7 maven plugin

* Applying formatt - No spaces
  • Loading branch information
Alex Vargas authored and zhendrikse committed Mar 5, 2017
1 parent 181688a commit c83c449
Show file tree
Hide file tree
Showing 10 changed files with 408 additions and 0 deletions.
41 changes: 41 additions & 0 deletions java-websocket/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<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>com.baeldung</groupId>
<artifactId>java-websocket</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>java-websocket Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
36 changes: 36 additions & 0 deletions java-websocket/src/main/java/com/baeldung/model/Message.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.baeldung.model;

public class Message {
private String from;
private String to;
private String content;

@Override
public String toString() {
return super.toString();
}

public String getFrom() {
return from;
}

public void setFrom(String from) {
this.from = from;
}

public String getTo() {
return to;
}

public void setTo(String to) {
this.to = to;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.baeldung.websocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.EncodeException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import com.baeldung.model.Message;

@ServerEndpoint(value = "/chat/{username}", decoders = MessageDecoder.class, encoders = MessageEncoder.class)
public class ChatEndpoint {
private Session session;
private static final Set<ChatEndpoint> chatEndpoints = new CopyOnWriteArraySet<>();
private static HashMap<String, String> users = new HashMap<>();

@OnOpen
public void onOpen(Session session, @PathParam("username") String username) throws IOException, EncodeException {

this.session = session;
chatEndpoints.add(this);
users.put(session.getId(), username);

Message message = new Message();
message.setFrom(username);
message.setContent("Connected!");
broadcast(message);
}

@OnMessage
public void onMessage(Session session, Message message) throws IOException, EncodeException {
message.setFrom(users.get(session.getId()));
broadcast(message);
}

@OnClose
public void onClose(Session session) throws IOException, EncodeException {
chatEndpoints.remove(this);
Message message = new Message();
message.setFrom(users.get(session.getId()));
message.setContent("Disconnected!");
broadcast(message);
}

@OnError
public void onError(Session session, Throwable throwable) {
// Do error handling here
}

private static void broadcast(Message message) throws IOException, EncodeException {
chatEndpoints.forEach(endpoint -> {
synchronized (endpoint) {
try {
endpoint.session.getBasicRemote()
.sendObject(message);
} catch (IOException | EncodeException e) {
e.printStackTrace();
}
}
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.baeldung.websocket;

import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;

import com.baeldung.model.Message;
import com.google.gson.Gson;

public class MessageDecoder implements Decoder.Text<Message> {
@Override
public Message decode(String s) throws DecodeException {
Gson gson = new Gson();
Message message = gson.fromJson(s, Message.class);
return message;
}

@Override
public boolean willDecode(String s) {
return (s != null);
}

@Override
public void init(EndpointConfig endpointConfig) {
// Custom initialization logic
}

@Override
public void destroy() {
// Close resources
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.baeldung.websocket;

import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;

import com.baeldung.model.Message;
import com.google.gson.Gson;

public class MessageEncoder implements Encoder.Text<Message> {
@Override
public String encode(Message message) throws EncodeException {
Gson gson = new Gson();
String json = gson.toJson(message);
return json;
}

@Override
public void init(EndpointConfig endpointConfig) {
// Custom initialization logic
}

@Override
public void destroy() {
// Close resources
}
}
5 changes: 5 additions & 0 deletions java-websocket/src/main/webapp/WEB-INF/beans.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_0.xsd">
</beans>
7 changes: 7 additions & 0 deletions java-websocket/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>
30 changes: 30 additions & 0 deletions java-websocket/src/main/webapp/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<html>
<head>
<title>Chat</title>
</head>
<body>

<table>
<tr>
<td colspan="2">
<input type="text" id="username" placeholder="Username"/>
<button type="button" onclick="connect();" >Connect</button>
</td>
</tr>
<tr>
<td>
<textarea readonly="true" rows="10" cols="80" id="log"></textarea>
</td>
</tr>
<tr>
<td>
<input type="text" size="51" id="msg" placeholder="Message"/>
<button type="button" onclick="send();" >Send</button>
</td>
</tr>
</table>
</body>

<script src="websocket.js"></script>

</html>
136 changes: 136 additions & 0 deletions java-websocket/src/main/webapp/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 80%;
background-color: #1f1f1f;
}

#wrapper {
width: 960px;
margin: auto;
text-align: left;
color: #d9d9d9;
}

p {
text-align: left;
}

.button {
display: inline;
color: #fff;
background-color: #f2791d;
padding: 8px;
margin: auto;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
box-shadow: none;
border: none;
}

.button:hover {
background-color: #ffb15e;
}
.button a, a:visited, a:hover, a:active {
color: #fff;
text-decoration: none;
}

#addDevice {
text-align: center;
width: 960px;
margin: auto;
margin-bottom: 10px;
}

#addDeviceForm {
text-align: left;
width: 400px;
margin: auto;
padding: 10px;
}

#addDeviceForm span {
display: block;
}

#content {
margin: auto;
width: 960px;
}

.device {
width: 180px;
height: 110px;
margin: 10px;
padding: 16px;
color: #fff;
vertical-align: top;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
display: inline-block;
}

.device.off {
background-color: #c8cccf;
}

.device span {
display: block;
}

.deviceName {
text-align: center;
font-weight: bold;
margin-bottom: 12px;
}

.removeDevice {
margin-top: 12px;
text-align: center;
}

.device.Appliance {
background-color: #5eb85e;
}

.device.Appliance a:hover {
color: #a1ed82;
}

.device.Electronics {
background-color: #0f90d1;
}

.device.Electronics a:hover {
color: #4badd1;
}

.device.Lights {
background-color: #c2a00c;
}

.device.Lights a:hover {
color: #fad232;
}

.device.Other {
background-color: #db524d;
}

.device.Other a:hover {
color: #ff907d;
}

.device a {
text-decoration: none;
}

.device a:visited, a:active, a:hover {
color: #fff;
}

.device a:hover {
text-decoration: underline;
}
Loading

0 comments on commit c83c449

Please sign in to comment.