HTML5_WebSocket_JAVA8_Chat
源代码下载地址:https://git.oschina.net/zhuhongliang/HTML5_WebSocket_JAVA8_Chat
一共就两个文件,服务端1个文件,jsp客户端一个(不包括js,css什么的)
服务端代码:
import java.text.SimpleDateFormat; import java.util.Date; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; 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; /** * 聊天服务器类 * @author 朱宏亮 * *@ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。 *注解的值将被用于监听用户连接的终端访问URL地址。 * *onOpen 和 onClose 方法分别被 @OnOpen 和 @OnClose 所注解。 *这两个注解的作用不言自明:他们定义了当一个新用户连接和断开的时候所调用的方法。 * *onMessage 方法被 @OnMessage 所注解。 *这个注解定义了当服务器接收到客户端发送的消息时所调用的方法。 *注意:这个方法可能包含一个javax.websocket.Session可选参数(在我们的例子里就是session参数)。 *如果有这个参数,容器将会把当前发送消息客户端的连接Session注入进去。 * */ @ServerEndpoint("/websocket") public class ChatServer { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // 日期格式化 static Setusers = new CopyOnWriteArraySet ();//把所有的session存在这个static集合里面 @OnOpen public void open(Session session) { // 添加初始化操作 users.add(session); System.out.println("当前用户数量:"+users.size()); } /** * 接受客户端的消息,并把消息发送给所有连接的会话 * @param message 客户端发来的消息 * @param session 客户端的会话 */ @OnMessage public void getMessage(String message, Session session) { //打印message System.out.println("当前用户发送信息:"+message); System.out.println("当前用户sessionID:"+session.getId()); // 把客户端的消息解析为JSON对象 JSONObject jsonObject = JSONObject.fromObject(message); // 在消息中添加发送日期 jsonObject.put("date", DATE_FORMAT.format(new Date())); // 把消息发送给所有连接的会话 int i = 0 ; System.out.println("当前用户数量:"+users.size()); for (Session openSession : users) { // 添加本条消息是否为当前会话本身发的标志 jsonObject.put("isSelf", openSession.equals(session)); // 发送JSON格式的消息 openSession.getAsyncRemote().sendText(jsonObject.toString()); } } @OnClose public void close(Session session) { // 添加关闭会话时的操作 users.remove(session); System.out.println("用户已断开ID:"+session.getId()); } @OnError public void error(Throwable t, Session session) { // 添加处理错误的操作 try{ System.out.println("客户端断开连接"); //close(session); }catch(Exception a){ a.printStackTrace(); } } }
客户端jsp代码:
<%@ 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>在线聊天室 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">在线聊天室 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() { // 初始化消息输入框 var um = UM.getEditor('myEditor'); // 使昵称框获取焦点 $('#nickname')[0].focus(); // 新建WebSocket对象,最后的/WebSocket跟服务器端的@ServerEndpoint("/websocket")对应 var socket = new WebSocket('ws://${pageContext.request.getServerName()}:${pageContext.request.getServerPort()}${pageContext.request.contextPath}/websocket'); // 处理服务器端发送的数据 socket.onmessage = function(event) { addMessage(event.data); }; // 点击Send按钮时的操作 $('#send').on('click', function() { var nickname = $('#nickname').val(); if (!um.hasContents()) { // 判断消息输入框是否为空 // 消息输入框获取焦点 um.focus(); // 添加抖动效果 $('.edui-container').addClass('am-animation-shake'); setTimeout("$('.edui-container').removeClass('am-animation-shake')", 1000); } else if (nickname == '') { // 判断昵称框是否为空 //昵称框获取焦点 $('#nickname')[0].focus(); // 添加抖动效果 $('#message-input-nickname').addClass('am-animation-shake'); setTimeout("$('#message-input-nickname').removeClass('am-animation-shake')", 1000); } else { // 发送消息 socket.send(JSON.stringify({ content : um.getContent(), nickname : nickname })); // 清空消息输入框 um.setContent(''); // 消息输入框获取焦点 um.focus(); } }); // 把消息添加到聊天内容中 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'); // 把滚动条滚动到底部 $(".chat-content-container").scrollTop($(".chat-content-container")[0].scrollHeight); } }); </script> </body> </html>