2.메시지 공급자(Message Provider) 개발

X-PUSH 서버에 의해 각 넥사크로 클라이언트에 전달될 메시지는 X-PUSH 서버와 소켓 통신을 통해 전달합니다. 메시지 제공 시 통신에 사용될 프로토콜이 정의되어 있으며, Java의 경우 API를 제공합니다.

2.1메시지 구성

X-PUSH 서버가 전달하는 메시지는 다음과 같은 3가지로 구성됩니다.

Topic Type 은 메시지가 어떤 종류인지를 나타내는 일종의 그룹입니다. 다양한 메시지 중에 현재 주가, 운영정보, 뉴스 등으로 각 메시지의 타입을 분류할 수 있습니다.

Topic Id 는 하나의 Topic Type 안에서 메시지를 구분하기 위한 것입니다. 같은 현재 주가 데이터라 하더라도 각 종목의 종목코드에 의해 메시지가 구분될 수 있습니다.

Topic Type 과 Topic Id 가 하나의 Topic Key를 형성합니다. Topic Id 가 같은 경우라도 Topic Type 이 다르면 다른 topic입니다. 예를 들어 현재 주가 Topic Type 의 종목코드 1001 message id로 구성된 메시지와 최근 뉴스 Topic Type 의 종목코드 1001 Topic Id 로 구성된 메시지는 서로 다른 topic key를 가지며 다른 메시지입니다.

Field Values는 실제 전달하고자 하는 내용입니다.

Topic Id 는 영문, 숫자, 특수문자( - _ @ . ) 를 사용할 수 있습니다.

2.2메시지 사이즈 제약사항

전달되는 메시지의 최대 크기는 메시지 length 6byte가 표현할 수 있는 999,999byte입니다. 그러나 X-PUSH의 모든 동작은 개개의 메시지를 단위로 하기 때문에 메시지의 크기가 클 경우 성능에 크게 영향을 끼칠 수 있고, 가용메모리가 부족할 경우가 발생할 수 있습니다.

X-PUSH가 권장하는 사이즈는 다음과 같습니다.

Field Values는 구분자를 포함하기 때문에, 실제 데이터는 4000byte보다 작습니다.

2.3Java API

Java API를 사용하기 위한 library는 $XPUSH_HOME/api 경로에 위치한 xpush-x.x.x_API.jar 입니다.

Java의 경우 메시지 공급을 위한 API가 제공되어 실제 socket 통신을 위한 개발을 하지 않아도 됩니다. API에는 하단의 3개의 클래스가 제공됩니다.

PushMessageProvider

void connect(String host, int port, String id, String password)

커넥션 생성

PushResponse sendPushMessage(PushMessage pushMessage)

PushMessage 전송

void close()

커넥션 종료

PushMessageBinaryProvider

void connect(String host, int port, String id, String password)

커넥션 생성

PushResponse sendPushMessage(PushMessage pushMessage)

PushMessage 전송

void close()

커넥션 종료

void useKeepService(boolean f)

keep 사용 여부 설정

void setKeepIntervalTime(long time)

keep 시간 간격 설정

PushMessage

void setProjectID(String projectID)

projectID 설정

void setTopicType(String topicType)

Topic Type 설정

void setTopicId(String topicId)

Topic Id 설정

void setActionType(String Action)

action 설정

void addData(String data)

데이터 추가

void addData(byte[] data)

데이터 추가

void addData(int index, String data)

데이터 추가

void addData(int index, byte[] data)

데이터 추가

void setData(int index, String data)

데이터 수정

void setData(int index, byte[] data)

데이터 수정

void resetData()

데이터 삭제

void removeData()

데이터 삭제

void removeData(int index)

데이터 삭제

void setAvailablePeriod(long days)

메시지 저장 기간

void setEmergencyMessage(boolean emergency)

긴급 메세지 설정

List Unmarshal(String data)

데이터 변환

2.3.1PushMessageProvider

X-PUSH 서버와 연결을 맺고 Json 프로토콜로 메시지를 전송합니다.

