Creating a Java EE 7 Websocket Chat Application

  • 17,878 views
Uploaded on

Slides from my tutorial on creating a websocket chat application using Java EE 7, GlassFish4, Maven, Bootstrap and jQuery.

Slides from my tutorial on creating a websocket chat application using Java EE 7, GlassFish4, Maven, Bootstrap and jQuery.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
17,878
On Slideshare
0
From Embeds
0
Number of Embeds
15

Actions

Shares
Downloads
82
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Java EE 7 Websocket Chat Creating a Chat Application using Java EE 7, Websockets and GlassFish 4 2014 Micha Kops / www.hascode.com
  • 2. Table of Contents ● What we're going to build (I) ● What we're going to build (II) ● Prerequisites ● Creating a new web app ● Adding the Maven Embedded GlassFish Plugin ● Websocket Endpoint ● Chat Message Data Transfer Object ● Converting Chat Messages ● Encoder Implementation ● The Client Side ● Client DOM Scripts (I) ● Client DOM Scripts (II) ● Client DOM Scripts (III) ● Client HTML (I) ● Client HTML (II) ● Build, deploy, run … ● Tutorial, Sources and Links 2014 Micha Kops / www.hascode.com
  • 3. What we're going to build (I) 2014 Micha Kops / www.hascode.com
  • 4. What we're going to build (II) ● ● ● ● A chat application client using Bootstrap and jQuery A user may register with a nickname for a chatroom from a list of given rooms Messages in a chat room are pushed to each subscribed client using web sockets A user may log out from the chat room 2014 Micha Kops / www.hascode.com
  • 5. Prerequisites ● Java 7 JDK ● Maven 3 ● An IDE of your choice ● A websockets-capable web browser 2014 Micha Kops / www.hascode.com
  • 6. Creating a new web app ● Using the javaee7-webapp Maven Archetype <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> </dependencies> 2014 Micha Kops / www.hascode.com
  • 7. Adding the Maven Embedded GlassFish Plugin <plugin> <groupId>org.glassfish.embedded</groupId> <artifactId>maven-embedded-glassfish-plugin</artifactId> <version>4.0</version> <configuration> <goalPrefix>embedded-glassfish</goalPrefix> <app>${basedir}/target/${project.artifactId}-${project.version}.war</app> <autoDelete>true</autoDelete> <port>8080</port> <name>${project.artifactId}</name> <contextRoot>hascode</contextRoot> </configuration> <executions> <execution> <goals> <goal>deploy</goal> </goals> </execution> </executions> </plugin> 2014 Micha Kops / www.hascode.com
  • 8. Websocket Endpoint @ServerEndpoint(value = "/chat/{room}", encoders = ChatMessageEncoder.class, decoders = ChatMessageDecoder.class) public class ChatEndpoint { private final Logger log = Logger.getLogger(getClass().getName()); @OnOpen public void open(final Session session, @PathParam("room") final String room) { log.info("session openend and bound to room: " + room); session.getUserProperties().put("room", room); } @OnMessage public void onMessage(final Session session, final ChatMessage chatMessage) { String room = (String) session.getUserProperties().get("room"); try { for (Session s : session.getOpenSessions()) { if (s.isOpen() && room.equals(s.getUserProperties().get("room"))) { s.getBasicRemote().sendObject(chatMessage); } } } catch (IOException | EncodeException e) { log.log(Level.WARNING, "onMessage failed", e); } } } 2014 Micha Kops / www.hascode.com
  • 9. Chat Message Data Transfer Object package com.hascode.tutorial; import java.util.Date; public class ChatMessage { private String message; private String sender; private Date received; // getter, setter, toString omitted.. } 2014 Micha Kops / www.hascode.com
  • 10. Converting Chat Messages public class ChatMessageDecoder implements Decoder.Text<ChatMessage> { @Override public void init(final EndpointConfig config) { } @Override public void destroy() { } @Override public ChatMessage decode(final String textMessage) throws DecodeException { ChatMessage chatMessage = new ChatMessage(); JsonObject obj = Json.createReader(new StringReader(textMessage)) .readObject(); chatMessage.setMessage(obj.getString("message")); chatMessage.setSender(obj.getString("sender")); chatMessage.setReceived(new Date()); return chatMessage; } @Override public boolean willDecode(final String s) { return true; } } 2014 Micha Kops / www.hascode.com
  • 11. Encoder Implementation public class ChatMessageEncoder implements Encoder.Text<ChatMessage> { @Override public void init(final EndpointConfig config) { } @Override public void destroy() { } @Override public String encode(final ChatMessage chatMessage) throws EncodeException { return Json.createObjectBuilder() .add("message", chatMessage.getMessage()) .add("sender", chatMessage.getSender()) .add("received", chatMessage.getReceived().toString()).build() .toString(); } } 2014 Micha Kops / www.hascode.com
  • 12. The Client Side ● ● ● ● ● ● ● We're using JavaScript to create the following stuff: A websocket URL follows this schema: ws://IP:PORT/CONTEXT_PATH/ENDPOINT_URL e.g ws://0.0.0.0:8080/hascode/chat/java A new websocket connection is created using the native WebSocket object e.g. var wsocket = new WebSocket(‘ws://0.0.0.0:8080/hascode/chat/java’); Registering a callback function to receive incoming messages from the server goes like this: wsocket.onmessage = yourCallbackFunction; Sending a message to the server is done by wsocket.send() .. pass a string, binary data .. whatever you like .. Closing a connection is simply done by wsocket.close() There is a lot of useful information that I did not add to this tutorial from keepalive-pings to the handshake protocol and other features .. one good starting point for detailed information about websockets might be IETF RFC 6455 2014 Micha Kops / www.hascode.com
  • 13. Client DOM Scripts (I) var wsocket; var serviceLocation = "ws://0.0.0.0:8080/hascode/chat/"; var $nickName; var $message; var $chatWindow; var room = ''; function onMessageReceived(evt) { //var msg = eval('(' + evt.data + ')'); var msg = JSON.parse(evt.data); // native API var $messageLine = $('<tr><td class="received">' + msg.received + '</td><td class="user label label-info">' + msg.sender + '</td><td class="message badge">' + msg.message + '</td></tr>'); $chatWindow.append($messageLine); } function sendMessage() { var msg = '{"message":"' + $message.val() + '", "sender":"' + $nickName.val() + '", "received":""}'; wsocket.send(msg); $message.val('').focus(); } 2014 Micha Kops / www.hascode.com
  • 14. Client DOM Scripts (II) function connectToChatserver() { room = $('#chatroom option:selected').val(); wsocket = new WebSocket(serviceLocation + room); wsocket.onmessage = onMessageReceived; } function leaveRoom() { wsocket.close(); $chatWindow.empty(); $('.chat-wrapper').hide(); $('.chat-signin').show(); $nickName.focus(); } 2014 Micha Kops / www.hascode.com
  • 15. Client DOM Scripts (III) $(document).ready(function() { $nickName = $('#nickname'); $message = $('#message'); $chatWindow = $('#response'); $('.chat-wrapper').hide(); $nickName.focus(); $('#enterRoom').click(function(evt) { evt.preventDefault(); connectToChatserver(); $('.chat-wrapper h2').text('Chat # '+$nickName.val() + "@" + room); $('.chat-signin').hide(); $('.chat-wrapper').show(); $message.focus(); }); $('#do-chat').submit(function(evt) { evt.preventDefault(); sendMessage() }); $('#leave-room').click(function(){ leaveRoom(); }); }); 2014 Micha Kops / www.hascode.com
  • 16. Client HTML (I) <div class="container chat-signin"> <form class="form-signin"> <h2 class="form-signin-heading">Chat sign in</h2> <label for="nickname">Nickname</label> <input type="text" class="input-block-level" placeholder="Nickname" id="nickname"> <div class="btn-group"> <label for="chatroom">Chatroom</label> <select size="1" id="chatroom"> <option>arduino</option> <option>java</option> <option>groovy</option> <option>scala</option> </select> </div> <button class="btn btn-large btn-primary" type="submit" id="enterRoom">Sign in</button> </form> </div> 2014 Micha Kops / www.hascode.com
  • 17. Client HTML (II) <div class="container chat-wrapper"> <form id="do-chat"> <h2 class="alert alert-success"></h2> <table id="response" class="table table-bordered"></table> <fieldset> <legend>Enter your message..</legend> <div class="controls"> <input type="text" class="input-block-level" placeholder="Your message..." id="message" style="height:60px"/> <input type="submit" class="btn btn-large btn-block btn-primary" value="Send message" /> <button class="btn btn-large btn-block" type="button" id="leave-room">Leave room</button> </div> </fieldset> </form> </div> 2014 Micha Kops / www.hascode.com
  • 18. Build, deploy, run … ● Simply run: mvn package embedded-glassfish:run 2014 Micha Kops / www.hascode.com
  • 19. Tutorial, Sources and Links ● Please feel free to take a look at the full tutorial on my blog: http://www.hascode.com/2013/08/ 2014 Micha Kops / www.hascode.com