发布时间:2022-09-02 15:00
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代码:
在线聊天室 Chat.title {
text-align: center;
}
.chat-content-container {
height: 29rem;
overflow-y: scroll;
border: 1px solid silver;
}
$(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 = '
'+ ''
+ '
$(messageItem).appendTo('#message-list');
// 把滚动条滚动到底部
$(".chat-content-container").scrollTop($(".chat-content-container")[0].scrollHeight);
}
});
+ ''
+ message.nickname + ' ' + message.date
+ '
+ '
+ '