Javascript代码
$ (功能() ) )。
getMsg (;
);
函数getmsg (
{
$.Ajax({
URL : ' /轮询/msg ',
类型: ' get ',
data:{},
是success :功能(数据)
{
IF (数据!=空数据!=' ' )
警报显示(data.msg );
getMsg (;
}
);
}
Java代码
//*
*
*@author{chensg}:2016年6月1日
*example
*
*/
@Controller
@ request mapping (/轮询/) )。
publicclassPollingController{
@Autowired
消息容器存储器; 全局存储为每个用户创建的延迟结果实例,key:userId,value:DeferredResult
@Autowired
RabbitTemplaterabbitTemplate;
//*
*长轮询
*@return
*/
@requestmapping(value='msg ',method=RequestMethod.GET ) )。
公共@ responsebodydeferredresultgetmessage (
finalstringuserid=(用户详细信息) securitycontextholder.get context (
. getAuthentication ()
. getPrincipal ().getUsername );
deferredresultresult=newdeferredresult (30000 l,null ); //超时设置为30s,超时并返回null
finalmapresultmap=message container.getuser messages (;
resultmap.put(userid,result );
result.on completion (新运行) )。
{
@Override
公共void run (}
resultmap.remove(userid;
}
);
返回结果;
}
//*
*test添加了必须推送给特定用户的消息
*@return
*/
@requestmapping(value='msg ',method=RequestMethod.POST ) )。
公共@ responsebodyrestresultaddmessage (string msg,StringuserId ) {
usermessageusermsg=new用户消息(;
usermsg.setuserid(userid;
usermsg.setmsg(msg;
//系统或其他用户需要推送的消息将放入消息队列
rabbit template.convertandsend (' test.exchange ',' test.binding ',userMsg );
返回空值;
}
}
页面加载完成后,该用户将请求/轮询/msg控制器接口,在接口上创建DeferredResult实例,设置超时30S,超时返回null 使用DeferredResult,APP应用程序可以从一个线程返回。 返回的时间由线程决定。
消息实体类
Java代码
publicclassusermessageimplementsserializable {
//*
*
*/
私有状态长时间服务版本=1l;
隐私用户id;
隐私保护msg;
publicStringgetUserId
返回用户id;
}
公共语音设置用户id (字符串用户id )。
this.userId=userId;
}
公共字符串getmsg (
returnmsg;
}
publicvoidsetmsg (字符串msg ) {
this.msg=msg;
}
}
rabbitMQ配置
Xml代码
xmlns 3360 xsi=' http://www.w3.org/2001/XML架构-instance '
xmlns 3360 rabbit=' http://www.spring framework.org/schema/rabbit '
xsi :方案定位=' http://www.spring framework.org/schema/beans 3358 www.spring framework.org/schema/beans
3358 www.spring framework.org/schema/rabbit 3358 www.spring framework.org/schema/rabbit/spring-rabbit-1.5 .
host=' $ { rabbit MQ.host } ' port=' $ { rabbit MQ.port } ' username=' $ { rabbit MQ.username } ' password=' $ { rabit }
虚拟主机='/' /
retry-template=' retry template ' /
class=' com.XXX.controller.test.servicepollinghandler ' /
method='testPollingHandle '
队列=' test queue ' /
Java代码
publicclasservicepollinghandler {
@Autowired
消息容器存储器;
publicvoidtestpollinghandle (用户消息用户消息) )。
{
mapmsgcontainer=message container.getuser messages (;
eferredresultdeferredresult=msg container.get (用户消息. get userid () );
延迟结果!=空) {
eferredresult.set result (用户消息; 调用setResult (,线程返回消息。
}
}
}
Java代码
@ property source (value=' class path : application.properties ' ) ) ) ) )。
@导入资源((class path : amqp.XML ) )
publicclassRootConfig{
@Bean
publicmessagecontainermessagecontainer (
returnnewMessageContainer (;
}
}
Java代码
publicclassMessageContainer{
privateconcurrenthashmapusermessages=newconcurrenthashmap (; //线程安全
publicconcurrenthashmapgetusermessages (
returnuserMessages;
}
}
此示例的用途是,当一个用户登录页面时,异步请求后台/轮询/msg,在后台创建线程,维护30s的延长连接,并返回超时或消息,页面将再次返回
系统或其他用户调用/polling/msg method:post,传递msg和userId,控制器将消息置于消息队列中,消息队列将消息置于servicepollinghhod
基于以上代码,能够实现网络聊天
(自转) 3358 chens hangge.iteye.com/blog/2302710