1. 程式人生 > >flex+blazeds+java後臺訊息推送(簡單示例)

flex+blazeds+java後臺訊息推送(簡單示例)

現在有個問題需要大家思考一下,有個已經上線了的專案,有好好幾千甚至上萬的客戶在使用了。現在專案開發商想釋出一個通知。在今天下午6點需要重新啟動伺服器,想讓線上的人在在預定的時間內都收到訊息,讓大家做好相應的準備,大家會怎麼做?
1、逐個打電話
2、在前臺弄一個定時器,每隔一定的時間重新整理一次
3、後臺訊息主動往前臺推送
相信你已經做出選擇了。。。呵呵 ,下面講一個簡單的例子,

首先,新建一個web專案,新增開發flex需要的jar包,和blazeds相關檔案,然後把web專案轉成flex專案(不明白怎麼弄沒事,過幾天會寫一篇這樣的文章),然後修改一下services-config.xml和messaging-config.xml檔案,新增如下程式碼
services-config.xml

1.   <channel-definition

2.   id="my-streaming-amf"

3.   class="mx.messaging.channels.StreamingAMFChannel">

4.   <endpoint

5.   url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf"

6.   class="flex.messaging.endpoints.StreamingAMFEndpoint"

7.   />

8.   <properties>

9.   <idle-timeout-minutes>0</idle-timeout-minutes>

10.  <max-streaming-clients>10</max-streaming-clients>

11.  <server-to-client-heartbeat-millis>5000

12.  </server-to-client-heartbeat-millis>

13.  <user-agent-settings>

14.  <user-agent

15.  match-on="MSIE"

16.  kickstart-bytes="2048"

17.  max-streaming-connections-per-session="1"

18.  />

19.  <user-agent match-on="Firefox"

20.  kickstart-bytes="2048"

21.  max-streaming-connections-per-session="1"

22.  />

23.  </user-agent-settings>

24.  </properties>

25.  </channel-definition>

複製程式碼


messaging-config.xml

1.   <destination

2.   id="tick-data-feed">

3.   <properties>

4.   <server>

5.   <allow-subtopics>true</allow-subtopics>

6.   <subtopic-separator>.</subtopic-separator>

7.   </server>

8.   </properties>

9.   <channels>

10.  <channel

11.  ref="my-polling-amf" />

12.  <channelref="my-streaming-amf"

13.  />

14.  </channels>

15.  </destination>

複製程式碼

OK,完了之後,我們新建一個servlet作為服務端

1.   package com.serverpush;

2.    

3.   import java.io.IOException;

4.   import

5.   javax.servlet.ServletException;

6.   import

7.   javax.servlet.http.HttpServlet;

8.   import

9.   javax.servlet.http.HttpServletRequest;

10.  import

11.  javax.servlet.http.HttpServletResponse;

12.   

13.  import

14.  com.model.Tick;

15.   

16.  import flex.messaging.MessageBroker;

17.  import

18.  flex.messaging.messages.AsyncMessage;

19.  import

20.  flex.messaging.util.UUIDUtils;

21.   

22.  /**

23.  * Servlet implementation class

24.  TickCacheServlet

25.  */

26.  public class TickCacheServlet extendsHttpServlet

27.  {

28.  private static final long serialVersionUID= 1L;

29.  private static

30.  FeedThread thread;

31.   

32.  /**

33.  * @see

34.  HttpServlet#HttpServlet()

35.  */

36.  public TickCacheServlet() {

37.  super();

38.  //

39.  TODO Auto-generated constructor stub

40.  }

41.   

42.  /**

43.  * @see

44.  HttpServlet#doGet(HttpServletRequestrequest, HttpServletResponse

45.  *

46.  response)

47.  */

48.  protected void doGet(HttpServletRequest

49.  request,

50.  HttpServletResponse response) throwsServletException, IOException

51.  {

52.  //接收前臺引數

53.  String cmd =request.getParameter("cmd");

54.  if

55.  (cmd.equals("start")) {

56.  start();

57.  }

58.  if (cmd.equals("stop"))

59.  {

60.  stop();

61.  }

62.  }

63.   

64.  public void start() {

65.  if (thread == null)

66.  {

67.  thread = new

68.  FeedThread();

69.  thread.start();

70.  }

71.  System.out.println("start!!");

72.  }

73.   

74.  public

75.  void stop() {

76.  thread.running = false;

77.  thread = null;

78.  }

79.   

80.  /**

81.  *

82.  @see HttpServlet#doPost(HttpServletRequestrequest, HttpServletResponse

83.  *

84.  response)

85.  */

86.  protected void doPost(HttpServletRequest

87.  request,

88.  HttpServletResponse response) throwsServletException, IOException

89.  {

90.  doGet(request, response);

91.  }

92.  //執行緒類,每隔多長時間傳送一次

93.  public static class

94.  FeedThread extends Thread {

95.  public boolean running = true;

96.  public void

97.  run() {

98.  MessageBroker msgBroker =

99.  MessageBroker.getMessageBroker(null);

100. String clientID =

101. UUIDUtils.createUUID();

102. int i = 0;

103. while (running) {

104. Tick tick = new

105. Tick();

106. tick.setMessageCN("今天下午6點更新程式需重啟伺服器");

107. tick.setSeqNo(String.valueOf(i));

108. System.out.println(i);

109.  

110. AsyncMessage

111. msg = new

112. AsyncMessage();

113. msg.setDestination("tick-data-feed");

114. msg.setHeader("DSSubtopic",

115. "tick");

116. msg.setClientId(clientID);

117. msg.setMessageId(UUIDUtils.createUUID());

118. msg.setTimestamp(System.currentTimeMillis());

119. msg.setBody(tick);

120. msgBroker.routeMessageToService(msg,

121. null);

122. i++;

123. try {

124. Thread.sleep(2000);

125. } catch (InterruptedException

126. e) {

127. }

128. }

129. }

130. }

131. }

