Presentation is loading. Please wait.

Presentation is loading. Please wait.

임베디드 프로그래밍 Lecture #11 2017. 12. 11.

Similar presentations


Presentation on theme: "임베디드 프로그래밍 Lecture #11 2017. 12. 11."— Presentation transcript:

1 임베디드 프로그래밍 Lecture #11

2 목 차 JMS API 기반 Console 클라이언트 JMS와의 연동

3 JMS(Java Message Service)?
A specification that describes a common way for Java programs to create, send, receive and read distributed enterprise messages loosely coupled communication Asynchronous messaging Reliable delivery A message is guaranteed to be delivered once and only once. Outside the specification Security services Management services A JMS Application is one or more JMS clients that exchange messages asynchronously

4 A JMS Application JMS Clients Messages Administered Objects
Java programs that send/receive messages Messages Administered Objects preconfigured JMS objects created by an admin for the use of clients ConnectionFactory, Destination(queue or topic) JMS Provider(Message Broker) messaging system that implements JMS and administrative functionality A JMS Application is one or more JMS clients that exchange messages asynchronously

5 JMS Administration Bind Administrative Tool JNDI Namespace Lookup
JMS Provider A JMS Application is one or more JMS clients that exchange messages asynchronously JMS Client Logical Connection

6 JMS Messaging Domains Point-to-Point (PTP) Publish-Subscribe systems
built around the concept of message queues each message has only one consumer Publish-Subscribe systems uses a “topic” to send and receive messages each message has multiple consumers A JMS Application is one or more JMS clients that exchange messages asynchronously. JMS deals with two kinds of message domains. - Point-to-Point (PTP) are built around the concept of message queues.     Publish-Subscribe systems use a “topic” to send and receive messages. Supports messages containing Java objects and XML pages.

7 Point-to-Point Messaging
Msg Msg consumes Client1 Client2 Queue sends 1 consumer a sender and a receiver have no timing dependencies. the receiver can fetch the mesg whether or not it was running when client sent the msg receiver acknowledges acknowledges

8 Publish/Subscribe Messaging
subscribes Topic Client2 Msg Client1 delivers publishes subscribes multiple consumers publishers and subscribers have timing dependency. a client can consume only msgs published after its subscription and must continue to be active to consume msgs ( exception durable subscription) Client3 delivers

9 Message Consumptions Synchronously(동기적 수신) Asynchronously(비동기적 수신)
A subscriber or a receiver explicitly fetches the message from the destination by calling the receive method. The receive method can block until a message arrives or can time out if a message does not arrive within a specified time limit. Asynchronously(비동기적 수신) A client can register a message listener with a consumer. Whenever a message arrives at the destination, the JMS provider delivers the message by calling the listener's onMessage() method. A message listener is similar to an event listener

10 JMS API Programming Model
Connection Factory creates Connection Message Producer Message Consumer creates creates Session JMS Interfaces: connectionfactory: administrative object used by client to create a connection connection: an active connection for JMS provider destination: administrative object that encapsulates the identity of a message destination session: a single-threaded context for sending/receiving message messageproducer: an object created by a session that is used for sending msg to a dest messageconsumer: similar receives from sends to creates Destination Destination Msg

11 JMS Client Example Setting up a connection and creating a session
InitialContext jndiContext=new InitialContext(); //look up for the connection factory ConnectionFactory cf=jndiContext.lookup(connectionfactoryname); //create a connection Connection connection=cf.createConnection(); //create a session Session session=connection.createSession(false,Session.AUTO_ACKNOWLEDGE); //create a destination object Destination dest1=(Queue) jndiContext.lookup(“/jms/myQueue”); // for PointToPoint Destination dest2=(Topic)jndiContext.lookup(“/jms/myTopic”); // for publish-subscribe transacted session connection.createSession(true,0); AUTO_ACK: when client succesfully returned froma call to receive or when messagelistener returned successfully Client_ACK: a client acks a mesg by calling the message’s acknowledge() method ( consume 10 ack 5th, you acked for all 10) DUPS_ACK:dups are permitted, lazy ack (??)

12 Producer Sample Setup connection and create a session
Creating producer MessageProducer producer=session.createProducer(dest1); Send a message Message m=session.createTextMessage(); m.setText(“just another message”); producer.send(m); Closing the connection connection.close(); transacted session connection.createSession(true,0); AUTO_ACK: when client succesfully returned froma call to receive or when messagelistener returned successfully Client_ACK: a client acks a mesg by calling the message’s acknowledge() method ( consume 10 ack 5th, you acked for all 10) DUPS_ACK:dups are permitted, lazy ack (??)

13 Consumer Sample (Synchronous)
Setup connection and create a session Creating consumer MessageConsumer consumer=session.createConsumer(dest1); Start receiving messages connection.start(); Message m=consumer.receive();

