基本思路:(非JMS实现)
栈内聊天分为广播消息(群聊)和队列消息(私聊)。
用户发消息,将之消息存放到application中,同时用户界面有不停地从tomcat中接受消息(定时器)。
广播消息:大家取得的消息主要是根据引入版本号version的控制,在application中有一个版本号,然后每个用户也都有个各自的版本号,比较每个用户的版本号和application中的版本号,当用户的version低于application中的version时,接受消息。
队列消息:用户发送指定消息,将之放到application的map中,接受的用户根据各自的key值就收消息。
jsp页面:
<h1>简易聊天室</h1>
<div style="width: 300px; height: auto;" id="chatContent"></div>
<br/><br>
发送者:
<input type="text" name="sendMsgUser" id="sendMsgUser">
发送类型:
<select id="sendType">
<option value="0">
指定发送
</option>
<option value="1">
广播发送
</option>
</select>
接受者:<input type="text" name="receiveMsgUser" id="receiveMsgUser">
<br/><br/>
发送内容:<br/>
<textarea rows="3" cols="100" id="sendContent">
发送的内容
</textarea>
<input id="sendBnt" type="button" value="发送"/>
js代码:
<script type="text/javascript">
var chatMsg = {
sendMsg:function(){
var parameter = {
//发送者
"sendMsgUser":$("#sendMsgUser").val(),
//发送类型
"sendType":$("#sendType").val(),
//接受者
"receiveMsgUser":$("#receiveMsgUser").val(),
//发送内容
"sendContent":$("#sendContent").val()
};
$.get("<%=basePath %>jsp/chatMsg!sendMsg.action",parameter,
function(data){
$("#sendContent").val = "";
$("#sendContent").html("");
$("#chatContent").append("我:" + data.sendContent + "<br>");
});
},
receiveMsg:function(){
var parameter = {
"sendMsgUser":$("#sendMsgUser").val()
};
$.get("<%=basePath %>jsp/chatMsg!receiveMsg.action", parameter,
function(data){
var list = data.mylist;
for ( var i = 0; i < list.length; i++) {
$("#chatContent").append(list[i].sendMsgUser + ":" + list[i].sendContent + "<br>");
}
});
}
};
$(function(){
$("#sendBnt").click(function(){
chatMsg.sendMsg();
});
window.setInterval(function(){
chatMsg.receiveMsg();
}, 1000);
});
</script>
action里面页面:
public String sendMsg(){
ChatMessage chatMessage = new ChatMessage();
if("0".equals(sendType)){
chatMessage = ChatMessageFactory.getQequenceMsg();
}else{
chatMessage = ChatMessageFactory.getBroadcastMsg();
}
chatMessage.setSendMsgUser(sendMsgUser);
chatMessage.setSendContent(sendContent);
chatMessage.setReceiveMsgUser(receiveMsgUser);
MessageService messageService = new MessageServiceImpl();
messageService.send(chatMessage);
return "success";
}
public String receiveMsg(){
MessageService messageService = new MessageServiceImpl();
mylist = messageService.recevice(sendMsgUser);
for (ChatMessage msg : mylist) {
System.out.println("content:"+msg.getSendContent()+"----"+msg.getReceiveMsgUser());
System.out.println("接受消息");
}
return "success";
service代码:
//广播消息
private static ArrayList<ChatMessage> broadcastMessageList = new ArrayList<ChatMessage>();
//版本号
private static int version = 1;
//队列消息
private static Map<String, ArrayList<ChatMessage>> qequenceMessageList = new HashMap<String, ArrayList<ChatMessage>>();
//用户版本号
private static Map<String, Integer> userVersion = new HashMap<String, Integer>();
public void send(ChatMessage chatMessage) {
if("Broadcast".equals(chatMessage.getSendType())){
//广播消息
chatMessage.setVersion(version++);
broadcastMessageList.add(chatMessage);
}
if("Qequence".equals(chatMessage.getSendType())){
//队列消息
if(isReceiveMsgUserEmpty(chatMessage)){
throw new RuntimeException("队列消息缺少接受者");
}
ArrayList<ChatMessage> list = qequenceMessageList.get(chatMessage.getReceiveMsgUser());
if(list == null){
list = new ArrayList<ChatMessage>();
qequenceMessageList.put(chatMessage.getReceiveMsgUser(), list);
}
list.add(chatMessage);
}
}
public ArrayList<ChatMessage> recevice(String user) {
ArrayList<ChatMessage> mylist = new ArrayList<ChatMessage>();
// 查看是否有可接受的广播消息
for (ChatMessage chatMessage : broadcastMessageList) {
if(isMatchVersion(chatMessage, user)){
continue;
}
mylist.add(chatMessage);
incrementUserVersion(user);
}
//查看是否有可接受的队列消息
ArrayList<ChatMessage> qeuenceMsgList = qequenceMessageList.get(user);
if (isNotEmpty(qeuenceMsgList)) {
mylist.addAll(qeuenceMsgList);
qequenceMessageList.get(user).removeAll(qeuenceMsgList);
}
return mylist;
}
private void incrementUserVersion(String userId) {
Integer currentVersion = userVersion.get(userId);
if (currentVersion == null) {
currentVersion = 1;
userVersion.put(userId, currentVersion);
} else {
//所有Map操作中key的值是不能重复的,例如,HashMap操作时key是不能重复的,如果重复则肯定会覆盖之前的内容
userVersion.put(userId, ++currentVersion);
}
}
private boolean isMatchVersion(ChatMessage chatMessage, String user){
Integer currentVersion = userVersion.get(user);
if (currentVersion == null) {
currentVersion = 1;
userVersion.put(user, currentVersion);
}
return chatMessage.getVersion() < currentVersion;
}