2016-11-15 8 views
1

私は、Wildfly 10.0.0の最終的なスタンドアロンデプロイメントであるEJB、Hibernateを使ってWebアプリケーションを開発しました。私が言及してMDBMessageProducerBean(@RequestScoped)、キューのConnectionFactoryを作成しました。メッセージと通知を特定のユーザーに送信する方法と、すべてのユーザーがJMSとMDBを使用する方法

メッセージプロデューサビーンからMDBで受け取ることができます。

私の問題は、アプリケーションが多くのユーザーからアクセスできることです。特定のユーザー(例:User-A)といくつかのメッセージをすべてのユーザーに送信する必要があります。

キューを使用して1つのクライアントに送信できる場合は、その知識のある記事を読んで、トピックを使用すると多くのクライアントに送信できますが、それについて明確な考えはありませんでした。私の次の問題は、このメッセージがアクティブなユーザーの場合にのみ動作することです。

オンラインであるかどうかにかかわらず、いつでもメッセージを送信する必要があります。彼らがログインした後にオフラインにいる場合、マッサージが表示されます。誰もこれを助けることができますか? 以下、私の問題を要約します。

1)メッセージと通知をユーザーが送信する必要があります。

2)オフラインでもすべてのメッセージをユーザーに保存する必要があります。

はここ

MessageProducerBean事前に

@JMSDestinationDefinition(name = "queue/testQueue", 
    interfaceName = "javax.jms.Queue", 
    destinationName = "queue/testQueue") 
@Named("messageProducerBean") 
@RequestScopedpublic class MessageProducerBean { 

@Inject 
private JMSContext context;  
@Resource(mappedName = "queue/testQueue") 
private Queue queue; 
private final static Logger LOGGER = Logger.getLogger(MessageProducerBean.class.toString()); 
@Resource(mappedName = "ConnectionFactory") 
private ConnectionFactory factory; 

private String message; 

public String getMessage() { 
    return message; 
} 

public void setMessage(String message) { 
    this.message = message; 
} 

public void sendMessage() { 
    try { 
     String text = "Message from producer: " + message; 
     context.createProducer().send(queue, text); 

     FacesMessage facesMessage 
       = new FacesMessage("Sent message: " + text); 
     FacesContext.getCurrentInstance().addMessage(null, facesMessage); 
    } catch (Throwable t) { 
     LOGGER.log(Level.SEVERE, "SenderBean.sendMessage: Exception: {0}", t.toString()); 

    } 
} } 

おかげMDB

@MessageDriven(mappedName = "queue/testQueue", activationConfig = { 
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "queue/testQueue"), 
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), 
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") }) 
public class MessageDrivenBean implements MessageListener { 

private final static Logger LOGGER = Logger.getLogger(MessageDrivenBean.class.toString()); 

public MessageDrivenBean() { 
    System.out.println("TextMDB.ctor, this=" + hashCode()); 
} 

@Override 
public void onMessage(Message rcvMessage) { 
    TextMessage msg = null; 
    try { 
     if (rcvMessage instanceof TextMessage) { 
      msg = (TextMessage) rcvMessage; 
      LOGGER.log(Level.INFO, "Received Message from topic: {0}", msg.getText()); 
     } else { 
      LOGGER.log(Level.WARNING, "Message of wrong type: {0}", rcvMessage.getClass().getName()); 
     } 
    } catch (JMSException e) { 
     throw new RuntimeException(e); 
    } 
}} 
私のコード

スタンドアロン-full.xml

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0"> 
     <server name="default"> 
      <security-setting name="#"> 
       <role name="guest" delete-non-durable-queue="true" create-non-durable-queue="true" consume="true" send="true"/> 
      </security-setting> 
      <address-setting name="#" message-counter-history-day-limit="10" page-size-bytes="2097152" max-size-bytes="10485760" expiry-address="jms.queue.ExpiryQueue" dead-letter-address="jms.queue.DLQ"/> 
      <http-connector name="http-connector" endpoint="http-acceptor" socket-binding="http"/> 
      <http-connector name="http-connector-throughput" endpoint="http-acceptor-throughput" socket-binding="http"> 
       <param name="batch-delay" value="50"/> 
      </http-connector> 
      <in-vm-connector name="in-vm" server-id="0"/> 
      <http-acceptor name="http-acceptor" http-listener="default"/> 
      <http-acceptor name="http-acceptor-throughput" http-listener="default"> 
       <param name="batch-delay" value="50"/> 
       <param name="direct-deliver" value="false"/> 
      </http-acceptor> 
      <in-vm-acceptor name="in-vm" server-id="0"/> 
      <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/> 
      <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/> 
      <jms-queue name="testQueue" entries="queue/testQueue java:jboss/exported/jms/queue/testQueue"/> 
      <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/> 
      <connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/> 
      <pooled-connection-factory name="activemq-ra" transaction="xa" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm"/> 
     </server> 
    </subsystem> 

です!

答えて

2

最後に私は方法を見つけました。私はそれが誰かのために役立つかもしれないためにここに投稿しています。

私が行ったことを要約すれば。

まず、wildflyでアプリケーションユーザーが必要です。そのためには{wildflyHome}/binに行き、./add-user.shを実行してください。

