본문 바로가기

카테고리 없음

Server-Push example

StreamingAMFChannel을 이용한 Server-Push example

1. 채널설정(services-config.xml, messaging-config.xml)
2. 서버 코드(Java class) -- server push
3. 클라이언트 코드(Flex Application) -- message 수신
4. 브라우저에서 JSP를 요청하여 서버코드 실행(서버푸시 시작)
5. Flex Application을 실행하여 서버푸시되는 메시지를 수신 및 출력

프로젝트 설정법은 여기를 참조

....................................................................................................................................................................................................................................
services-config.xml
<channels> 태그 안에 서버푸시에 사용될 채널을 다음과 같이 등록한다.
    <channel-definition id="my-amf-stream"
        class="mx.messaging.channels.StreamingAMFChannel">
        <endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure/streamingamf"            class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
           <properties>
               <idle-timeout-minutes>0</idle-timeout-minutes>
              <!--
               <max-streaming-clients>10</max-streaming-clients>
               <server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis>
               <user-agent-settings>
               <user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="3" />
               <user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="3" />
               </user-agent-settings>
              -->
           </properties>
    </channel-definition>


....................................................................................................................................................................................................................................

messaging-config.xml
다음과 같이 작성한다.

<?xml version="1.0" encoding="UTF-8"?>
<service id="message-service"
    class="flex.messaging.services.MessageService">

    <adapters>
        <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
        <!-- <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/> -->
    </adapters>

    <default-channels>
        <channel ref="my-amf-stream"/>
    </default-channels>
   
    <destination id="server-push-test">
        <properties>
            <server>
                <message-time-to-live>0</message-time-to-live>
            </server>
        </properties>
        <channels>
            <channel ref="my-amf-stream"/>
            <channel ref="my-polling-amf"/>
        </channels>
    </destination>

</service>


......................................................................................................................................................................................................................................................................

Server-Push 기능을 가진 클래스 (BlazeDS의 라이브러리 클래스인 MessageBroker를 이용하여 클라이언트에게 메시지를 전송한다. MessageBroker가 실행되는 서버에서 실행되어야 한다)

package test;

import flex.messaging.MessageBroker;
import flex.messaging.messages.AsyncMessage;
import flex.messaging.util.UUIDUtils;

public class FlexServerPush {
 
 public static void startPush(){
  new Thread(){
   public void run(){
    while(true){
     serverPush(new java.util.Date().toString());
     try{
      Thread.sleep(1000);
     }catch(Exception e){e.printStackTrace();}
    }
   }
  }.start();
 }
 
 public static void serverPush(String str)
 {
  final MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
  final String clientID = UUIDUtils.createUUID(false);
  final AsyncMessage msg = new AsyncMessage();
  msg.setDestination("server-push-test");
  msg.setClientId(clientID);
  msg.setMessageId(UUIDUtils.createUUID(false));
  msg.setTimestamp(System.currentTimeMillis());
  msg.setBody(str);
  msgBroker.routeMessageToService(msg, null);
 }
}


..........................................................................................................................................................................................................................................................

