flex+spring+blazds 数据推送,client自动断开问题。
上次,整理了下,flex+spring+blazds 数据推送配置,今天使用的时候,发现了一个问题。打开客户端后,后台一直在推送数据,client也一直在接收数据,
过了一会儿,发现client无法时时更新,debug查了下,不接收数据。但是服务端一直在发送,这个问题郁闷了很久。
问题也不好重现,于是通过日志打印一直等待问题的重现,发现一个规律。client打开后,如果超过半个小时,消息订阅就会自动断开,
不知道是不是需要在客户端设置什么参数,但本人找不到答案。
于是尝试在client使用心跳功能,每隔一段时间,去检测消息有木有断开,如果断开了,就自动重新连上。
附上代码。主要是红色代码。
<?xml version="1.0" encoding="utf-8"?> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" implements="demo.ISerializable" xmlns:twaver="http://www.servasoftware.com/2009/twaver/flex" width="100%" height="100%" creationComplete="init()"> <fx:Declarations> <s:ChannelSet id="cs"> <s:StreamingAMFChannel id="samf"/> </s:ChannelSet> <s:Consumer id="consumer" destination="simple-feed" channelSet="{cs}" message="consumer_messageHandler(event)" fault="consumer_faultHandler(event)" channelFault="consumer_channelFaultHandler(event)"/> <mx:DateFormatter id="df" formatString="YYYY-MM-DD JJ:NN:SS"/> </fx:Declarations> <fx:Script> <![CDATA[ import com.xinyitech.bp.flex.common.NetWorkUtils; import com.xinyitech.bp.flex.constant.CustomEvent; import demo.*; import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.controls.CheckBox; import mx.controls.Menu; import mx.controls.PopUpMenuButton; import mx.controls.Spacer; import mx.messaging.events.ChannelFaultEvent; import mx.messaging.events.MessageEvent; import mx.messaging.events.MessageFaultEvent; import twaver.*; import twaver.network.interaction.InteractionEvent; import twaver.network.layout.AutoLayouter; private var box:ElementBox = new ElementBox(); private var autoLayouter:AutoLayouter = null; private var accountAttachments:CheckBox = new CheckBox(); private var enableAnimation:CheckBox = new CheckBox(); private var zoomToOverview:CheckBox = new CheckBox(); private var selectModel:SelectionModel; private var elementArray:ArrayCollection; private var popupMenuButton:PopUpMenuButton = new PopUpMenuButton(); private var rootNode:Node = new Node(); private var timer:Timer; [Embed(source='images/server_32.png')] public var routerImage:Class; public function get dataBox():DataBox{ return box; } private function init():void{ trace(df.format(new Date())+" test"); samf.url = CustomEvent.URL_ADDRESS+"/messagebroker/streamingamf"; consumer.subscribe(); Utils.registerImageByClass("routerImage",routerImage); network.elementBox = box; selectModel = box.selectionModel; timer = new Timer(1000); //新增心跳功能防止client消息订阅被自动断开 timer.addEventListener(TimerEvent.TIMER,function():void{ if(!consumer.subscribed){ trace(df.format(new Date())+" 消息订阅已被断开,重新开始注册"); //consumer.unsubscribe(); consumer.subscribe(); } }); timer.start(); table.dataBox = box; //table只显示node信息 table.visibleFunction = function(e:Element):Boolean{ return e is Node && e.name!="master"; } network.selectionModel.filterFunction = function(data:IData):Boolean{ return data.name!=null; }; DemoUtils.initNetworkToolbar(toolbar, network); network.selectionModel.selection; NetWorkUtils.initNetworkContextMenu(network); this.autoLayouter = new AutoLayouter(network); this.initBox(); this.autoLayouter.animate = false; this.autoLayouter.doLayout(Consts.LAYOUT_ROUND); this.autoLayouter.animate = true; var count:int; //添加交互 network.addInteractionListener(function(evt:InteractionEvent):void{ if(evt.kind != InteractionEvent.DOUBLE_CLICK_ELEMENT){ return; } var element:IElement = evt.element; if(element is Node){ if(!element.getClient("loaded")){ for each (var obj:Object in elementArray) { var jNode:Node = new Node(); jNode.setClient("loaded",true); jNode.name = obj.name; jNode.setClient("cpu",obj.cpuInfo); jNode.setClient("memoryCapacity",obj.memoryCapacity); box.add(jNode); var links:Link = new Link(element, jNode); links.setStyle(Styles.LINK_WIDTH, 2); links.setStyle(Styles.LINK_COLOR, 0x00FF00); box.add(links); autoLayouter.animate = false; autoLayouter.doLayout(Consts.LAYOUT_ROUND); autoLayouter.animate = true; element.setClient("loaded",true); } } } }); } private function getName():void{ } private function selectBox(e:Event):void{ trace(box.selectionModel.count); } private function initBox():void{ rootNode.name = "master"; rootNode.image = "routerImage"; network.makeVisible(rootNode); box.add(rootNode); } private function doLayout(e:Event = null):void{ this.autoLayouter.explicitXOffset = 300; this.autoLayouter.explicitYOffset = 600; if(this.zoomToOverview.selected){ this.autoLayouter.doLayout(this.popupMenuButton.label, function():void{ network.callLater(network.zoomOverview, [true]); }); }else{ this.autoLayouter.doLayout(this.popupMenuButton.label); } } protected function consumer_faultHandler(event:MessageFaultEvent):void { trace("MessageFaultEvent:"+event.message.faultString); } protected function consumer_channelFaultHandler(event:ChannelFaultEvent):void { trace("服务端链接关闭"+event.faultDetail); } protected function consumer_messageHandler(event:MessageEvent):void { elementArray = event.message.body as ArrayCollection; box.clear(); initBox(); for each (var obj:Object in elementArray) { var jNode:Node = new Node(); jNode.setClient("loaded",true); jNode.name = obj.name; jNode.setClient("cpu",obj.cpuInfo); jNode.setClient("memory",obj.memoryCapacity); jNode.setClient("memoryCapacity",obj.memoryCapacity+"%"); if(obj.memoryCapacity>60 && obj.memoryCapacity<70){ addAlarm(jNode.name,jNode.id,AlarmSeverity.MINOR,box.alarmBox); }else if(obj.memoryCapacity>69 && obj.memoryCapacity<80){ addAlarm(jNode.name,jNode.id,AlarmSeverity.MAJOR,box.alarmBox); } else if(obj.memoryCapacity>79 && obj.memoryCapacity<101){ addAlarm(jNode.name,jNode.id,AlarmSeverity.CRITICAL,box.alarmBox); } box.add(jNode); var links:Link = new Link(rootNode, jNode); links.setStyle(Styles.LINK_WIDTH, 2); links.setStyle(Styles.LINK_COLOR, 0x00FF00); box.add(links); autoLayouter.animate = false; autoLayouter.doLayout(Consts.LAYOUT_ROUND); autoLayouter.animate = true; rootNode.setClient("root",true); } network.makeVisible(rootNode); } //添加告警,通常需要从alarmBox来操作,这点与网元需要在elementBox中增删是一致的 private function addAlarm(alarmID:Object,elementID:Object, alarmSeverity:AlarmSeverity,alarmBox:AlarmBox):void{ var alarm:Alarm=new Alarm(alarmID,elementID,alarmSeverity); network.alarmLabelFunction = function(e:IElement):Object{ return null; } alarmBox.add(alarm); } private var menu:Menu = null; ]]> </fx:Script> <mx:VBox width="100%" height="100%"> <mx:HBox id="toolbar" top="4" left="4" right="18" horizontalGap="0" /> <twaver:Network id="network" width="100%" height="70%" verticalCenter="0" horizontalCenter="0"/> <twaver:Table width="100%" height="30%" id="table" editable="false" > <twaver:columns> <mx:DataGridColumn dataField="name" headerText="节点" textAlign="center"/> <twaver:TableColumn client="memoryCapacity" textAlign="center" headerText="内存信息" itemRenderer="com.xinyitech.bp.flex.common.AlarmSeverityRenderer"/> <twaver:TableColumn client="severity" textAlign="center" headerText="" visible="false"/> <twaver:TableColumn client="cpu" textAlign="center" headerText="CPU信息"/> <twaver:TableColumn client="memory" textAlign="center" headerText="" visible="false"/> </twaver:columns> </twaver:Table> </mx:VBox> </s:Group>