연결을 위한 connect(), close() 메소드와 실제 메시지 전송을 위한 sendMessage() 메소드를 제공합니다.

Package

com.nexacro.xpush.api

connect

X-PUSH 서버에 접속하고 인증을 하기 위한 메소드입니다.

void connect (String host, int port, String id, String password) throws UnknownHostException, IOException, LoginFailException, ProtocolMismatchException;

Parameters

host

연결하고자 하는 X-PUSH 서버의 IP 주소

port

연결하고자 하는 X-PUSH 서버의 Message Provider 접속 포트

id

사용자 인증 id

password

사용자 인증 password

Exception

UnknownHostException

연결하고자 하는 X-PUSH 서버의 주소값(host, port)이 잘못된 경우 발생합니다.

IOException

네트워크 통신 에러 시 발생합니다.

LoginFailException

사용자 인증이 실패한 경우 발생합니다.

ConnectionClosedException

해당 채널이 종료되거나 하여 연결이 불가능할 때 발생합니다.

sendPushMessage

하나의 PushMessage 객체를 X-PUSH 서버에 전송합니다.

PushResponse sendPushMessage (PushMessage pushMessage) throws IOException

Parameters

pushMessage

X-PUSH 서버에 전송하고자 하는 Push Message 데이터가 저장된 객체

Return value

PushResponse

provider 응답 객체

ActionType이 Constants.ACTION_RELI_STRING, Constants.ACTION_MONT_STRING일때 PushResponse 객체가 반환됩니다.


메소드

getAction() : 메시지 Action

getBodysize() : 메시지 본문 크기

istSucceed(): 성공 실패(true, false)

getErrorCode() : 성공 실패 ("OK" or "NG")

getSessionId() : 세션 아이디

response.getBody() : 바이트 메시지

getMessage() : 에러 메시지

Exception

IOException

네트워크 통신 에러 시 발생합니다.

close

PushMessageProvider.connect() 메소드를 이용하여 생성한 X-PUSH 서버와 연결을 해제하는 메소드입니다. 일반적으로 X-PUSH 서버와 메시지 통신을 종료할 때 호출합니다.

void close () throws IOException

Exception

IOException

네트워크 통신 에러 시 발생합니다.

2.3.2PushMessageBinaryProvider

X-PUSH 서버와 연결을 맺고 Binary 프로토콜로 메시지를 전송합니다.

연결을 위한 connect(), close() 메소드와 실제 메시지 전송을 위한 sendMessage() 메소드를 제공합니다.

provider keep 사용 여부를 설정하기 위한 useKeepService() 메소드와 provider keep 시간 간격 설정을 위한 setKeepIntervalTime() 메소드를 제공합니다.

Package

com.nexacro.xpush.api

connect

X-PUSH 서버에 접속하고 인증을 하기 위한 메소드입니다.

void connect (String host, int port, String id, String password) throws UnknownHostException, IOException, LoginFailException, ProtocolMismatchException;

Parameters

host

연결하고자 하는 X-PUSH 서버의 IP 주소

port

연결하고자 하는 X-PUSH 서버의 Message Provider 접속 포트

id

사용자 인증 id

password

사용자 인증 password

Exception

UnknownHostException

연결하고자 하는 X-PUSH 서버의 주소값(host, port)이 잘못된 경우 발생합니다.

IOException

네트워크 통신 에러 시 발생합니다.

LoginFailException

사용자 인증이 실패한 경우 발생합니다.

ConnectionClosedException

해당 채널이 종료되거나 하여 연결이 불가능할 때 발생합니다.

sendPushMessage

하나의 PushMessage 객체를 X-PUSH 서버에 전송합니다.

PushResponse sendPushMessage (PushMessage pushMessage) throws IOException

Parameters

pushMessage

X-PUSH 서버에 전송하고자 하는 Push Message 데이터가 저장된 객체

Return value

PushResponse

provider 응답 객체

ActionType이 Constants.ACTION_RELI_STRING, Constants.ACTION_MONT_STRING일때 PushResponse 객체가 반환됩니다.


