开发环境:eclipse+JDK7.0+Tomcat8
语言:Java
服务器端:
package com.lts.chat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Vector; 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 com.opensymphony.xwork2.ActionSupport; import net.sf.json.JSONObject; /** @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端, * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端 */ @ServerEndpoint("/websocket") public class ChatServer { private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static Vector<Session> room = new Vector<Session>(); /** * * * @param session * */ @OnOpen public void onOpen(Session session) { room.addElement(session); System.out.println("客户端连接成功"); } /** * * * @param message * @param session */ @OnMessage public void onMessage(String message, Session session) { // 要发送的消息保存在JSON中 JSONObject obj = JSONObject.fromObject(message); // obj.put("date", df.format(new Date())); // for (Session se : room) { // obj.put("isSelf", se.equals(session)); /* getAsyncRemote()和getBasicRemote()都是WebSocket Session发送文本信息的 方法,它们是异步与同步的区别,由于getBasicRemote()是阻塞式的,因此大部分情况下, 推荐使用getAsyncRemote()*/ se.getAsyncRemote().sendText(obj.toString()); } System.out.println("信息发送成功"); } /** * * * @param session */ @OnClose public void onClose(Session session) { room.remove(session); System.out.println("关闭连接"); } /** * * * @param t */ @OnError public void onError(Throwable t) { System.out.println("连接失败"); } }
客户端:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta charset="UTF-8"> <title>寝室圈</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="format-detection" content="telephone=no"> <meta name="renderer" content="webkit"> <meta http-equiv="Cache-Control" content="no-siteapp"/> <link rel="alternate icon" type="image/png" href="assets/i/favicon.png"> <link rel="stylesheet" href="assets/css/amazeui.min.css"/> <script src="assets/js/jquery.min.js"></script> <script src="assets/js/amazeui.min.js"></script> <!-- UM相关资源 --> <link href="assets/umeditor/themes/default/css/umeditor.css" type="text/css" rel="stylesheet"> <script type="text/javascript" charset="utf-8" src="assets/umeditor/umeditor.config.js"></script> <script type="text/javascript" charset="utf-8" src="assets/umeditor/umeditor.min.js"></script> <script type="text/javascript" src="assets/umeditor/lang/zh-cn/zh-cn.js"></script> </head> <body> <header class="am-topbar am-topbar-fixed-top"> <div class="am-container"> <h1 class="am-topbar-brand"> <a href="#">寝室圈</a> </h1> <div class="am-collapse am-topbar-collapse" id="collapse-head"> <ul class="am-nav am-nav-pills am-topbar-nav"> <li class="am-active"><a href="#">聊天</a></li> <li><a href="FriendList.jsp">退出</a></li> </ul> <div class="am-topbar-right"> <button class="am-btn am-btn-secondary am-topbar-btn am-btn-sm"><span class="am-icon-pencil"></span> 动态</button> </div> <div class="am-topbar-right"> <button class="am-btn am-btn-primary am-topbar-btn am-btn-sm"><span class="am-icon-user"></span> 首页</button> </div> </div> </div> </header> <div id="main"> <!-- 聊天内容展示区域 --> <div id="ChatBox" class="am-g am-g-fixed" > <div class="am-u-lg-12" style="height:400px;border:1px solid #999;overflow-y:scroll;"> <ul id="chatContent" class="am-comments-list am-comments-list-flip"> <li id="msgtmp" class="am-comment" style="display:none;"> <a href=""> <img class="am-comment-avatar" src="assets/images/lts.jpg" alt=""/> </a> <div class="am-comment-main" > <header class="am-comment-hd"> <div class="am-comment-meta"> <a ff="nickname" href="#link-to-user" class="am-comment-author">帝国攻城狮</a> <time ff="msgdate" datetime="" title="">2017-5-22</time> </div> </header> <div ff="content" class="am-comment-bd">此处是消息内容</div> </div> </li> </ul> </div> </div> <!-- 聊天内容发送区域 --> <div id="EditBox" class="am-g am-g-fixed"> <!--style给定宽度可以影响编辑器的最终宽度--> <script type="text/plain" id="myEditor" style="100%;height:140px;"></script> <button id="send" type="button" style="60px;"class="am-btn am-btn-primary am-btn-block">发送</button> </div> </div> <script type="text/javascript"> $(function(){ //实例化编辑器 var um = UM.getEditor('myEditor',{ initialContent:" ", autoHeightEnabled:false, toolbar:[ 'source | undo redo | bold italic underline strikethrough | superscript subscript | forecolor backcolor | removeformat |', 'insertorderedlist insertunorderedlist | selectall cleardoc paragraph | fontfamily fontsize' , '| justifyleft justifycenter justifyright justifyjustify |', 'link unlink | emotion image video | map' ] }); var nickname = "道长"+Math.random(); var socket = new WebSocket("ws://${pageContext.request.getServerName()}:${pageContext.request.getServerPort()}${pageContext.request.contextPath}/websocket"); //接收服务器的消息 socket.onmessage=function(ev){ var obj = eval( '('+ev.data+')' ); addMessage(obj); } $("#send").click(function(){ if (!um.hasContents()) { // 判断消息输入框是否为空 // 消息输入框获取焦点 um.focus(); // 添加抖动效果 $('.edui-container').addClass('am-animation-shake'); setTimeout("$('.edui-container').removeClass('am-animation-shake')", 1000); } else { //获取输入框的内容 var txt = um.getContent(); //构建一个标准格式的JSON对象 var obj = JSON.stringify({ nickname:nickname, content:txt }); // 发送消息 socket.send(obj); // 清空消息输入框 um.setContent(''); // 消息输入框获取焦点 um.focus(); } }); }); //人名nickname,时间date,是否自己isSelf,内容content function addMessage(msg){ var box = $("#msgtmp").clone(); //复制一份模板,取名为box box.show(); //设置box状态为显示 box.appendTo("#chatContent"); //把box追加到聊天面板中 box.find('[ff="nickname"]').html(msg.nickname); //在box中设置昵称 box.find('[ff="msgdate"]').html(msg.date); //在box中设置时间 box.find('[ff="content"]').html(msg.content); //在box中设置内容 box.addClass(msg.isSelf? 'am-comment-flip':''); //右侧显示 box.addClass(msg.isSelf? 'am-comment-warning':'am-comment-success');//颜色 box.css((msg.isSelf? 'margin-left':'margin-right'),"20%");//外边距 $("#ChatBox div:eq(0)").scrollTop(999999); //滚动条移动至最底部 } </script> </body> </html>
聊天页面: