I. Project Introduction
WebSocket is a new protocol of HTML5. It realizes full-duplex communication between browser and server. Here we will use WebSocket to develop web chat room. The front-end framework will use AmazeUI, the background will use Java, and the editor will use UMEditor.
II. Knowledge Points
Web front-end (HTML+CSS+JS) and Java
1. New projects
Open Eclipse JavaEE, create a new Dynamic Web Project named Chat, and import the packages needed to process JSON format strings. Put commons-beanutils-1.8.0.jar, commons-collections-3.2.1.jar, commons-lang-2.5.jar, commons-logging-1.1.1.jar, morphez-1.0.6.jar and json-lib-2.4-jdk15.jar into these packages. In the WebContent/WEB-INF/lib directory, the project was finally published to the Tomcat server, and the empty project was completed.
2. Write front-end pages
A new page named index.jsp is created in the WebContent directory. The AmazeUI framework is used here. It is a cross-screen adaptive front-end framework. The message input box uses UMEditor. It is a rich text online editor, which can make our message content colorful.
First of all, from AmazeUI official website Download the compressed package, then unzip and copy the assets folder to the WebContent directory, so that we can use the AmazeUI.
From then on UEditer official website Download the Mini version of JSP version compression package, after decompression, copy the entire directory to the WebContent directory, then you can write the front-end code, the code is as follows (you can write according to your preferences):
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>ShiYanLou Chat</title>
<!-- Set render engine for 360 browser -->
<meta name="renderer" content="webkit">
<!-- No Baidu Siteapp-->
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="alternate icon" href="assets/i/favicon.ico">
<link rel="stylesheet" href="assets/css/amazeui.min.css">
<link rel="stylesheet" href="assets/css/app.css">
<!-- umeditor css -->
<link href="umeditor/themes/default/css/umeditor.css" rel="stylesheet">
<style>
.title {
text-align: center;
}
.chat-content-container {
height: 29rem;
overflow-y: scroll;
border: 1px solid silver;
}
</style>
</head>
<body>
<!-- title start -->
<div class="title">
<div class="am-g am-g-fixed">
<div class="am-u-sm-12">
<h1 class="am-text-primary">ShiYanLou Chat</h1>
</div>
</div>
</div>
<!-- title end -->
<!-- chat content start -->
<div class="chat-content">
<div class="am-g am-g-fixed chat-content-container">
<div class="am-u-sm-12">
<ul id="message-list" class="am-comments-list am-comments-list-flip"></ul>
</div>
</div>
</div>
<!-- chat content start -->
<!-- message input start -->
<div class="message-input am-margin-top">
<div class="am-g am-g-fixed">
<div class="am-u-sm-12">
<form class="am-form">
<div class="am-form-group">
<script type="text/plain" id="myEditor" style="width: 100%;height: 8rem;"></script>
</div>
</form>
</div>
</div>
<div class="am-g am-g-fixed am-margin-top">
<div class="am-u-sm-6">
<div id="message-input-nickname" class="am-input-group am-input-group-primary">
<span class="am-input-group-label"><i class="am-icon-user"></i></span>
<input id="nickname" type="text" class="am-form-field" placeholder="Please enter nickname"/>
</div>
</div>
<div class="am-u-sm-6">
<button id="send" type="button" class="am-btn am-btn-primary">
<i class="am-icon-send"></i> Send
</button>
</div>
</div>
</div>
<!-- message input end -->
<!--[if (gte IE 9)|!(IE)]><!-->
<script src="assets/js/jquery.min.js"></script>
<!--<![endif]-->
<!--[if lte IE 8 ]>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<![endif]-->
<!-- umeditor js -->
<script charset="utf-8" src="umeditor/umeditor.config.js"></script>
<script charset="utf-8" src="umeditor/umeditor.min.js"></script>
<script src="umeditor/lang/zh-cn/zh-cn.js"></script>
<script>
$(function() {
// Initialize message input box
var um = UM.getEditor('myEditor');
// Make the nickname box focus
$('#nickname')[0].focus();
});
</script>
</body>
</html>
Start the Tomcat server after writing, and then access it http://localhost:8080/Chat/index.jsp You will see the following interface.
3. Writing background code
Create a new package of com.shiyanlou.chat and create a class named ChatServer in the package. Since Java EE 7, the API of WebSocket has been unified. Therefore, no matter what server, the code written in Java is the same. The code is as follows:
package com.shiyanlou.chat;
import java.text.SimpleDateFormat;
import java.util.Date;
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;
import net.sf.json.JSONObject;
/**
* Chat Server Class
* @author shiyanlou
*
*/
@ServerEndpoint("/websocket")
public class ChatServer {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // DateFormatter
@OnOpen
public void open(Session session) {
// Adding Initialization Operations
}
/**
* Accept client messages and send them to all connected sessions
* @param message Message from Client
* @param session Client-side sessions
*/
@OnMessage
public void getMessage(String message, Session session) {
// Resolve client messages into JSON objects
JSONObject jsonObject = JSONObject.fromObject(message);
// Add a send date to the message
jsonObject.put("date", DATE_FORMAT.format(new Date()));
// Send messages to all connected sessions
for (Session openSession : session.getOpenSessions()) {
// Add a flag whether this message is issued by the current session itself
jsonObject.put("isSelf", openSession.equals(session));
// Send messages in JSON format
openSession.getAsyncRemote().sendText(jsonObject.toString());
}
}
@OnClose
public void close() {
// Adding actions when closing sessions
}
@OnError
public void error(Throwable t) {
// Adding operations to handle errors
}
}
4. Front-back interaction
When the background is finished, the front desk needs to connect the background with WebSocket. It needs to create a new WebSocket object. Then it can interact with the server and send messages from the browser to the server. At the same time, it needs to verify whether the contents of the input box are empty. Then it accepts the messages sent by the server and dynamically adds them to the chat. In the content box, in
var um = UM.getEditor('myEditor'); $('#nickname')[0].focus();
Then add the following code:
// Create a new WebSocket object, and the last / websocket corresponds to @ServerEndpoint("/websocket") on the server side.
var socket = new WebSocket('ws://${pageContext.request.getServerName()}:${pageContext.request.getServerPort()}${pageContext.request.contextPath}/websocket');
// Processing data sent by server
socket.onmessage = function(event) {
addMessage(event.data);
};
// Operation when clicking Send button
$('#send').on('click', function() {
var nickname = $('#nickname').val();
if (!um.hasContents()) { // Determine whether the message entry box is empty
// Message Input Box Gets Focus
um.focus();
// Adding jitter effect
$('.edui-container').addClass('am-animation-shake');
setTimeout("$('.edui-container').removeClass('am-animation-shake')", 1000);
} else if (nickname == '') { // Determine whether the nickname box is empty
//Nickname box to get focus
$('#nickname')[0].focus();
// Adding jitter effect
$('#message-input-nickname').addClass('am-animation-shake');
setTimeout("$('#message-input-nickname').removeClass('am-animation-shake')", 1000);
} else {
// send message
socket.send(JSON.stringify({
content : um.getContent(),
nickname : nickname
}));
// Clear the message input box
um.setContent('');
// Message Input Box Gets Focus
um.focus();
}
});
// Add messages to chat content
function addMessage(message) {
message = JSON.parse(message);
var messageItem = '<li class="am-comment '
+ (message.isSelf ? 'am-comment-flip' : 'am-comment')
+ '">'
+ '<a href="javascript:void(0)" ><img src="assets/images/'
+ (message.isSelf ? 'self.png' : 'others.jpg')
+ '" alt="" class="am-comment-avatar" width="48" height="48"/></a>'
+ '<div class="am-comment-main"><header class="am-comment-hd"><div class="am-comment-meta">'
+ '<a href="javascript:void(0)" class="am-comment-author">'
+ message.nickname + '</a> <time>' + message.date
+ '</time></div></header>'
+ '<div class="am-comment-bd">' + message.content
+ '</div></div></li>';
$(messageItem).appendTo('#message-list');
// Scroll the scroll bar to the bottom
$(".chat-content-container").scrollTop($(".chat-content-container")[0].scrollHeight);
}