sendMessage.jsp
위에 선언된 클래스의 메소드를 호출하여 서버푸시를 시작하게 한다

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@page import="test.FlexServerPush" %>
<%
  try
  {
    FlexServerPush.startPush();
    out.println("Server-Push started.");
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
%>


..........................................................................................................................................................................................................................................................

PushClient.mxml
서버푸시되는 메시지를 수신하여 출력한다

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="logon();" width="480" height="299">
   
    <mx:Script>
        <![CDATA[
            import mx.messaging.*;
            import mx.messaging.messages.*;
            import mx.messaging.events.*;
           
            // Subscribe to destination.
            private function logon():void {
                consumer.subscribe();
            }

            // Write received message to TextArea control.
            private function messageHandler(event:MessageEvent):void {
                // Handle message event.
                ta.text = event.message.body + "\n";
            }

            private function faultHandler(event:MessageFaultEvent):void {
                // Handle message fault event.
            }
        ]]>
    </mx:Script>
   
    <mx:Consumer id="consumer"
        destination="server-push-test"
        message="messageHandler(event);"
        fault="faultHandler(event);"/>
    <mx:Panel y="10" width="448" height="270" layout="absolute" horizontalCenter="0" title="Flex Server-Push 예제" fontSize="14" fontFamily="Georgia">
        <mx:TextArea id="ta" width="407" height="205" horizontalCenter="0" y="10"/>
    </mx:Panel>
</mx:Application>

위의 Consumer.mxml을 작성하기 위해 Flex Project를 생성할 때는 RemoteObject를 위한 프로젝트를 생성할 때와 같은 절차에 따라야 한다.


..........................................................................................................................................................................................................................................................

실행순서
blazeds 프로젝트안에서 sendMessage.jsp를 실행하여 서버푸시기능을 시작하게 하고, 이어서 Flex Application을 실행하여 화면에 서버푸시된 메시지가 제대로 수신되는지 확인한다.

Server-Push 예제 1 끝

..........................................................................................................................................................................................................................................................

Server-Push 예제 2

서버측에서 Employee클래스의 인스턴스를 Flex 클라이언트에게 전달하는 예

서버측 코드

package test;

import flex.messaging.MessageBroker;
import flex.messaging.messages.AsyncMessage;
import flex.messaging.util.UUIDUtils;
/* 1초에 한번씩 사원정보(Employee객체)를 Flex 클라이언트에게 전달하는 서버측 코드(Server-Push) */
public class FlexServerPush {
 
 public static void startPush(){
   new Thread(){
    public void run(){
     while(true){
      serverPush();
      try{
       Thread.sleep(1000);
      }catch(Exception e){e.printStackTrace();}
     }
    }
   }.start();
 }
 
 static int empno;
 static char tmp  = '가';

 public static void serverPush()
 {
   final MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
   final String clientID = UUIDUtils.createUUID(false);
   final AsyncMessage msg = new AsyncMessage();
   msg.setDestination("server-push-test");
   msg.setClientId(clientID);
   msg.setMessageId(UUIDUtils.createUUID(false));
   msg.setTimestamp(System.currentTimeMillis());
  String ename = (tmp++) + "길동";
   Employee emp = new Employee(++empno, ename, new java.util.Date().toString());
   msg.setBody(emp);
   msgBroker.routeMessageToService(msg, null);
 }
}


 Client 측 코드 (Flex Application) : Employee 클래스의 인스턴스를 수신하여 출력하는 예

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="logon();" width="480" height="299">
   
    <mx:Script>
        <![CDATA[
            import mx.messaging.*;
            import mx.messaging.messages.*;
            import mx.messaging.events.*;
           
            // Subscribe to destination.
            private function logon():void {
                consumer.subscribe();
            }

            // Write received message to TextArea control.
            private function messageHandler(event:MessageEvent):void {
                // 서버측에서 전송한 데이터는 Employee클랠스의 인스턴스이므로....
                var emp:Object = event.message.body;
                var empno:uint = emp.empno;
                var ename:String = emp.ename;
                var birthDate:String = emp.birthDate;
                ta.text = "사번 : "+empno+"\n이름 : "+ename+"\n생일 : "+birthDate;

            }

            private function faultHandler(event:MessageFaultEvent):void {
                // Handle message fault event.
            }
        ]]>
    </mx:Script>
   
    <mx:Consumer id="consumer"
        destination="server-push-test"
        message="messageHandler(event);"
        fault="faultHandler(event);"/>
    <mx:Panel y="10" width="448" height="270" layout="absolute" horizontalCenter="0" title="Flex Server-Push 예제" fontSize="14" fontFamily="Georgia">
        <mx:TextArea id="ta" width="407" height="205" horizontalCenter="0" y="10"/>
    </mx:Panel>
</mx:Application>



위와는 달리 DataGrid에 Employee데이터를 출력하려면..................

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="logon();" width="480" height="299">
   
    <mx:Script>
        <![CDATA[
            import mx.messaging.*;
            import mx.messaging.messages.*;
            import mx.messaging.events.*;
           
            // Subscribe to destination.
            private function logon():void {
                consumer.subscribe();
            }

            // Write received message to TextArea control.
            private function messageHandler(event:MessageEvent):void {
                // 서버측에서 전송한 데이터는 Employee데이터를 DataGrid에 출력한다
                dg.dataProvider=event.message.body;
            }

            private function faultHandler(event:MessageFaultEvent):void {
                // Handle message fault event.
            }
        ]]>
    </mx:Script>
   
    <mx:Consumer id="consumer"
        destination="server-push-test"
        message="messageHandler(event);"
        fault="faultHandler(event);"/>
    <mx:Panel y="10" width="448" height="270" layout="absolute" horizontalCenter="0" title="Flex Server-Push 예제 2" fontSize="14" fontFamily="Georgia">

        <mx:DataGrid id="dg" y="10" horizontalCenter="0" textAlign="center" width="408">
            <mx:columns>
                <mx:DataGridColumn headerText="사 번" dataField="empno"/>
                <mx:DataGridColumn headerText="이 름" dataField="ename"/>
                <mx:DataGridColumn headerText="생 일" dataField="birthDate"/>
            </mx:columns>
        </mx:DataGrid>

    </mx:Panel>
</mx:Application>



위에서 사용된 DTO (Employee.java)

package test;

public class Employee implements java.io.Serializable {
 public int empno;
 public String ename;
 public String birthDate;
 
 public Employee(int empno, String ename, String birthDate){
  this.empno = empno;
  this.ename = ename;
  this.birthDate = birthDate;
 }
}


Server-Push 예제 2 끝
................................................................................................................................................................................................................