메소드

getAction() : 메시지 Action

getBodysize() : 메시지 본문 크기

istSucceed(): 성공 실패(true, false)

getErrorCode() : 성공 실패 ("OK" or "NG")

getSessionId() : 세션 아이디

response.getBody() : 바이트 메시지

getMessage() : 에러 메시지

Exception

IOException

네트워크 통신 에러 시 발생합니다.

close

PushMessageProvider.connect() 메소드를 이용하여 생성한 X-PUSH 서버와 연결을 해제하는 메소드입니다. 일반적으로 X-PUSH 서버와 메시지 통신을 종료할 때 호출합니다.

void close () throws IOException

Exception

IOException

네트워크 통신 에러 시 발생합니다.

useKeepService

Provider Keep 사용 여부를 설정하는 메소드입니다.

void useKeepService (boolean f)

Parameters

f

Provider Keep 사용 여부를 설정하는 boolean 값 (default = false)

setKeepIntervalTime

Provider Keep 시간 간격을 설정하는 메소드입니다.

void setKeepIntervalTime (long time)

Parameters

time

Provider Keep 시간 간격을 설정하는 long 값 (단위: ms)

setKeepErrorCallBack

callback 함수 등록

void setKeepErrorCallBack(KeepErrorCallBack callback)

Parameters

callback

CallBack Interface


ex)

// 콜백생성

KeepErrorCallBack keepErrorCallBack = new KeepErrorCallBack() {


// 사용자 정의 함수

public void onData(String remoteSession, String localSession) {

/*

* remoteSession:59.10.169.3:50002, localSession:172.10.12.24:48429

*/

System.out.println("onData() " + remoteSession + ", " + localSession);

}

};


// 콜백함수 적용

pushMessageBinaryProvider.setKeepErrorCallBack(keepErrorCallBack);

2.3.3PushMessage

X-PUSH 서버에 전달할 메시지에 해당하는 클래스입니다. 하나의 메시지는 Topic Type, Topic Id, data로 구성됩니다. Topic Type 은 메시지들의 그룹 혹은 종류라 할 수 있고, Topic Id는 각 메시지를 구분하기 위한 구분자이며, data는 실제로 전달될 메시지입니다.

Package

nexacro.xpush.fw.service.provider

setProjectID

ProjectID 값을 설정합니다.

void setProjectID (String projectID)

Parameters

projectID

설정할 projectID 값.

setTopicType

Topic Type 값을 설정합니다.

void setTopicType (String TopicType)

Parameters

TopicType

설정할 topic type 값.

메시지 성격에 따른 타입입니다. 예를 들어 현재 주가의 경우 "CPDT", 운영 정보의 경우 "OPDT", 뉴스의 경우 "NEWS" 등으로 시스템에 맞게 정의해서 사용할 수 있습니다.


topic type은 반드시 4byte여야 합니다.

setTopicId

Topic id를 설정합니다. 특정 타입의 메시지 중에서 메시지를 선별하기 위한 키를 설정합니다. 예를 들어 "CPDT"와 같은 현재 주가 메시지 중에서 종목코드 "1234"의 주가를 전달하는 메시지라면 topicId는 "1234"가 됩니다.

void setTopicId(String topicId)

Parameters

TopicType

설정할 topic type 값.

setActionType

전달할 값을 추가하는 메소드입니다.

void setActionType(String actionType)

Parameters

actionType

설정할 액션타입

신뢰성 메시지 : Constants.ACTION_RELI_STRING

실시간 메시지 : Constants.ACTION_PUSH_STRING

addData

전달할 값을 추가하는 메소드입니다.

void addData (String data)

Parameters

data

전달할 String 값

void addData (byte[] data)

Parameters

data

전달할 byte[] 값

void addData (int index, String data)

Parameters

index

인덱스

data

해당 인덱스에 전달할 String 값

void addData (int index, byte[] data)

Parameters

index

인덱스

data

해당 인덱스에 전달할 byte[] 값

setData

