<servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
2、客户端代码:
<script type="text/javascript">
var sendId ="";
var isReceiver = false;
function longPolling() {
if(isReceiver) {
$.ajax({
url : "../longPolling/customer/receive",
data : {"receiverId" : "123", "time" : new Date()},
dataType : "json",
type : "POST",
success : function(data) {
console.log(data);
if(data.code == "success"){
var $tbody = "";
$.each(data.data, function(index, value) {
var $tr = "";
$tr += "<tr><td>"+value.receiverId+"</td><td>"+value.sendId+"</td><td>"+value.context+"</td><td>"+value.date+"</td></tr>"
$tbody += $tr;
});
$("#message").append($tbody);
}
longPolling();
},
error : function(XMLHttpRequest) {
console.log(XMLHttpRequest.status);
if (XMLHttpRequest.status == "500") { //超时
longPolling();
} else {
isReceiver = false;
}
}
});
}
}
$(function(){
$('#startReceive').click(function() {
isReceiver = true;
longPolling();
});
$("#startSend").click(function() {
//alert("123");
$.ajax({
url : "../common/createId",
type : "post",
dataType : "json",
data : {"time" : new Date()},
success : function(msg) {
console.log(msg);
sendId = msg.data;
},
error : function() {
}
});
});
$("#send").click(function() {
if(sendId != "") {
var context = $("#sendMessage").val();
//alert(text);
$.ajax({
url : "../longPolling/customer/send",
type : "post",
dataType : "json",
data : {
"receiverId" : "123", "sendId" : sendId, "context" : context, "time" : new Date()
},
success : function(msg) {
console.log(msg);
$("#sendMessage").val("");
},
error : function() {}
});
} else {
alert("请先点击开始!");
}
});
window.onbeforeunload = function() {
isReceiver = false;
$.ajax({
url : "../longPolling/customer/clear",
type : "post",
dataType : "json",
data : {
"receiverId" : "123", "time" : new Date()
},
success : function(msg) {
console.log(msg);
},
error : function() {}
});
}
})
</script>
</head>
<body>
<button id="startSend">开始</button><br><br>
<input type="text" id="sendMessage"/><button id = "send">发送</button>
<br>
<button id = "startReceive">startReceive</button>
<table id ="message"></table>
</body>
3、控制层代码:
就这样完了。。。
推送消息接口:
public DeferredResult<ResultDTO> receiverMessage(final String receiverId) {
DeferredResult<ResultDTO> result = new DeferredResult<ResultDTO>(90000L);
/**
* http连接先查询仓库中是否有消息
*/
Integer messageSize = longCustomerService.countReceiverMessageNum(receiverId);
SysoutLogUtil.log(messageSize);
if(messageSize > 0){
result.setResult(new ResultDTO("success", "", longCustomerService.listMessage(receiverId)));
}
longCustomerService.saveReceiverRequest(receiverId, result);
result.onCompletion(new Runnable() {
@Override
public void run() {
longCustomerService.removeReceiverRequest(receiverId);
}
});
SysoutLogUtil.log("获取到"+messageSize+"条消息");
return result;
}
发送消息接口:
public Object sendMessage(String receiverId, String sendId, String context) {
MessageDO message = new MessageDO(receiverId, sendId, context);
longCustomerService.saveMessage(message);
return new ResultDTO("success");
}
浏览器刷新接口:
public Object clearRequest(String receiverId){
SysoutLogUtil.log("调用了刷新接口"+receiverId +"end");
longCustomerService.removeReceiverRequest(receiverId);
return new ResultDTO("success");
}
4、Service层代码:
private static Map<String, DeferredResult<ResultDTO>> receiverRequest = new ConcurrentHashMap<String, DeferredResult<ResultDTO>>();
private static ConcurrentHashMap<String, ConcurrentLinkedQueue<MessageDO>> repository = new ConcurrentHashMap<>();
@Override
public void saveMessage(MessageDO message) {
String receiverId = message.getReceiverId();
/**
* 检测是否有http连接
*/
DeferredResult<ResultDTO> result = receiverRequest.get(receiverId);
if(result != null){
SysoutLogUtil.log("有http连接,直接输出消息!");
List<MessageDO> receiverMessage = new ArrayList<>();
receiverMessage.add(message);
result.setResult(new ResultDTO("success", "", receiverMessage));
return;
}
/**
* 没有http连接入库
*/
ConcurrentLinkedQueue<MessageDO> messageQueue = repository.get(receiverId);
if(messageQueue == null){
messageQueue = new ConcurrentLinkedQueue<>();
messageQueue.add(message);
} else {
messageQueue.add(message);
}
SysoutLogUtil.log(messageQueue.size());
repository.put(receiverId, messageQueue);
}
@Override
public List<MessageDO> listMessage(String receiverId) {
List<MessageDO> receiverMessage = new ArrayList<>();
ConcurrentLinkedQueue<MessageDO> messageQueue = repository.get(receiverId);
if(messageQueue == null){
return null;
} else {
while (messageQueue.peek() != null) {
receiverMessage.add(messageQueue.poll());
}
}
return receiverMessage;
}
@Override
public Integer countReceiverMessageNum(String receiverId) {
ConcurrentLinkedQueue<MessageDO> messageQueue = repository.get(receiverId);
if(messageQueue == null){
return 0;
} else {
return messageQueue.size();
}
}
@Override
public void saveReceiverRequest(String receiverId, DeferredResult<ResultDTO> Object) {
receiverRequest.put(receiverId, Object);
}
@Override
public void removeReceiverRequest(String receiverId) {
SysoutLogUtil.log("删除"+receiverId+"的连接");
receiverRequest.remove(receiverId);
}
就这样完了。。。