active消息通知设计思路及示例:
服务端发送消息,
客户端接收消息,保存进入数据库
页面定时刷新查出当前用户的消息
在需要发送的地方调用消息的发送方法,通过消息的方式通知客户端(queue的模式),客户端监听到消息,消费掉queue,并插入数据库,
页面轮询(公共页面),在做接口的时候考虑需求的参数传入设计,有点击读取的时候改变状态
现有的是查出对话者所有的对话记录,没有点击之后改变数据库状态
需要发消息通知的地方用发送界面模拟(调用发送接口),接收闪烁的地方用接收框模拟(页面定时刷新),中间的监听(队列)插入(自动监听),
页面的定时轮询,一样,就是点击之后的(图标不再闪烁(即前消息队列为空的时候不显示))显示的还是所有的消息列表
闪烁的问题
1用消息的状态(不行,效果是点击图标即不闪烁)new状态闪烁(同样页面定时看有无new状态的消息)
刚插入都是new的状态,只要点击了图标,new状态变为old,即用一个字段标记图标闪烁状态
至于消息的读阅状态用另一个字段标记
发送:调用发送接口
接收:中间的监听(队列)插入(自动监听) -----》addTipReg(现有系统)用存储过程
提醒:刚插入都是new的状态,只要点击了图标,new状态变为old,即用一个字段标记图标闪烁状态(页面定时看有无new状态的消息)-----》updateTipStatus(现有系统)
LOOK_TIMES这个是标记字段
展现:显示的还是所有的消息列表----(至于有无连接看需要,可以传多的信息出去)-----》getTipData(现有系统)(后台查出所有通过登录人员拥有的menuId确定,
前台通过cuntomKey过滤)sql是另一套,参考前台jar包
由此可见消息的通知只是在原来的基础上加上了mq防止高并发的阻塞,丢失请求
在addTipReg之前即要插入之前,发出消息到mq,再由监听器去一个一个addaddTipReg(先缓存起来,再插,不是直接插入),
其他要应用到mq的地方也是如此,做之前先缓存起来然后该如何做就在监听器中照样做
消息编码:
提交时先把提价过来的对象json话,然后组一些标记信息成为更大的json串。发送---》放入队列缓冲
发送:
@RequestMapping(value = "/message/offer/submit", method = RequestMethod.POST)
public void TbConOrdPriceSubmit(HttpSession session, HttpServletRequest request, HttpServletResponse response, Model model, TbConOrdVo tbConOrdVo)
throws EsteelException, IOException {
String currentUserKey = getCurrentUserKey(request, session);
if (!currentUserKey.equals(tbConOrdVo.getCustomerKey())) {
/* 仅作测试用,上线需要删除此行★★★ */
currentUserKey = tbConOrdVo.getCustomerKey();
}
if (!currentUserKey.equals(tbConOrdVo.getTradeCustomerKey()) && !currentUserKey.equals(tbConOrdVo.getTbConobjCustomerKey())) {
response.getWriter().write("Access denied!");
} else {
if (currentUserKey.equals(tbConOrdVo.getTbConobjCustomerKey())) {
tbConOrdVo.setOrdpriceMan("B");
} else {
tbConOrdVo.setOrdpriceMan("A");
}
/* 先转换成json, */
JSONObject object = JSONObject.fromObject(tbConOrdVo);//将对象转化为json
String tempstr = object.toString();
/* 加入name信息,和ipAddress信息 */
tempstr = "{\"objectName\":\"Message\",\"ipAddress\":" + EsteelNetworkUtil.getIpAddress(request) + ",\"object\":" + tempstr + "}";
/* 然后写入activemq */
topicSender.sendMessage(tempstr);
System.out.println("==============Write to MQ success============");
response.getWriter().write("Success submit!");
}
}
接收:
根据发送过来的含有附加信息的json过滤出自己要的那种消息的json串,将之前的对象转化的json,转回对象,然后普通系统改如何操作就如何操作---》从队列中取,
然后该如何就如何---一般是完成入库
public void onMessage(Message m) {
ObjectMessage om = (ObjectMessage) m;
try {
String key_esteelMessage = om.getStringProperty("key_esteelMessage");
JSONObject object1 = JSONObject.fromObject(key_esteelMessage);
String objectName = (String)object1.get("objectName");
if(objectName.equals("Message")){//过滤出自己需要的json串
JSONObject object2 = (JSONObject) object1.get("object");
TbConOrdVo tbConOrdVo=(TbConOrdVo)JSONObject.toBean(object2, TbConOrdVo.class);
TbConOrd tbConOrd = new TbConOrd();
/*获取ipAddress*/
String ipAddress = (String)object1.get("ipAddress");
/* 从tbConOrdVo中提取tbConOrd */
tbConOrd = copyTbConOrd(tbConOrdVo, tbConOrd, ipAddress);
/* 写入tbConOrd */
tbConOrd = tbConOrdService.insertTbConOrd(tbConOrd);
TbConOrdPrice tbConOrdPrice = new TbConOrdPrice();
tbConOrdPrice = copyTbConOrdPrice(tbConOrd, tbConOrdVo, tbConOrdPrice);
/* 写入聊天文字到 tbConOrdPrice*/
String msgText = tbConOrdPrice.getMsgText();
if (msgText.equals("请录入您的议价留言,最大为300个字符!按Ctrl+Enter提交!")) {
tbConOrdPrice.setMsgText("");
}
//tbConOrd = tbConOrdService.getTbConOrdByObj(tbConOrd);
//tbConOrdPrice.setOrdKey(tbConOrd.getOrdKey());
tbConOrdPrice=tbConOrdPriceService.insertTbConOrdPrice(tbConOrdPrice);
/* 还得写入tbConObj的数据 */
TbConObj tbConObj=tbConObjService.getTbConObjById(tbConOrd.getConobjKey());
if(tbConObj.getContradeType().equals("A")){
/*销售单*/
/*设置最低价位*/
if(tbConObj.getHighPrice()==null){
tbConObj.setHighPrice(tbConObj.getOrderPrice());
}
if(tbConOrdPrice.getOrdpriceMan()==null){
/*当前对象是客人*/
tbConObj.setLowPrice(tbConOrd.getOrderPrice());
}else if(tbConOrdPrice.getOrdpriceMan().equals("A")){
/*当前对象是客人*/
tbConObj.setLowPrice(tbConOrd.getOrderPrice());
}else{
/*当前对象是主人*/
tbConObj.setHighPrice(tbConOrd.getOrderPrice());
}
}else{
/*采购单*/
/*设置最低价位*/
if(tbConObj.getLowPrice()==null){
tbConObj.setLowPrice(tbConObj.getOrderPrice());
}
if(tbConOrdPrice.getOrdpriceMan()==null){
/*当前对象是客人*/
tbConObj.setHighPrice(tbConOrd.getOrderPrice());
}else if(tbConOrdPrice.getOrdpriceMan().equals("A")){
/*当前对象是客人*/
tbConObj.setHighPrice(tbConOrd.getOrderPrice());
}else{
/*当前对象是主人*/
tbConObj.setLowPrice(tbConOrd.getOrderPrice());
}
}
tbConObj = tbConObjService.updateTbConObj(tbConObj);
tbConObjService.listClearCache(tbConObj.getConobjKey());
tbConOrdService.listClearCache();
tbConOrdService.listClearCache(tbConObj.getConobjKey(),tbConOrdVo.getTradeCustomerKey());
}
System.out.println("==============MQ Write to Database success============");
} catch (JMSException e) {
e.printStackTrace();
} catch (EsteelException e) {
e.printStackTrace();
}
}
页面定时从数据库轮询数据:
<title>洽谈</title>
<div class="chart1" id="pop_up" style="height: 600px; overflow: auto; cursor: move;">
<div class="biaodan">
<form id="submitForm" name="submitForm" action="" method="post"
οnkeydοwn= "javascript:if(event.ctrlKey && event.keyCode==13){checkCanBuy();}">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td>
<td rowspan="3"><br /> <br /> <input type="button"
name="button" id="button_messageRecord" value="消息" class="btnhr30">
</td>
</tr>
</tbody>
</table>
</form>
<!-- <input type="button" οnclick="getmessageRecord();" value="ok"> -->
<div class="con pr" id="messageRecord">
</div>
<div id="messageRecordJsonHidden" style="display:none">
</div>
</div>
</div>
js定时的几种方式
1,function show_tip(){
getTipData();
setTimeout("show_tip()",3000);
}
2,直接用jquery插件:
jsp中的上下文等要用到jsp专属的内置对象的比如(${pageContext.request.contextPath}),
只能在jsp中识别得到,但是类似插件的js文件需要用这种的话可以把以上要用的作为变量声明在jsp页面的全局js中,
这个js中再加载js插件,是js插件的代码就相当在jsp中写的,当然可以直接用这个全局变量(变量在哪些脚本前面,这些脚本可直接用)
如
jsp中:
weburl变量jquery.message.offer.js中可以直接用
<script>
var webUrl = "${pageContext.request.contextPath}";
$.getScript("${pageContext.request.contextPath}/resources/js/message/jquery.timer.js",定时到这里即可
function() {
$.getScript("${pageContext.request.contextPath}/resources/js/message/jquery.message.offer.js",//自定义插件函数
function() {$.getScript("${pageContext.request.contextPath}/resources/js/message/jquery.form.js",//表单插件
function() {
$(".btnhr30").on('click',
function() {
checkCanBuy();
});
/* 每3秒取一次数据 */
timermessageRecord = $.timer(3000,
function() {
var count=infoCount(0);
//alert(count);
if(count>0){
$("#button_messageRecord").val("消息("+count+")");
$("#button_messageRecord").fadeOut(100).fadeIn(100);闪烁效果
}
});
$(".class_customerNameSet").on('click',
function(){
switchCustomer(this);
}
);
//$(".class_customerNameSet").eq(0).click();
//checkmessageRecord(1);
});
});
});
</script>
jquery.timer.js:
/**
* jQuery Timer Plugin (jquery.timer.js)
* @version 1.0.1
* @author James Brooks <jbrooksuk@me.com>
* @website http://james.brooks.so
* @license MIT - http://jbrooksuk.mit-license.org
*/
(function($) {
jQuery.timer = function(interval, callback, options) {
// Create options for the default reset value
var options = jQuery.extend({ reset: 500 }, options);
var interval = interval || options.reset;
if(!callback) { return false; }
var Timer = function(interval, callback, disabled) {
// Only used by internal code to call the callback
this.internalCallback = function() { callback(self); };
// Clears any timers
this.stop = function() {
if(this.state === 1 && this.id) {
clearInterval(self.id);
this.state = 0;
return true;
}
return false;
};
// Resets timers to a new time
this.reset = function(time) {
if(self.id) { clearInterval(self.id); }
var time = time || options.reset;
this.id = setInterval($.proxy(this.internalCallback, this), time);
this.state = 1;
return true;
};
// Pause a timer.
this.pause = function() {
if(self.id && this.state === 1) {
clearInterval(this.id);
this.state = 2;
return true;
}
return false;
};
// Resumes a paused timer.
this.resume = function() {
if(this.state === 2) {
this.state = 1;
this.id = setInterval($.proxy(this.internalCallback, this), this.interval);
return true;
}
return false;
};
// Set the interval time again
this.interval = interval;
// Set the timer, if enabled
if (!disabled) {
this.id = setInterval($.proxy(this.internalCallback, this), this.interval);
this.state = 1;
}
var self = this;
};
// Create a new timer object
return new Timer(interval, callback, options.disabled);
};
})(jQuery);