전달할 값을 수정하는 메소드입니다.

void setData (int index, String data)

Parameters

index

인덱스

data

해당 인덱스에 전달할 String 값

void setData (int index, byte[] data)

Parameters

index

인덱스

data

해당 인덱스에 전달할 byte[] 값

resetData

전달할 값을 삭제하는 메소드입니다.

void resetData ()

removeData

전달할 값을 삭제하는 메소드입니다.

void removeData ()
void removeData (int index)

Parameters

index

인덱스

setAvailablePeriod

신뢰성 메시지 유효기간

void setAvailablePeriod(int days)

Parameters

days

일 단위

setEmergencyMessage

긴급 메세지 여부

- true 로 설정된 경우, 메세지의 우선 순위는 보낸 즉시 가장 높으며 각 큐의 첫 번째에 적재 됩니다. 이를 통해 클라이언트 혹은 모바일 Notification을 가장 먼저 받을 수 있습니다.

void setEmergencyMessage(boolean emergency)

Parameters

emergency

true / false

unmarshal

메시지 변환

- T_Message 테이블의 message_body 데이터를 List<String> 타입으로 반환합니다.

List<String> unmarshal(String value)

Parameters

value

T_Message 테이블의 message_body 컬럼의 값

ex) 0020004Test0005Test1

2.4예제

2.4.1Json 프로토콜 예제

일반 메시지