14 Consumer Sample (Asynchronous)
Setup the connection, create a session Create consumer Registering the listener MessageListener listener=new myListener(); consumer.setMessageListener(listener); myListener should have onMessage() public void onMessage(Message msg){ //read the massage and do computation } register the listener

15 Listener Example public void onMessage(Message message) {
TextMessage msg = null; try { if (message instanceof TextMessage) { msg = (TextMessage) message; System.out.println("Reading message: " + msg.getText()); } else { System.out.println("Message of wrong type: " + message.getClass().getName()); } } catch (JMSException e) { System.out.println("JMSException in onMessage(): " + e.toString()); } catch (Throwable t) { System.out.println("Exception in onMessage():" + t.getMessage());

16 JMS Messages Message Header Message Properties (optional)
used for identifying and routing messages contains vendor-specified values, but could also contain application- specific data typically name/value pairs Message Properties (optional) Message Body(optional) contains the data five different message body types in the JMS specification

17 JMS Message Types Message Type Contains Some Methods TextMessage
String getText, setText MapMessage set of name/value pairs setString, setDouble, setLong, getDouble, getString BytesMessage stream of uninterpreted bytes writeBytes, readBytes StreamMessage stream of primitive values writeString, writeDouble, writeLong, readString ObjectMessage serialize object setObject, getObject

18 More JMS Features (1) Durable subscription Request/Reply
by default a subscriber gets only messages published on a topic while a subscriber is alive durable subscription retains messages until they are received by a subscriber or expire Request/Reply by creating temporary queues and topics Session.createTemporaryQueue() producer=session.createProducer(msg.getJMSReplyTo()); reply= session.createTextMessage(“reply”); reply.setJMSCorrelationID(msg.getJMSMessageID); producer.send(reply); producer=session.createProducer(msg.getJMSReplyTo()); reply= session.createTextMessage(“reply”); reply.setJMSCorrelationID(msg.getJMSMessageID); producer.send(reply);

19 More JMS Features (2) Transacted sessions
session=connection.createSession(true, 0) combination of queue and topic operation in one transaction is allowed void onMessage(Message m) { try { Message m2=processOrder(m); publisher.publish(m2); session.commit(); } catch(Exception e) { session.rollback(); }

20 More JMS Features (3) Persistent/Nonpersistent delivery
Producer.setDeliveryMethod(DeliveryMode.NON_PERSISTENT); Producer.send(mesg,DeliveryMode.NON_PERSISTENT,3,1000); Message selectors SQL-like syntax for accessing header: subscriber = session.createSubscriber(topic, “priority>6 AND type=‘alert’ ”); Point to point: selector determines single recipient Pub-sub: acts as filter send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

21 JMS와 MQTT와의 연동(1) ActiveMQ JMS Provider
JMS, Stomp, AMQP, MQTT 등의 프로토콜 지원 JMS 이외의 프로토콜의 메시지를 JMS 클라이언트와 교환할 수 있도록 자동 매핑 기능을 지원  MQTT 송수신자와 JMS 송수신자 간에 메시지 교환 가능 Spring, J2EE WAS의 컴포넌트와 사물을 JMS로 연동 가능 send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

22 JMS와 MQTT와의 연동(2) ActiveMQ의 JMS 활성화
$(ActiveMQ 설치 디렉토리)/conf/activemq.xml 설정 파일에서 설정 기본적으로 포트로 설정 send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

23 JMS와 MQTT와의 연동(3) JMS와 MQTT 간 토픽 및 메시지 매핑 토픽 필터링
Ex) jiot/mqtt/thing  jiot.mqtt.thing MQTT Message(byte array)  JMS BytesMessage (javax.jms.BytesMessage) 기 능 MQTT JMS 토픽 레벨 구분자 ‘/’ ‘.’ 레벨 와이드 카드 ‘+’ ‘*’ 자식 레벨 와이드 카드 ‘#’ ‘>’ send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

24 JMS와 MQTT와의 연동(4) JMS와 paho.client.mqttv3 클래스 간의 관계
send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

25 JMS CLI Console (1) JMS CLI Console 프로젝트 생성
기존의 JiotMqttCliConsole 프로젝트를 이용 MqttCliConsole 프로그램과 기능적으로 유사 데이터 저장 기능 등을 활용 send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

26 JMS CLI Console (2) JMS 관련 라이브러리 추가
$(ActiveMQ 설치 디렉토리)/lib 디렉토리에서 다음의 5가지 라이브러 리를 복사하여 프로젝트에 추가 send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

27 JMS CLI Console (3) JMS 관련 라이브러리 등록 프로젝트 속성에서 라이브러리 등록
send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

28 JMS CLI Console (4) JMS CLI Console 클래스 생성 및 구현
send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

29 package com.example.mqtt;
import java.io.IOException; import java.io.StringReader; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; import javax.jms.BytesMessage; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.Topic; import javax.json.Json; import javax.json.JsonObject; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.util.ByteArrayOutputStream; import org.eclipse.paho.client.mqttv3.MqttClient; public class JmsCliConsole { public static final String TOPIC_PREFIX = "jiot.mqtt.thing."; public static final String TOPIC_COMMAND = TOPIC_PREFIX + "%s.%s.command"; public static final String TOPIC_RESULT = TOPIC_PREFIX + "%s.result"; public static final String TOPIC_BROADCAST = TOPIC_PREFIX + "%s.broadcast"; private String url; private String clientId; private MqttClient client; private Connection connection; private Session session; private String commandTopicName; private String resultTopicName; private String broadcastTopicName; private MessageProducer commandProducer; private MessageConsumer resultConsumer; private MessageConsumer broadcastConsumer; private BigDataHandler bdHandler; public JmsCliConsole(String clientId, String handlerId, BigDataHandler bdHandler) throws JMSException { this.clientId = clientId; this.bdHandler = bdHandler; url = System.getProperty("jms.server", "tcp:// :61616"); commandTopicName = String.format(TOPIC_COMMAND, clientId, handlerId); resultTopicName = String.format(TOPIC_RESULT, clientId); broadcastTopicName = String.format(TOPIC_BROADCAST, handlerId); System.out.println("JMS server url: " + url); ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url); connection = connectionFactory.createConnection(); connection.start(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Topic commandTopic = session.createTopic(commandTopicName); Topic resultTopic = session.createTopic(resultTopicName); Topic broadcastTopic = session.createTopic(broadcastTopicName); commandProducer = session.createProducer(commandTopic); resultConsumer = session.createConsumer(resultTopic); resultConsumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message msg) { try { System.out.println("Result: " + convertMessageToString(msg)); displayPrompt(); } catch (JMSException e) { Logger.getLogger(JmsCliConsole.class.getName()).log(Level.SEVERE, null, e); } catch (IOException e) { } });

30 broadcastConsumer = session.createConsumer(broadcastTopic);
broadcastConsumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message msg) { try { StringReader in = new StringReader(convertMessageToString(msg)); JsonObject jsonObj = Json.createReader(in).readObject(); String broadcastType = jsonObj.getString("type"); if (broadcastType.equals(ChangeOfValue.TYPE)) { saveData(new ChangeOfValue(jsonObj)); } else { System.out.println("Received a broadcast: " + msg); } catch (JMSException e) { Logger.getLogger(JmsCliConsole.class.getName()).log(Level.SEVERE, null, e); } catch (IOException e) { }); public void publish(String payload) throws JMSException { BytesMessage message = session.createBytesMessage(); message.writeBytes(payload.getBytes()); commandProducer.send(message); public void saveData(ChangeOfValue cov) { bdHandler.saveBigData(cov); public void close() throws JMSException { connection.stop(); commandProducer.close(); resultConsumer.close(); broadcastConsumer.close(); session.close(); connection.close(); private String convertMessageToString(Message msg) throws JMSException, IOException { if (!(msg instanceof BytesMessage)) { throw new JMSException("Only BytesMessage is processible"); } BytesMessage response = (BytesMessage)msg; ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[512]; int count = 0; while ((count = response.readBytes(buffer)) != -1) { baos.write(buffer, 0, count); return new String(baos.toByteArray()); public static void displayPrompt() { System.out.print("Input command or 'q'(quit) > "); public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("Input client ID: "); String clientId = input.nextLine(); System.out.print("Input the IP address of thing: "); String handlerId = input.nextLine().replace('.', '_'); try { System.out.print("JmsCliConsole connecting..."); BigDataHandler bdHandler = new BigDataHandler(); JmsCliConsole console = new JmsCliConsole(clientId, handlerId, bdHandler); displayPrompt(); for (String line = input.nextLine(); !line.equals("q"); line = input.nextLine()) { if (line.trim().length() == 0) { continue;

31 if (line.equals("display")) {
bdHandler.displayBigData(); displayPrompt(); } else if (line.equals("clear")) { bdHandler.clearBigData(); else { console.publish(line); System.out.println("Waitting the result from thing..."); console.close(); } catch (JMSException e) { Logger.getLogger(JmsCliConsole.class.getName()).log(Level.SEVERE, null, e); input.close();

32 JMS CLI Console (5) JMS CLI Console 프로그램 실행
ActiveMQ JMS Provider 실행(Host PC) #> $(ActiveMQ 설치 디렉토리)/bin/activemq start 라즈베리파이에서 JiotMqttCliThing 배포 파일 실행 JMS CLI console 프로그램 실행 Host PC에서 java application으로 실행 Run Configuration에서 “VM Options”항에 “-Djms.server=tcp://[ActiveMQ Host Address]:61616”을 추가 send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

33 JMS CLI Console (6) JMS CLI Console 프로그램 실행
send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)

34 JMS CLI Console (7) JMS CLI Console 프로그램 테스트
send(msg,persistent, 3,100) 3: priority( default 4) 100: timeout (0 : no timeout)


Download ppt "임베디드 프로그래밍 Lecture #11 2017. 12. 11."

Similar presentations


Ads by Google