複製程式碼

在新建一個model用來儲存訊息

1.   package com.model;

2.    

3.   public class Tick {

4.   private String

5.   seqNo;

6.   private String messageCN;

7.    

8.   public String getMessageCN()

9.   {

10.  return messageCN;

11.  }

12.   

13.  public void setMessageCN(String messageCN)

14.  {

15.  this.messageCN = messageCN;

16.  }

17.   

18.  public String getSeqNo()

19.  {

20.  return seqNo;

21.  }

22.   

23.  public void setSeqNo(String seqNo)

24.  {

25.  this.seqNo = seqNo;

26.  }

27.  }

複製程式碼

後臺就搞定了。下面看前臺

新建一個mxml檔案和一個VO檔案
mxml:

1.   <?xml version="1.0"

2.   encoding="utf-8"?>

3.   <s:Application

4.   xmlns:fx="http://ns.adobe.com/mxml/2009"

5.   xmlns:s="library://ns.adobe.com/flex/spark"

6.   xmlns:mx="library://ns.adobe.com/flex/mx"

7.   minWidth="955"

8.   minHeight="600">

9.   <s:layout>

10.  <s:BasicLayout/>

11.  </s:layout>

12.   

13.  <fx:Script>

14.  <![CDATA[

15.  import

16.  mx.controls.Alert;

17.  import mx.messaging.ChannelSet;

18.  import

19.  mx.messaging.Consumer;

20.  import

21.  mx.messaging.events.MessageEvent;

22.   

23.  protected function

24.  submsg():void

25.  {

26.  Alert.show("click start");

27.  var consumer:Consumer = new

28.  Consumer();

29.  consumer.destination ="tick-data-feed";

30.  consumer.subtopic =

31.  "tick";

32.  consumer.channelSet = new

33.  ChannelSet(["my-streaming-amf"]);

34.  //新增message的監聽,當後臺有訊息傳送時,呼叫messageHandler

35.   

36.  consumer.addEventListener(MessageEvent.MESSAGE,messageHandler);

37.   

38.  consumer.subscribe();

39.  }

40.  private function

41.  messageHandler(event:MessageEvent):void

42.  {

43.  var tick:TickVO =

44.  event.message.body as TickVO;

45.  txtTick.text = tick.messageCN+tick.seqNo;

46.   

47.  }

48.   

49.   

50.  ]]>

51.  </fx:Script>

52.   

53.  <fx:Declarations>

54.  <!--

55.  將非可視元素(例如服務、值物件)放在此處 -->

56.  </fx:Declarations>

57.  <mx:Panel

58.  x="32"

59.  y="43"

60.  width="362"

61.  height="302"

62.  layout="absolute"

63.  title="Watch

64.  Tick">

65.  <mx:Label

66.  x="72"

67.  y="43"

68.  text="Label"

69.  id="txtTick"/>

70.  <mx:Button

71.  x="132"

72.  y="71"

73.  label="Button"

74.  click="submsg()"/>

75.  </mx:Panel>

76.  </s:Application>

複製程式碼

VO,就是對應後臺的model

1.   package

2.   {

3.   //遠端到後臺的Tick,也就是說他們倆現在是對應的關係了,你在後臺給model賦值了,在前臺flex中就可以通過VO

4.   //取得model中的值

5.   [RemoteClass(alias="com.model.Tick")]

6.    

7.   [Bindable]

8.   public class TickVO

9.   {

10.  private var

11.  _seqNo:String;

12.  private var _messageCN:String;

13.   

14.  public function

15.  TickVO()

16.  {

17.   

18.  }

19.  public function get seqNo():String

20.  {

21.  return

22.  _seqNo;

23.  }

24.   

25.  public function setseqNo(value:String):void

26.  {

27.  _seqNo

28.  = value;

29.  }

30.   

31.  public function get messageCN():String

32.  {

33.  return

34.  _messageCN;

35.  }

36.   

37.  public function set

38.  messageCN(value:String):void

39.  {

40.  _messageCN =

41.  value;

42.  }

43.   

44.   

45.  }

46.  }

複製程式碼