I have used javapns for pushing notifications to ios and android.gcm.server to push notification for android devices. But when I sent one notifications to many devices each device get multiple number of copies of the notification sent. Sometimes this number is 2 and sometimes 3. Hardly it delivers only one which I expect always. Any Ideas ?
My code is as below
public void pushNotificationsToAndroid(String pushMessage,
String contentType, String content, String notification_id,
List<String> devices) {
try {
Sender sender = new Sender(
properties
.getProperty("notification.android.senderIdDemo"));
com.google.android.gcm.server.Message message = new com.google.android.gcm.server.Message.Builder()
.collapseKey("1").timeToLive(3).delayWhileIdle(true)
.addData("message", pushMessage)
.addData("content_type", contentType)
.addData("content", content)
.addData("notification_id", notification_id).build();
MulticastResult result = sender.send(message, devices, 1);
if (result.getResults() == null) {
System.out.println(result.getFailure());
logger.debug("getFailure() of sender.send() method :",
result.getFailure());
}
} catch (Exception exception) {
logger.error("erorr push notification ");
}
System.out.println("sent not at " + new Date());
logger.debug(
"exit pushNotificationsToAndroid() method : current time is ",
new Date());
}
public void pushNotificationsToIOS(String pushMessage, String contentType,
String content, String notification_id, List<String> devices)
{
boolean production = true;
String password = properties
.getProperty("notification.ios.password");
String keyStroke = properties
.getProperty("notification.ios.certFileName");
AppleNotificationServer jksServer = null;
try {
jksServer = new AppleNotificationServerBasicImpl(keyStroke,
password, ConnectionToAppleServer.KEYSTORE_TYPE_JKS,
production);
} catch (KeystoreException keystoreException) {
logger.error("erorr creating jksServer");
}
PushNotificationPayload payload = PushNotificationPayload.complex();
try {
payload.addAlert(pushMessage);
} catch (JSONException e2) {
logger.error("erorr creating payload alert");
}
try {
payload.addCustomDictionary("content_type", contentType);
} catch (JSONException e1) {
logger.error("erorr creating payload content_type");
}
try {
payload.addCustomDictionary("content", content);
} catch (JSONException e1) {
logger.error("erorr creating payload content");
}
try {
payload.addCustomDictionary("notification_id", notification_id);
} catch (JSONException e1) {
logger.error("erorr creating payload notification_id");
}
PushNotificationManager pushManager = new PushNotificationManager();
try {
pushManager.initializeConnection(jksServer);
} catch (CommunicationException | KeystoreException e) {
logger.error("erorr connecting Server");
}
try {
List<PushedNotification> notifications = pushManager
.sendNotifications(payload, Devices.asDevices(devices));
} catch (CommunicationException | KeystoreException e) {
logger.error("erorr push notifications");
}
}
In android official site says about some reasons for duplicate message conditions .
Related
I want to send mails with attachments using JavaMail, but I am encountering an Exception difficult to understand.
My code is divided in two parts. The first is the class EmailSender, deputied to manage the mail account used to send mail and the system configurations. The second is the class Mail, that manages the single email. (Code at the end of the post)
When creating an EmailSender, the constructor automatically searches the SMTP settings from a list of known settings with the method setServerHost().
When the EmailSender is asked to send a Email, the EmailSender transforms the information contained in the fields of the Email into a MimeMessage by calling the build() method of the Email; this is then sent using the Transport class of JavaMail.
The testing method I use is rather simple:
public static void sendMail(String subject, String body, String to, String urlAttachment) {
System.out.printf("Username:\t");
String username = readString();
System.out.printf("Password:\t");
String password = readString();
EmailSender account = new EmailSender(username, password);
Email mail = new Email(username, to, subject, body);
mail.addAttachment(urlAttachment);
account.sendMail(to, subject, body);
}
The error I get in turn is less so.
javax.mail.MessagingException: IOException while sending message;
nested exception is:
java.io.IOException: Exception writing Multipart
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1365)
at mail.EmailSender.sendMail(EmailSender.java:104)
at mail.EmailSender.sendMail(EmailSender.java:122)
at Test.TestLibraries.sendMail(TestLibraries.java:134)
at Test.TestLibraries.main(TestLibraries.java:51)
Caused by: java.io.IOException: Exception writing Multipart
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:86)
at javax.activation.ObjectDataContentHandler.writeTo(Unknown Source)
at javax.activation.DataHandler.writeTo(Unknown Source)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1694)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1913)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1315)
... 4 more
Caused by: javax.mail.MessagingException: Empty multipart: multipart/mixed;
boundary="----=_Part_0_2129789493.1581503162040"
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:556)
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:84)
... 9 more
What is the problem (and how can I solve it)?
Here is the code:
public class EmailSender {
private String from;
private String password;
private String emailHost;
private Properties properties = System.getProperties();
private Session session;
public static final int serverName = 0;
public static final int serverPort = 1;
public static final int serverAutentication = 2;
public static final String[][] knownServerHostData = new String[][]
{
{ "smtp.mail.yahoo.com", "587", "SLL" } ,
{ "smtp.mail.com", "587", "StartTLS" } ,
{ "smtp.gmail.com", "587", "" } ,
{ "out.virgilio.it", "587", "" }
};
public EmailSender(String username, String password) {
this.from = username;
this.password = password;
this.session = Session.getDefaultInstance(properties);
this.setServerHost(password);
}
public boolean sendMail(String to, String subject, String body) {
return sendMail(new Email(from, to, subject, body));
}
public boolean sendMail(Email email) {
MimeMessage message = email.build(session);
Transport transport = null;
try {
transport = session.getTransport("smtp");
} catch (NoSuchProviderException e) { e.printStackTrace(); closeTransport(transport); }
try {
transport.connect(emailHost, from, password);
} catch (MessagingException e) { e.printStackTrace(); closeTransport(transport); }
try {
transport.sendMessage(message, message.getAllRecipients()); // <== THIS LINE RETURN EXCEPTION
} catch (MessagingException e) { e.printStackTrace(); closeTransport(transport); }
closeTransport(transport);
return true;
}
private void closeTransport(Transport transport) {
try { transport.close();
} catch (MessagingException e) { e.printStackTrace(); }
}
}
public class Email {
private String sender;
private Vector<String> recipients = new Vector<String>();
private Vector<String> cc = new Vector<String>();
private Vector<String> bcc = new Vector<String>();
private String subject;
private String body;
private Vector<String> attachments = new Vector<String>();
public Email(String from, String to, String subject, String body) {
this.sender = from;
this.recipients.add(to);
this.subject = subject;
this.body = body;
}
/** Returns a {#link MimeMessage} ready to be sent by an {#link EmailSender} with all the fields of {#code this} {#link Email}.
*
* #return
*/
public MimeMessage build(Session session) {
MimeMessage message = new MimeMessage(session);
// STEP 1 - Header
// Sets the sender
try { message.setFrom(new InternetAddress(sender));
} catch (AddressException e) { e.printStackTrace(); }
catch (MessagingException e) { e.printStackTrace(); }
// Sets the subject
try { message.setSubject(subject);
} catch (MessagingException e) { e.printStackTrace(); }
// Adds the recipients one by one
int i = 0;
try {
for(i=0 ; i<recipients.size() ; i++)
message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipients.get(i)));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th recipient gave error."); }
try {
for(i=0 ; i<cc.size() ; i++)
message.addRecipient(Message.RecipientType.CC, new InternetAddress(cc.get(i)));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th cc gave error."); }
try {
for(i=0 ; i<bcc.size() ; i++)
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(bcc.get(i)));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th bcc gave error."); }
// STEP 2 - Body
// Adds the body
MimeBodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
try {
messageBodyPart.setContent(message, "text/plain; charset=" +
MimeUtility.quote("us-ascii", HeaderTokenizer.MIME));
} catch (MessagingException e) { e.printStackTrace(); }
try { message.setText(body);
} catch (MessagingException e) { e.printStackTrace(); }
// Adds the attachments
try {
for(i=0 ; i<attachments.size() ; i++) // Preps the attachments
attachFileToMessageMultipart(multipart, attachments.get(i));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th attachment gave error."); }
catch (IOException e) { e.printStackTrace(); System.err.println("The " + i + "-th attachment gave error."); }
// STEP 3 - Appends the MimeMessage's body
try {
message.setContent(multipart);
} catch (MessagingException e1) { e1.printStackTrace(); }
return message;
}
/** This method avoids compatibility problems between JavaMail 1.3 and JavaMail 1.4.
* #throws MessagingException
* #throws IOException
*
*/
private static void attachFileToMessageMultipart(Multipart multipart, String fileUrl) throws MessagingException, IOException {
File file = new File(fileUrl);
if( ! file.isFile() )
throw new IOException("The specified url does not identify a file.");
// JavaMail 1.3
MimeBodyPart attachPart = new MimeBodyPart();
DataSource source = new FileDataSource(fileUrl);
attachPart.setDataHandler(new DataHandler(source));
attachPart.setFileName(file.getName());
multipart.addBodyPart(attachPart);
}
Edit: After reading the answer of Bill Shannon, I edited my method build(). The current version is:
MimeMessage message = new MimeMessage(session);
System.out.println("\t Building mail.");
// STEP 1 - Header
// Sets the sender
try { message.setFrom(new InternetAddress(sender));
} catch (AddressException e) { e.printStackTrace(); }
catch (MessagingException e) { e.printStackTrace(); }
// Sets the subject
try { message.setSubject(subject);
} catch (MessagingException e) { e.printStackTrace(); }
System.out.println("\t\t Sender and subject set mail.");
// Adds the recipients one by one
int i = 0;
try {
for(i=0 ; i<recipients.size() ; i++)
message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipients.get(i)));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th recipient gave error."); }
try {
for(i=0 ; i<cc.size() ; i++)
message.addRecipient(Message.RecipientType.CC, new InternetAddress(cc.get(i)));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th cc gave error."); }
try {
for(i=0 ; i<bcc.size() ; i++)
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(bcc.get(i)));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th bcc gave error."); }
System.out.println("\t\t TO, CC, BCC fields setted.");
// STEP 2 - Body
// Adds the body
MimeBodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
try {
messageBodyPart.setText(body);
} catch (MessagingException e) { e.printStackTrace(); }
try {
multipart.addBodyPart(messageBodyPart);
} catch (IllegalWriteException e) { e.printStackTrace(); }
catch (MessagingException e) { e.printStackTrace(); }
// try {
// messageBodyPart.setContent(message, "text/plain; charset=" +
// MimeUtility.quote("us-ascii", HeaderTokenizer.MIME));
// } catch (MessagingException e) { e.printStackTrace(); }
System.out.println("\t\t Body attached.");
// Adds the attachments
for(i=0 ; i<attachments.size() ; i++)
{
// Creates a BodyPart representing the attachment
try {
messageBodyPart.attachFile(attachments.get(i));
} catch (MessagingException e) { e.printStackTrace(); System.err.println("The " + i + "-th attachment gave error."); }
catch (IOException e) { e.printStackTrace(); System.err.println("The " + i + "-th attachment gave error."); }
// Appends the BodyPart to the MultiPart
try {
multipart.addBodyPart(messageBodyPart);
} catch (IllegalWriteException e) { e.printStackTrace(); }
catch (MessagingException e) { e.printStackTrace(); }
}
System.out.println("\t\t Files attached.");
// STEP 3 - Appends the MimeMessage's body
try {
message.setContent(multipart);
} catch (MessagingException e1) { e1.printStackTrace(); }
System.out.println("\t\t MimeMessage created.");
return message;
}
This version does not give Exceptions and the mail is sent... but without the attachment.
I don't understand what you're trying to do here:
messageBodyPart.setContent(message, "text/plain; charset=" +
MimeUtility.quote("us-ascii", HeaderTokenizer.MIME));
I'm sure you don't mean to add the MimeMessage object itself as
the content of a message body part. And you should never need to
use the MimeUtility.quote method in this way.
This statement:
message.setText(body);
sets the entire content of the MimeMessage object to be a plain
text message with the body string as its content. I don't think
that's what you want.
What you want is to use the setText method to set the content of
messageBodyPart object to the string body. Then add the messageBodyPart
object to the multipart object.
After that, you can add all the attachments to the multipart object. Note that you might want to use the MimeBodyPart.atttachFile
method to simplify your code.
I used to use GCM, now I 've passed to FCM.For this reason, right now, I am sending WebPush Message with Firebase Admin SDK. When I sent webpush, clients get notification without data. According to texts which I read, I have to encyrpt payload with JWT. However I could not find a way to encyrpt.
I've clientAuthSecret, clientPublicKey and endpoint. I need your leadership.
#Override
public WebPushResponse sendMessageToMultipleUsers(List<String> registrationTokens) throws IOException {
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())).build();
if (FirebaseApp.getApps().isEmpty()) {
FirebaseApp.initializeApp(options);
logger.info("Firebase application has been initialized");
}
MulticastMessage message = MulticastMessage.builder()
.setWebpushConfig(WebpushConfig.builder()
.setNotification(new WebpushNotification("$GOOG up 1.43% on the day",
"$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.", "https://my-server/icon.png"))
.build())
.addAllTokens(registrationTokens).build();
BatchResponse response = null;
try {
response = FirebaseMessaging.getInstance().sendMulticastAsync(message).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (response != null && response.getFailureCount() > 0) {
List<SendResponse> responses = response.getResponses();
List<String> failedTokens = new ArrayList<>();
for (int i = 0; i < responses.size(); i++) {
if (!responses.get(i).isSuccessful()) {
// The order of responses corresponds to the order of the registration tokens.
failedTokens.add(registrationTokens.get(i));
}
}
System.out.println("List of tokens that caused failures: " + failedTokens);
}
return null;
}
Messages published and response received are on two different subjects. Right now I have following set of functionality in my java class. Class is implementing TibrvMsgCallback interface.
How can i make sure that whatever the message is published i am receiving exactly its response?
public class TibcoRVUtility implements TibrvMsgCallback {
public void onMsg(TibrvListener listener, TibrvMsg msg) {
try {
_log.info("Request and Response found");
msgReceived = true;
} catch (final TibrvException ex) {
_log.error("Exception#" + this.getClass().getName() + ".onMsg", ex);
}
}
private void sendMessage(String messageString, final String soType,
final String responseSubject) {
try {
Tibrv.open(Tibrv.IMPL_NATIVE);
TibrvTransport transport = new TibrvRvdTransport(tibcoSetting.getService(), tibcoSetting.getNetwork(),
tibcoSetting.getDaemon());
String inboxName = transport.createInbox();
TibrvMsg msg = new TibrvMsg();
msg.setSendSubject("PUBLISH_SUBJECT");
msg.add("DATA", "DUMMY_MESSAGE");
TibrvListener listener = new TibrvListener(Tibrv.defaultQueue(), this, transport, responseSubject, null);
transport.send(msg);
_log.info("msg" + msg.toString());
_log.info("message successfully sent.");
while (!msgReceived) {
try {
Tibrv.defaultQueue().dispatch();
} catch (InterruptedException ex) {
_log.error("Exception#" + this.getClass().getName() + ".sendMessage", ex);
break;
} catch (TibrvException ex) {
_log.error("Exception#" + this.getClass().getName() + ".sendMessage", ex);
break;
}
}
listener.destroy();
transport.destroy();
} catch (TibrvException e) {
_log.error("Exception#" + this.getClass().getName() + ".sendMessage", e);
}
}
}
When you send a message, add another field
var correlation_id = Guid.NewGuid().ToString();
msg.add("CORRELATION_ID", correlation_id);
and then stash that correlation ID somewhere, in a hash set perhaps.
Have the publisher read the CORRELATION_ID off of the request and add it to the response.
When you receive a message, only process it if it has the ID that you are expecting in the CORRELATION_ID field.
I having a problem with the RabbitMQ Work Queue implementation. im current running it in Tomcat, and i have the following class constantly listerning to new task in the queue. But after a day or two, sudden it behaving strangely, where by the object DeliveryOK return by channel.queueDeclare(taskQueueName, isDurable, false, false, null); is always zero. (i print out this in the log below mentioning "Current poolSize").
But in Rabbit admin (./rabbitmqadmin list queues or the RabbitMq Admin portal) it always return a number greater than zero (say 1267 messages in the queue). And it will not reduce to zero until i restart the tomcat, the class below only able to detect that there are actually some messages in the queue.
Initially i thought that this class was terminated somehow, but it is able to consume those messages that newly arrive. It will not consume those 1267 messages that is left hanging inside the queue. For example messages 1267 in the queue, will not be consume until i restart tomcat.
From the code below, is it because buggy implementation or is there a better way to implement a queue consumer specifically for RabbitMQ? i have read a related stack post(Producer/Consumer threads using a Queue), but im not sure if it helps.
Also, is it true that this consumer implementation below will not survive a RunTimeException?
MqConsumer Class:
#Service
public class MqConsumer implements Runnable{
private static final Logger logger = LoggerFactory.getLogger(MqConsumer.class);
private final int MAX_ALERT_THRESHOLD = 10000;
#Autowired
private AsynchSystemConnections asynchSystemConnections;
public MqConsumer(){
}
#PostConstruct
private void init() {
(new Thread(new MqConsumer(asynchSystemConnections))).start();
}
public MqConsumer(AsynchSystemConnections asynchSystemConnections){
this.asynchSystemConnections = asynchSystemConnections;
}
#Override
public void run() {
logger.info("Execute Consumer instance...");
while (true) { // infinite loop until it die due server restart
boolean toSleep = consume(asynchSystemConnections);
if (toSleep){
logger.error("Sleeping for 1 second...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
logger.error("", e);
}
}
}
}
private boolean consume(AsynchSystemConnections asynchSystemConnections) {
com.rabbitmq.client.Connection mqConnection = null;
Channel mqChannel = null;
DatasiftMq dMq = null;
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(asynchSystemConnections.getMqServerHost());
mqConnection = factory.newConnection();
mqChannel = mqConnection.createChannel();
//consumePushInteractionJob method will forward to AsynchTwService.consume(connection, channel, AsynchTwService.PUSH_INTERACTION_QUEUE )
dMq = asynchSystemConnections.getAsynchService().consumePushInteractionJob(mqConnection, mqChannel);
int poolSize = asynchSystemConnections.getAsynchService().getPushInteractionQueueSize();
logger.info("Current poolSize: " + poolSize);
} catch(NullPointerException e) {
logger.error("", e);
if (dMq != null) {
try {
logger.error("Removing JSON with" + dMq.getLogHeader(dMq));
asynchSystemConnections.getAsynchService().ack(mqChannel, dMq.getDelivery());
logger.error("Removed JSON with" + dMq.getLogHeader(dMq));
} catch (IOException e1) {
logger.error("Remove JSON Failed: ", e);
}
}
return true;
} catch (IOException e) {
logger.error("Unable to create new MQ Connection from factory.", e);
return true;
} catch (InterruptedException e) {
logger.error("", e);
return true;
} catch (ClassNotFoundException e) {
logger.error("", e);
return true;
} catch (Exception e) {
logger.error("Big problem, better solve this fast!!", e);
asynchSystemConnections.getNotificationService().notifySystemException(null, e);
return true;
} finally {
try {
asynchSystemConnections.getAsynchService().ack(mqChannel, dMq.getDelivery());
asynchSystemConnections.getAsynchService().disconnect(mqConnection, mqChannel);
} catch (IOException e) {
logger.error("", e);
}
}
return false;
}
AsynchTwService Class:
#Service("asynchTwService")
public class AsynchTwService implements AsynchService {
static final String FAVOURITE_COUNT_QUEUE = "favourite_count_queue";
static final String FRIENDS_FOLLOWERS_QUEUE = "friends_followers_queue";
static final String DIRECT_MESSAGE_RECEIVE_QUEUE = "direct_message_receive_queue";
static final String PUSH_INTERACTION_QUEUE = "push_interaction_queue";
private static String mqServerHost;
private static final Logger logger = LoggerFactory.getLogger(AsynchTwService.class);
private static final boolean isDurable = true;
private boolean autoAck = false;
private ConcurrentHashMap<String, Integer> currentQueueSize = new ConcurrentHashMap<String, Integer>();
#Override
public Connection getConnection() throws IOException{
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(mqServerHost);
return factory.newConnection();
}
#Override
public void produce(Connection connection, Channel channel, Object object, String taskQueueName) throws IOException {
sendToQueue(connection, channel, object, taskQueueName);
}
#Override
public QueueItem consume(Connection connection, Channel channel, String taskQueueName) throws IOException, InterruptedException, ClassNotFoundException{
Serializer serializer = new Serializer();
try {
Delivery delivery = listenFromQueue(connection, channel, taskQueueName);
Object messageObj = serializer.toObject(delivery.getBody());
QueueItem queueItem = (QueueItem)messageObj;
queueItem.setDelivery(delivery);
return queueItem;
} catch (InterruptedException e) {
throw e;
} catch (ClassNotFoundException e) {
logger.error("Unable to serialize the message to QueueItem object", e);
throw e;
}
}
#Override
public int getQueueSize(String taskQueueName){
return this.currentQueueSize.get(taskQueueName);
}
private Delivery listenFromQueue(Connection connection, Channel channel, String taskQueueName) throws IOException, InterruptedException, ClassNotFoundException{
try {
DeclareOk ok = channel.queueDeclare(taskQueueName, isDurable, false, false, null);
currentQueueSize.put(taskQueueName, ok.getMessageCount());
logger.info("Queue ("+ taskQueueName + ") has items: " +ok.getMessageCount());
} catch (IOException e) {
// TODO Auto-generated catch block
}
logger.info(" [*] Consuming "+taskQueueName+" message...");
QueueingConsumer consumer = new QueueingConsumer(channel);
try {
channel.basicConsume(taskQueueName, autoAck, consumer);
} catch (IOException e) {
logger.error("", e);
}
try {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
return delivery;
} catch (ShutdownSignalException e) {
logger.error("Unable to retrieve message from Queue", e);
throw e;
} catch (ConsumerCancelledException e) {
logger.error("Unable to retrieve message from Queue", e);
throw e;
} catch (InterruptedException e) {
logger.error("Unable to retrieve message from Queue", e);
throw e;
}
}
private void sendToQueue(Connection connection, Channel channel, Object object, String taskQueueName) throws IOException{
//Initialization, create Message Queue broker connection
try{
channel.queueDeclare(taskQueueName, isDurable, false, false, null);
}catch(IOException e) {
logger.error(e.getMessage());
logger.error("Error create Message Queue connection for queue name:" + taskQueueName, e);
throw e;
}
//send message to broker
try {
long start = System.currentTimeMillis();
Serializer serializer = new Serializer();
logger.info("Sending Twitter QueueItem to Message Queue...");
channel.basicPublish("", taskQueueName, MessageProperties.PERSISTENT_TEXT_PLAIN,
serializer.toBytes(object));
logger.info("Queue successfully sent, process took: " + (System.currentTimeMillis()-start)+ "ms");
} catch (IOException e) {
logger.error("Error while sending object to queue : " + taskQueueName, e);
throw e;
}
}
public static String getMqServerHost() {
return mqServerHost;
}
public static void setMqServerHost(String mqServerHost) {
AsynchTwService.mqServerHost = mqServerHost;
}
#Override
public void disconnect(Connection connection, Channel channel) throws IOException{
try {
if (channel != null){
if (channel.isOpen()){
channel.close();
}
}
if (connection != null){
if (connection.isOpen()){
connection.close();
}
}
logger.debug("MQ Channel Disconnected");
} catch (IOException e) {
throw e;
}
}
#Override
public void ack(Channel channel, QueueingConsumer.Delivery delivery) throws IOException {
// this is made as another method call is to avoid Ack too fast un intentionally
try {
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
logger.info("[x] acked" );
} catch (IOException e) {
logger.error("Unable Acknowledge Queue Message", e);
throw e;
}
}
#Override
public DatasiftMq consumeDatasiftInteraction(Connection connection, Channel channel,
String taskQueueName) throws IOException, InterruptedException, ClassNotFoundException {
Serializer serializer = new Serializer();
try {
Delivery delivery = listenFromQueue(connection, channel, taskQueueName);
Object messageObj = serializer.toObject(delivery.getBody());
DatasiftMq dto = (DatasiftMq)messageObj;
dto.setDelivery(delivery);
return dto;
} catch (InterruptedException e) {
throw e;
} catch (ClassNotFoundException e) {
logger.error("Unable to serialize the message to DatasiftDTO object", e);
throw e;
}
}
#Override
public void reQueue(Channel channel, Delivery delivery) throws IOException {
try {
channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, true);
logger.info("[x] Nacked" );
} catch (IOException e) {
logger.error("Unable Acknowledge Queue Message", e);
throw e;
}
}
}
Seems like you are missing some basics here.
Taken from here and some code of mine.
Setting up the connection outside of the consumer thread:
//executed once
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("someHost");
factory.setUsername("user");
factory.setPassword("pass");
Connection connection = factory.newConnection();
What you have to do inside your thread:
//Consumer - executed in a Thread
QueueingConsumer consumer = new QueueingConsumer(connection.createChannel());
boolean autoAck = false;
channel.basicConsume("hello", autoAck, consumer);
while (!Thread.current().isInterrupted())) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
//...
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
In general I do still recommand you check out the spring-amqp library it integrates perfectly.
Hey how can i display every response from the xmpp server?
I try to send messages but a lot of them get lost on the way so i want to check the response of the server. I am using smack 3.3.1 sending to the facebook xmpp port.
DeliveryReceiptManager and/or MessageEventManager wont show anything so i would like to see everything the server is responding!
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222);
config.setSASLAuthenticationEnabled(true);
XMPPConnection connection = new XMPPConnection(config);
try {
//ESTA LINEA HACE QUE NO DE TIMEOUT
SmackConfiguration.setPacketReplyTimeout(15000);
XMPPConnection.DEBUG_ENABLED = true;
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
connection.connect();
String apiKey = "1234567";
String accessToken = "";
connection.login(apiKey, accessToken);
}catch (XMPPException e){
e.printStackTrace();
}
try {
DeliveryReceiptManager deliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(connection);
deliveryReceiptManager.addReceiptReceivedListener(new ReceiptReceivedListener() {
#Override
public void onReceiptReceived(String s, String s2, String s3) {
System.out.println("REVEIVED RESPONCE");
System.out.println(s);
System.out.println(s2);
System.out.println(s3);
}
});
Chat chat = connection.getChatManager().createChat("1234567890#chat.facebook.com", new MessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
if(message.getType() == Message.Type.chat)
System.out.println(chat.getParticipant() + " says: " + message.getBody());
}
});
Message msg = new Message();
msg.setSubject("Invite");
msg.setBody("blablabla");
DeliveryReceiptManager.addDeliveryReceiptRequest(msg);
//MessageEventManager.addNotificationsRequests(msg, true, true, true, true);
chat.sendMessage(msg);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}catch (XMPPException e){
e.printStackTrace();
}
try {
Thread.sleep(10000);
}catch (InterruptedException e) {
e.printStackTrace();
}
Connection.DEBUG_ENABLED = true;