public class DemoProvider_Push {
    public static void main(String[] args) {

        String host = "localhost";
        int port = 50002;
        String id = "tobesoft";
        String password = "xpush";

        System.out.println("host="+host+", 
            port="+port+", 
            id="+id+", 
            password="+password);

        PushMessageProvider pushMessageProvider 
            = new PushMessageProvider();
        try {
            pushMessageProvider.connect(host, port, id, password);
        } catch (UnknownHostException e) {
            e.printStackTrace();
            System.exit(0);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        } catch (LoginFailException e) {
            e.printStackTrace();
            System.exit(0);
        } catch (ConnectionClosedException e) {
            e.printStackTrace();
            System.exit(0);
        }

        try {
            PushMessage pushMessageNOTI = new PushMessage();
            pushMessageNOTI.setActionType(Constants.ACTION_PUSH_STRING);
            pushMessageNOTI.setCharsetName("utf-8");
            pushMessageNOTI.setProjectID("PRO#1");
            pushMessageNOTI.setTopicType("NOTI");
            pushMessageNOTI.setTopicId("000000001");
            pushMessageNOTI.addData("Tobesoft Push Message " + currentTime);
            PushResponse response = 
                     pushMessageProvider.sendPushMessage(pushMessageNOTI);

    System.out.println("response.isSucceed() : " + response.isSucceed());
    System.out.println("response.getErrorCode() : " + response.getErrorCode());
    System.out.println("response.getResponseMessage().getMessageId() : "
     + response.getResponseMessage().getMessageId());
    System.out.println("response.getResponseMessage().getTopic().getType() : "
     + response.getResponseMessage().getTopic().getType());
    System.out.println("response.getResponseMessage().getTopic().getId() : "
     + response.getResponseMessage().getTopic().getId());

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (XPushMessageException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 

        try {
            pushMessageProvider.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

신뢰성 메시지

public class DemoProvider_Reli {
    public static void main(String[] args) {

        String host = "localhost";
        int port = 50002;
        String id = "tobesoft";
        String password = "xpush";

        System.out.println("host="+host+", 
            port="+port+", 
            id="+id+", 
            password="+password);
        PushMessageProvider pushMessageProvider = new PushMessageProvider();
        try {
            pushMessageProvider.connect(host, port, id, password);
        } catch (UnknownHostException e) {
            e.printStackTrace();
            System.exit(0);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        } catch (LoginFailException e) {
            e.printStackTrace();
            System.exit(0);
        } catch (ConnectionClosedException e) {
            e.printStackTrace();
            System.exit(0);
        }

        try {
            PushMessage pushMessageOPDT = new PushMessage();
            pushMessageOPDT.setActionType(Constants.ACTION_RELI_STRING);
            pushMessageOPDT.setCharsetName("utf-8");
            pushMessageOPDT.setProjectID("PRO#1");
            pushMessageOPDT.setTopicType("OPDT");
            pushMessageOPDT.setTopicId("ALL");
            SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
            String currentTime = "pushed current time : "+
                formatter.format(new Date());
            pushMessageOPDT.addData(currentTime);
            pushMessageOPDT.setAvailablePeriod(30);
            PushResponse response = 
                pushMessageProvider.sendPushMessage(pushMessageOPDT);
            System.out.println( "isSuccess(true or false) : " 
                           + response.isSucceed() );
            System.out.println("MessageId :" 
                           + response.getResponseMessage().getMessageId()); 
            System.out.println("TopicType :" 
                           + response.getResponseMessage().getTopic().getType() ); 
            System.out.println("TopicId : " 
                           + response.getResponseMessage().getTopic().getId() ); 
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Exception e="+e);
        } catch (XPushMessageException e) {
            e.printStackTrace();
        }

        try {
            pushMessageProvider.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.4.2Binary 프로토콜 예제

일반 메시지

public class PushMessageBinaryProvider_Push {
    public static void main(String[] args) {                
        PushMessageBinaryProvider pushMessageBinaryProvider = new PushMessageBinaryProvider();        
        try {            
            /*
             * Keep 서비스 사용 유무
             */        
            pushMessageBinaryProvider.useKeepService(false);
            pushMessageBinaryProvider.setKeepIntervalTime(1 * 1000); // default: 5000
            KeepErrorCallBack keepErrorCallBack = new KeepErrorCallBack() {
                public void onData(String remoteSession, String localSession) {
                    /*
                     * remoteSession:59.10.169.3:50002, localSession:172.10.12.24:48429
                     */
                    System.out.println("onData() remoteSession:" + remoteSession + ", localSession:" + localSession);
                }
            };
            pushMessageBinaryProvider.setKeepErrorCallBack(keepErrorCallBack);        

                
            pushMessageBinaryProvider.connect("localhost",50002,"tobesoft","xpush");
            
            PushMessage pushMessage = new PushMessage();
            pushMessage.setProjectID("TFT");
            pushMessage.setTopicType("NOTI");
            pushMessage.setTopicId("ALL");                        
            pushMessage.setActionType(Constants.ACTION_PUSH_STRING); // 일반 메시지
                    
            /*
             * 추가 (String)
             */
            pushMessage.addData("11111");    
            pushMessage.addData("22222");
            pushMessage.addData("33333");
            
            /*
             * 추가 (byte[])
             */
            pushMessage.addData("aaa");
            pushMessage.addData("bbb".getBytes());            
            
            /*
             * 추가 (해당 인덱스에 String)
             */
            pushMessage.addData(0, "ccc");
            
            /*
             * 추가 (해당 인덱스에 byte[])
             */            
            pushMessage.addData(2, "ddd".getBytes());            
                        
            /*
             * 수정 (해당 인덱스에 String)
             */
            pushMessage.setData(1, "eee");
            
            /*
             * 수정 (해당 인덱스에 byte[])
             */
            pushMessage.setData(2, "fff".getBytes());
            
            /*
             * 삭제
             */
//            pushMessage.resetData();    
//            pushMessage.removeData();        
            
            /*
             * 삭제 (해당 인덱스의 값)
             */
            pushMessage.removeData(1);            
            
                
            PushResponse pushResponse = pushMessageBinaryProvider.sendPushMessage(pushMessage);
            System.out.println("pushResponse = " + pushResponse);
            if(pushMessage.getActionType().equals("RELI")) {
                System.out.println("isSucceed: " + pushResponse.isSucceed());
                if(!pushResponse.getErrorCode().equals("OK")) {
                    System.out.println("ErrorCode: "+pushResponse.getErrorCode());
                }
                System.out.println("Action(): " + pushResponse.getAction());
                System.out.println("ProjectID(): " + pushResponse.getProjectID());
                System.out.println("SessionId(): " + pushResponse.getSessionId());
                System.out.println("MessageId(): " + pushResponse.getResponseMessage().getMessageId());
                System.out.println("Type(): " + pushResponse.getResponseMessage().getTopic().getType());
                System.out.println("Id(): " + pushResponse.getResponseMessage().getTopic().getId());            
            }            
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (LoginFailException e) {
            e.printStackTrace();
        } catch (ConnectionClosedException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }         
        
        try {
            pushMessageBinaryProvider.close();
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }
}

신뢰성 메시지

public class PushMessageBinaryProvider_Push {
    public static void main(String[] args) {                
        PushMessageBinaryProvider pushMessageBinaryProvider = new PushMessageBinaryProvider();        
        try {            
            /*
             * Keep 서비스 사용 유무
             */        
            pushMessageBinaryProvider.useKeepService(false);
            pushMessageBinaryProvider.setKeepIntervalTime(1 * 1000); // default: 5000
            KeepErrorCallBack keepErrorCallBack = new KeepErrorCallBack() {
                public void onData(String remoteSession, String localSession) {
                    /*
                     * remoteSession:59.10.169.3:50002, localSession:172.10.12.24:48429
                     */
                    System.out.println("onData() remoteSession:" + remoteSession + ", localSession:" + localSession);
                }
            };
            pushMessageBinaryProvider.setKeepErrorCallBack(keepErrorCallBack);        

                
            pushMessageBinaryProvider.connect("localhost",50002,"tobesoft","xpush");
            
            PushMessage pushMessage = new PushMessage();
            pushMessage.setProjectID("TFT");
            pushMessage.setTopicType("NOTI");
            pushMessage.setTopicId("ALL");                        
            pushMessage.setActionType(Constants.ACTION_RELI_STRING); // 신뢰성 메시지
                    
            /*
             * 추가 (String)
             */
            pushMessage.addData("11111");    
            pushMessage.addData("22222");
            pushMessage.addData("33333");
            
            /*
             * 추가 (byte[])
             */
            pushMessage.addData("aaa");
            pushMessage.addData("bbb".getBytes());            
            
            /*
             * 추가 (해당 인덱스에 String)
             */
            pushMessage.addData(0, "ccc");
            
            /*
             * 추가 (해당 인덱스에 byte[])
             */            
            pushMessage.addData(2, "ddd".getBytes());            
                        
            /*
             * 수정 (해당 인덱스에 String)
             */
            pushMessage.setData(1, "eee");
            
            /*
             * 수정 (해당 인덱스에 byte[])
             */
            pushMessage.setData(2, "fff".getBytes());
            
            /*
             * 삭제
             */
//            pushMessage.resetData();    
//            pushMessage.removeData();        
            
            /*
             * 삭제 (해당 인덱스의 값)
             */
            pushMessage.removeData(1);            
            
                
            PushResponse pushResponse = pushMessageBinaryProvider.sendPushMessage(pushMessage);
            System.out.println("pushResponse = " + pushResponse);
            if(pushMessage.getActionType().equals("RELI")) {
                System.out.println("isSucceed: " + pushResponse.isSucceed());
                if(!pushResponse.getErrorCode().equals("OK")) {
                    System.out.println("ErrorCode: "+pushResponse.getErrorCode());
                }
                System.out.println("Action(): " + pushResponse.getAction());
                System.out.println("ProjectID(): " + pushResponse.getProjectID());
                System.out.println("SessionId(): " + pushResponse.getSessionId());
                System.out.println("MessageId(): " + pushResponse.getResponseMessage().getMessageId());
                System.out.println("Type(): " + pushResponse.getResponseMessage().getTopic().getType());
                System.out.println("Id(): " + pushResponse.getResponseMessage().getTopic().getId());            
            }            
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (LoginFailException e) {
            e.printStackTrace();
        } catch (ConnectionClosedException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }         
        
        try {
            pushMessageBinaryProvider.close();
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }
}