最近同事在使用AMQ进行消息通信时遇到了问题:
在IE8中多个页面上访问AMQ的一个主题订阅的时候,多个页面中获得的消息其实是来自于同一个主题队列,导致页面状态逻辑错误.
查找AMQ的官方文档后得知,在5.4.2之后的版本中,AMQ的AJAX客户端可以通过指定唯一的clientId,让多个页面在一个浏览器中能够访问相同订阅的不同队列,避免了之前版本中只判断JSESSIONID导致的客户端无法区分的问题.官方文档在这里:
http://activemq.apache.org/ajax.html
但这里面实现的amq.js由于改动过大,无法与之前的接口兼容,所以并没有合并到官方主干源码中,只是以demo的形式额外存放.但实现上述功能的后端代码从5.4.2之后都被主干源码合并.
所以,单纯使用最新版的AMQ,是无法得到这个AJAX多客户端的功能的,需要自己额外进行调整.
今天上午解决了这个问题,稍稍修改了一下_amq.js文件,保证了与原接口的一致性,又增加了initClientId方法,可以方便的使用AMQ的AJAX多客户端功能了.
使用时,可以将这个_amq.js替换原activemq_web-x.x.x.jar中的文件,同时在调用页面中,进行最初uri赋值的时候,顺手调用一下amq.initClientId();就可以开启这个功能了.
刚刚进行代码测试,初步通过,功能的正确性得到了初步验证.
如果有同学遇到了相同的问题,希望能够帮忙进行测试调整.
文章系本人原创,转载请注明出处和作者
,本文原址在http://h-rain.iteye.com/blog/1387640
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// AMQ Ajax handler
// This class provides the main API for using the Ajax features of AMQ. It
// allows JMS messages to be sent and received from javascript when used
// with the org.apache.activemq.web.MessageListenerServlet
//
var amq =
{
// The URI of the MessageListenerServlet
uri: '/amq',
// Polling. Set to true (default) if waiting poll for messages is needed
poll: true,
// Poll delay. if set to positive integer, this is the time to wait in ms before
// sending the next poll after the last completes.
_pollDelay: 0,
_clientIdStr:'',
_first: true,
_pollEvent: function(first) {},
_handlers: new Array(),
_messages:0,
_messageQueue: '',
_queueMessages: 0,
//init the clientId,default auto make as Date string
initClientId:function(newId)
{
if (newId)
amq._clientIdStr="clientId="+newId;
else
amq._clientIdStr="clientId="+(new Date()).getTime().toString();
},
//using clientId,whit separtor
_makeClientIdStr:function(spChar)
{
var SC=spChar||'';
if (amq._clientIdStr=='')
return '';
return SC+amq._clientIdStr;
},
_messageHandler: function(request)
{
try
{
if (request.status == 200)
{
var response = request.responseXML.getElementsByTagName("ajax-response");
if (response != null && response.length == 1)
{
for ( var i = 0 ; i < response[0].childNodes.length ; i++ )
{
var responseElement = response[0].childNodes[i];
// only process nodes of type element.....
if ( responseElement.nodeType != 1 )
continue;
var id = responseElement.getAttribute('id');
var handler = amq._handlers[id];
if (handler!=null)
{
for (var j = 0; j < responseElement.childNodes.length; j++)
{
handler(responseElement.childNodes[j]);
}
}
}
}
}
}
catch(e)
{
alert(e);
}
},
startBatch: function()
{
amq._queueMessages++;
},
endBatch: function()
{
amq._queueMessages--;
if (amq._queueMessages==0 && amq._messages>0)
{
var body = amq._messageQueue;
amq._messageQueue='';
amq._messages=0;
amq._queueMessages++;
new Ajax.Request(amq.uri, { method: 'post', postBody: body+amq._makeClientIdStr('&'), onSuccess: amq.endBatch});
}
},
_pollHandler: function(request)
{
amq.startBatch();
try
{
amq._messageHandler(request);
amq._pollEvent(amq._first);
amq._first=false;
}
catch(e)
{
alert(e);
}
amq.endBatch();
if (amq._pollDelay>0)
setTimeout('amq._sendPoll()',amq._pollDelay);
else
amq._sendPoll();
},
_sendPoll: function(request)
{
new Ajax.Request(amq.uri, { method: 'get', parameters: amq._makeClientIdStr(),onSuccess: amq._pollHandler });
},
// Add a function that gets called on every poll response, after all received
// messages have been handled. The poll handler is past a boolean that indicates
// if this is the first poll for the page.
addPollHandler : function(func)
{
var old = amq._pollEvent;
amq._pollEvent = function(first)
{
old(first);
func(first);
}
},
// Send a JMS message to a destination (eg topic://MY.TOPIC). Message should be xml or encoded
// xml content.
sendMessage : function(destination,message)
{
amq._sendMessage(destination,message,'send');
},
// Listen on a channel or topic. handler must be a function taking a message arguement
addListener : function(id,destination,handler)
{
amq._handlers[id]=handler;
amq._sendMessage(destination,id,'listen');
},
// remove Listener from channel or topic.
removeListener : function(id,destination)
{
amq._handlers[id]=null;
amq._sendMessage(destination,id,'unlisten');
},
_sendMessage : function(destination,message,type)
{
if (amq._queueMessages>0)
{
if (amq._messages==0)
{
amq._messageQueue='destination='+destination+'&message='+message+'&type='+type;
}
else
{
amq._messageQueue+='&d'+amq._messages+'='+destination+'&m'+amq._messages+'='+message+'&t'+amq._messages+'='+type;
}
amq._messages++;
}
else
{
amq.startBatch();
new Ajax.Request(amq.uri, { method: 'post', postBody: 'destination='+destination+'&message='+message+'&type='+type+amq._makeClientIdStr('&'), onSuccess: amq.endBatch});
}
},
_startPolling : function()
{
if (amq.poll)
new Ajax.Request(amq.uri, { method: 'get', parameters: 'timeout=10'+amq._makeClientIdStr('&'), onSuccess: amq._pollHandler });
}
};
Behaviour.addLoadEvent(amq._startPolling);
function getKeyCode(ev)
{
var keyc;
if (window.event)
keyc=window.event.keyCode;
else
keyc=ev.keyCode;
return keyc;
}
分享到:
相关推荐
activemq linux下的多线程客户端,在windows下同样适用,包含生产消息客户端,和消费者消息客户端,以及生产者消息多线程客户端
此附件是Apache下面的一个ActiveMq客户端,如果需要在本地调试,不链接远程服务器的MQ可以下载研究。
基于SpringBoot开发的ActiveMQ虚拟主题客户端,达到消费者多点消费、负载均衡和故障转移的目的。 详情可以参考这里: https://my.oschina.net/noryar/blog/1573047 https://my.oschina.net/noryar/blog/1575003
activeMQ 服务端客户端 java代码 activeMQ 服务端客户端 java代码
使用C# winfrom做了一个ActiveMQ一个服务端对应一个客户端的即时收发消息的小程序,注释写得很详细,希望能帮到初学者。
使用c# winfrom 做了一个ActiveMQ一个服务端多个客户端的小程序,希望可以帮到初学者
activeMQ推送服务端和客户端完整案例
activemq服务器使用的zookeeper replicable 的方式进行负载均衡以及容灾,客户端使用spring进行配置
activemq 通过ajax发送接收消息简单例子
最新在做ActiveMQ Web端开发时,绕了很多路找到了这个插件,小编在这里就贡献了给爱学习小伙伴用。
activemq web通信简单demo,解决了中文乱码问题
ActiveMQ RabbitMQ AliyunMQ 示例程序
ActiveMQ使用Ajax实现多人聊天室。
用C实现的activemq的案例,整理了一下 , 希望对你有所帮助。这些数据阿帕奇官网也哟,具体的信息参考官网。http://activemq.apache.org/c-integration.html
ActiveMQ MQTT Android客户端Demo
ActiveMQ的amqjar包,ActiveMQamq.jar;ActiveMQamq.jar;
NULL 博文链接:https://hw1287789687.iteye.com/blog/2067736
中间件技术 实验三 消息中间件应用开发: - CSDN博客 https://blog.csdn.net/lly1122334/article/details/80139790