2016-11-15 5 views
1

Ich entwickelte eine Web-Anwendung mit Wildfly 10.0.0 endgültige eigenständige Bereitstellung, EJB, Hibernate. I bezeichnet und schuf die MDB, MessageProducerBean (@RequestScoped), Queue und ConnectionFactory-.Senden von Nachrichten und Benachrichtigungen an bestimmte Benutzer und alle Benutzer, die JMS und MDB verwenden?

Wenn ich sende Nachricht von MessageProducerBean ich es in MDB empfangen kann.

Mein Problem ist meine Anwendung kann von vielen Benutzern zugreifen. Ich muss einige Nachrichten an bestimmte Benutzer (z. B. Benutzer A) und einige Nachrichten an alle Benutzer senden.

Ich lese einen Artikel mit diesem Wissen, wenn wir Queue verwenden, können wir an einen Client senden, und wenn wir Topic verwenden, können wir an viele Clients senden, aber ich habe keine klare Vorstellung davon bekommen. Und mein nächstes Problem ist, dass Nachrichten nur funktionieren, wenn Benutzer aktiv sind.

Ich muss jederzeit eine Nachricht senden, ob sie online sind oder nicht. Wenn sie sich offline nach dem Login einloggen sollten die Massagen angezeigt werden. Kann mir jemand helfen? Ich werde mein Problem unten zusammenfassen.

1) Müssen Nachrichten und Benachrichtigungen von Benutzern gesendet werden.

2) müssen alle Nachrichten auch Benutzer offline bleiben.

Hier ist mein Codes

Standalone-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> 

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); 
    } 
}} 

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()); 

    } 
} } 

Vielen Dank im Voraus!

Antwort

2

Endlich fand ich einen Weg. Ich poste hier, denn es könnte jemandem helfen.

Wenn ich zusammengefasst, was ich getan habe.

Zuerst brauchen wir einen Anwendungsbenutzer in Wildfly. Gehen Sie dazu zu {wildflyHome}/bin und führen Sie die ./add-user.sh.

Geben Sie den Benutzertyp als Anwendung ein (Option b). Und geben Sie einen Benutzernamen und ein Passwort ein.

Zum Vergleich: link 1

In Link oben nehmen Schritt 1 und 2.

ändern Sie die Standalone-full.xml als

<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> 

In diesem Subsystem unter sicherheits Einstellung wir erlaubten Löschen und erstellen Sie eine dauerhafte Warteschlange.

Und meine Java-Klasse für das Senden und Nachricht empfängt, wie folgt,

zuerst die Ressource injizieren als

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

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

Nachricht Methode senden, wie folgt, ich

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(); 
} 

In diesem Verfahren erstellen die TopicConnection, indem Sie den Benutzernamen und das Passwort für Ihre Anwendung angeben.

Für die Verbindung habe ich clientId gesetzt und für die Nachricht habe ich eine stringProperty für den Fall, dass Benutzer eine Nachricht erhalten, müssen sie nur ihre Nachricht erhalten.

Meine erhaltene Methode wie folgt,

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(); 
    } 
} 

In dieser Methode, die ich alle Nachrichten eine durableTopicConsumer für halten erstellt, wenn der Benutzer zu inaktiv.

Ich übergab einen Parameterwert als Selektor für jeden Benutzer, der nur ihre Nachricht erhält.

Wenn benötigen Sie weitere Kenntnisse auf diesem beziehen link 2

Hope this helfen.

0

Fügen Sie für einen einzelnen Verbraucher eine Nachrichteneigenschaft hinzu, die den Verbraucher identifiziert, und lassen Sie den Benutzer Nachrichtenselektoren verwenden, um nur seine Nachrichten zu empfangen.

Für alle Verbraucher ist die beste Lösung, ein Thema zu verwenden und alle Verbraucher abonnieren zu lassen. Wenn Sie alle Benutzer kennen, sind einzelne Nachrichten für jeden Verbraucher in der gleichen Warteschlange wie oben möglich, aber keineswegs die beste Vorgehensweise.

+0

Danke für die wertvolle Antwort. Können Sie mir mit derselben Beispielnachrichteigenschaft helfen? – coolSmart

+0

Nachricht msg = session.createTextMessage (messageToSend); msg.setStringProperty ("user.name", "ssosna"); msg.setStringProperty ("host.name", "meindesktop"); –

+0

Danke @Scott Sosna für Ihre Hilfe. – coolSmart

Verwandte Themen