ユーザータイプをアプリケーション(オプションb)に指定します。ユーザー名とパスワードを入力します。link 1

上記のリンクテイクのステップ1とステップ2

は、我々ができるセキュリティ設定の下でこのサブシステムでは

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0"> 
     <server name="default"> 
      <security-setting name="#"> 
       <role name="guest" delete-non-durable-queue="true" create-non-durable-queue="true" delete-durable-queue="true" create-durable-queue="true" consume="true" send="true"/> 
      </security-setting> 
      <address-setting name="#" message-counter-history-day-limit="10" page-size-bytes="2097152" max-size-bytes="10485760" expiry-address="jms.queue.ExpiryQueue" dead-letter-address="jms.queue.DLQ"/> 
      <http-connector name="http-connector" endpoint="http-acceptor" socket-binding="http"/> 
      <http-connector name="http-connector-throughput" endpoint="http-acceptor-throughput" socket-binding="http"> 
       <param name="batch-delay" value="50"/> 
      </http-connector> 
      <in-vm-connector name="in-vm" server-id="0"/> 
      <http-acceptor name="http-acceptor" http-listener="default"/> 
      <http-acceptor name="http-acceptor-throughput" http-listener="default"> 
       <param name="batch-delay" value="50"/> 
       <param name="direct-deliver" value="false"/> 
      </http-acceptor> 
      <in-vm-acceptor name="in-vm" server-id="0"/> 
      <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/> 
      <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/> 
      <jms-queue name="JMSQueue" entries="java:/jboss/exported/jms/queue/JMSQueue jms/queue/JMSQueue"/> 
      <jms-topic name="JMSTopic" entries="jms/topic/JMSTopic java:jboss/exported/jms/topic/JMSTopic"/> 
      <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/> 
      <connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory jms/RemoteConnectionFactory" connectors="http-connector"/> 
      <connection-factory name="TopicConnectionFactory" entries="java:jboss/exported/jms/TopicConnectionFactory jms/TopicConnectionFactory" connectors="http-connector"/> 
      <pooled-connection-factory name="activemq-ra" transaction="xa" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm"/> 
     </server> 
    </subsystem> 

としてスタンドアロン-full.xmlを変更します。参考のため

耐久性のあるキューを削除して作成します。

、次のようにメッセージを送受信するための私のJavaクラス、

まず、私が作成するには、この方法では

public void send() throws JMSException { 
    TopicConnection connection = connectionFactory.createTopicConnection("JMSUser", "[email protected]"); 
    connection.setClientID("userA"); 
    TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 
    MessageProducer messageProducer = session.createProducer(topic); 
    TextMessage outMessage = session.createTextMessage(); 
    outMessage.setText("Hi User"); 
    outMessage.setStringProperty("name", "usera"); 
    messageProducer.send(outMessage); 
    System.out.println("message sent "); 
    connection.close(); 
} 

に従うよう

@Resource(mappedName = "jms/topic/EMSTopic") 
private Topic topic; 

@Resource(mappedName = "jms/TopicConnectionFactory") 
private TopicConnectionFactory connectionFactory; 

メッセージ送信方法などのリソースを注入私のアプリケーションのユーザ名とパスワードを提供することによってTopicConnection。

私はclientIdを設定し、メッセージの場合はユーザーがメッセージを受け取ったときにstringPropertyを設定してメッセージを受信する必要があります。

私は、従うように、この方法では

public void recieve() throws JMSException { 
    System.out.println("message reday to recieve "); 

    String selector = "name = 'usera'"; 

    try (TopicConnection connection = connectionFactory.createTopicConnection("JMSUser", "[email protected]")) { 
     connection.setClientID("userA"); 
     TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 
     TopicSubscriber subscriber = session.createDurableSubscriber(topic, "usera", selector, true); 
     connection.start(); 
     TextMessage message = (TextMessage) subscriber.receive(2000); 
     if (message != null) { 
      System.out.println("printing ==> " + message.getText()); 
     } else { 
      System.out.println("no messages"); 
     } 
     connection.close(); 
    } 
} 

の方法を受け取り、私はあまりにもユーザーがアクティブでないとき、すべてのメッセージを保つためdurableTopicConsumerを作成しました。

メッセージを取得するすべてのユーザーのセレクタとしてパラメータ値を渡しました。

あなたがこの参照してくださいlink 2

の更なる知識を必要とする場合、これが役立つことを願っています。

0

単一のコンシューマの場合、コンシューマを識別するメッセージプロパティを追加し、コンシューマがメッセージを受信するためにメッセージセレクタを使用するようにします。

すべてのコンシューマーにとって、最良の解決策はトピックを使用して、すべてのコンシューマーにサブスクライブすることです。すべてのユーザーがわかっている場合は、上記と同じキューにある各コンシューマの個々のメッセージが可能ですが、決してベストプラクティスではありません。

+0

貴重なご回答ありがとうございます。同じサンプルのメッセージプロパティで私を助けることができますか? – coolSmart

+0

メッセージmsg = session.createTextMessage(messageToSend); msg.setStringProperty( "user.name"、 "ssosna"); msg.setStringProperty( "host.name"、 "mydesktop"); –

+0

@Scott Sosnaありがとうございました。 – coolSmart

関連する問題