Is there any way to purge IBM MQ Queue programmatically? I have few messages lying in the Queue but when I read the messages using Consumer code , the messages are still present in the queue. I am assuming there are some uncommitted messages present in queue. I do not have access to MQ explorer so I want to clear the queue programmatically. (either through JMS code or IBM MQ implementation way)
Currently my consumer has jar file com.ibm.mq-6.0.2.1.jar So I prefer to use WMQ classes rather than JMS.
Here is a fully functioning Java/MQ program called 'EmptyQ.java' that will delete all messages on a queue until the queue is empty. Note: It is one of the sample MQ/Java programs that I posted here.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import com.ibm.mq.MQException;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
/**
* Program Name:
* EmptyQ
*
* Description:
* This java class will connect to a remote queue manager with the
* MQ setting stored in a HashTable, loop to retrieve (delete) all messages from
* a queue then close and disconnect.
*
* Sample Command Line Parameters:
* bindings mode:
* -m MQA1 -q TEST.Q1
*
* client mode:
* -m MQA1 -q TEST.Q1 -h 127.0.0.1 -p 1414 -c TEST.CHL -u UserID -x Password
*
* #author Roger Lacroix
*/
public class EmptyQ
{
private static final SimpleDateFormat LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
private Hashtable<String, String> params;
private Hashtable<String, Object> mqht;
/**
* The constructor
*/
public EmptyQ()
{
super();
params = new Hashtable<String, String>();
mqht = new Hashtable<String, Object>();
}
/**
* Make sure the required parameters are present.
*
* #return true/false
*/
private boolean allParamsPresent()
{
boolean b = params.containsKey("-m") && params.containsKey("-q");
if (params.containsKey("-c"))
{
b = b && params.containsKey("-c") && params.containsKey("-h") && params.containsKey("-p");
}
if (b)
{
try
{
if (params.containsKey("-p"))
Integer.parseInt((String) params.get("-p"));
}
catch (NumberFormatException e)
{
b = false;
}
}
return b;
}
/**
* Extract the command-line parameters and initialize the MQ HashTable.
*
* #param args
* #throws IllegalArgumentException
*/
private void init(String[] args) throws IllegalArgumentException
{
int port = 1414;
if (args.length > 0 && (args.length % 2) == 0)
{
for (int i = 0; i < args.length; i += 2)
{
params.put(args[i], args[i + 1]);
}
}
else
{
throw new IllegalArgumentException();
}
if (allParamsPresent())
{
if (params.containsKey("-c"))
{
try
{
port = Integer.parseInt((String) params.get("-p"));
}
catch (NumberFormatException e)
{
port = 1414;
}
mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));
mqht.put(CMQC.PORT_PROPERTY, new Integer(port));
if (params.containsKey("-u"))
mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
if (params.containsKey("-x"))
mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));
}
// I don't want to see MQ exceptions at the console.
MQException.log = null;
}
else
{
throw new IllegalArgumentException();
}
}
/**
* Connect, open queue, loop and get all messages then close queue and
* disconnect.
*
*/
private void receive()
{
String qMgrName = (String) params.get("-m");
String inputQName = (String) params.get("-q");
MQQueueManager qMgr = null;
MQQueue queue = null;
int openOptions = CMQC.MQOO_INPUT_AS_Q_DEF + CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_ACCEPT_TRUNCATED_MSG;
MQMessage receiveMsg = null;
int msgCount = 0;
boolean getMore = true;
try
{
if (params.containsKey("-c"))
qMgr = new MQQueueManager(qMgrName, mqht);
else
qMgr = new MQQueueManager(qMgrName);
EmptyQ.logger("successfully connected to " + qMgrName);
queue = qMgr.accessQueue(inputQName, openOptions);
EmptyQ.logger("successfully opened " + inputQName);
while (getMore)
{
receiveMsg = new MQMessage();
try
{
// get the message on the queue - request only 1 byte - make it go as fast as possible.
queue.get(receiveMsg, gmo, 1);
msgCount++;
}
catch (MQException e)
{
if ( (e.completionCode == CMQC.MQCC_FAILED) &&
(e.reasonCode == CMQC.MQRC_NO_MSG_AVAILABLE) )
{
// All messages read.
getMore = false;
break;
}
else if ( (e.completionCode == CMQC.MQCC_WARNING) &&
(e.reasonCode == CMQC.MQRC_TRUNCATED_MSG_ACCEPTED) )
{
msgCount++;
}
else
{
EmptyQ.logger("MQException: " + e.getLocalizedMessage());
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
getMore = false;
break;
}
}
}
}
catch (MQException e)
{
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
}
finally
{
EmptyQ.logger("deleted " + msgCount + " messages");
try
{
if (queue != null)
{
queue.close();
EmptyQ.logger("closed: " + inputQName);
}
}
catch (MQException e)
{
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
}
try
{
if (qMgr != null)
{
qMgr.disconnect();
EmptyQ.logger("disconnected from " + qMgrName);
}
}
catch (MQException e)
{
EmptyQ.logger("CC=" + e.completionCode + " : RC=" + e.reasonCode);
}
}
}
/**
* A simple logger method
*
* #param data
*/
public static void logger(String data)
{
String className = Thread.currentThread().getStackTrace()[2].getClassName();
// Remove the package info.
if ((className != null) && (className.lastIndexOf('.') != -1))
className = className.substring(className.lastIndexOf('.') + 1);
System.out.println(LOGGER_TIMESTAMP.format(new Date()) + " " + className + ": " + Thread.currentThread().getStackTrace()[2].getMethodName() + ": " + data);
}
/**
* main line
*
* #param args
*/
public static void main(String[] args)
{
EmptyQ write = new EmptyQ();
try
{
write.init(args);
write.receive();
}
catch (IllegalArgumentException e)
{
System.err.println("Usage: java EmptyQ -m QueueManagerName -q QueueName [-h host -p port -c channel] [-u UserID] [-x Password]");
System.exit(1);
}
System.exit(0);
}
}
I implemented this in my project recently.
USING WMQ
browse the queue , consume the messages destructively from the queue.
Use CMQC.MQGMO_MSG_UNDER_CURSOR in MQMessageoptions to remove message destructively from the queue.
https://www.ibm.com/docs/en/ibm-mq/9.0?topic=java-mqc
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = CMQC.MQGMO_MSG_UNDER_CURSOR + CMQC.MQGMO_NO_WAIT
+ CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_ACCEPT_TRUNCATED_MSG;
How about something simple like this ?
import java.io.IOException;
import com.ibm.mq.MQException;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.MQConstants;
import com.ibm.msg.client.wmq.WMQConstants;
public class MQClear {
private static final String qManager = "QM1";
private static final String qName = "Q1";
public static void main(String args[]) {
try {
MQQueueManager qMgr = new MQQueueManager(qManager);
int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF;
MQQueue queue = qMgr.accessQueue(qName, openOptions);
// not great: while (queue.getCurrentDepth()>0) {
boolean hasMore = true;
while (hasMore) {
try {
MQMessage mqMsg = new MQMessage();
queue.get(mqMsg);
}
catch (MQException ex) {
hasMore = false;
if( ex.reasonCode!=2033 ) throw ex; // if this was something other than NO_MSG_AVAILABLE, rethrow
}
}
queue.close();
qMgr.disconnect();
}
catch (MQException ex) {
System.out.println("A WebSphere MQ Error occured : Completion Code " + ex.completionCode
+ " Reason Code " + ex.reasonCode);
ex.printStackTrace();
}
}
}
Related
A requester is sending messages over a normal queue to a responder, indicating a dynamic queue it created as a reply queue. The responder puts these same messages on the reply queue. The responder retrieves all messages correctly.
For each message sent the requester obtains a message from the reply queue, but its body is filled with zeroes. Both programs are written in Java, using com.ibm.mq.allclient-9.2.2.0.jar. When I wrote the same in JavaScript with Node.js and ibmmq for node, everything worked fine.
Requester.java:
package com.hellerim.imq.comm.requester;
import static com.ibm.mq.constants.CMQC.MQENC_INTEGER_NORMAL;
import static com.ibm.mq.constants.CMQC.MQFMT_STRING;
import static com.ibm.mq.constants.CMQC.MQGMO_FAIL_IF_QUIESCING;
import static com.ibm.mq.constants.CMQC.MQGMO_NO_SYNCPOINT;
import static com.ibm.mq.constants.CMQC.MQGMO_NO_WAIT;
import static com.ibm.mq.constants.CMQC.MQGMO_WAIT;
import static com.ibm.mq.constants.CMQC.MQMT_REQUEST;
import static com.ibm.mq.constants.CMQC.MQOO_FAIL_IF_QUIESCING;
import static com.ibm.mq.constants.CMQC.MQOO_INPUT_EXCLUSIVE;
import static com.ibm.mq.constants.CMQC.MQOO_OUTPUT;
import static com.ibm.mq.constants.CMQC.MQPMO_NO_SYNCPOINT;
import static com.ibm.mq.constants.CMQC.MQRC_NO_MSG_AVAILABLE;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import io.netty.util.CharsetUtil;
import net.jcip.annotations.GuardedBy;
public class Requester
{
private static final int WAIT_WHILE_EMPTY = 100; // ms
private static int MAX_MILLIS_BETWEEN_REQUESTS = 100;
private static int LONG_WIDTH_IN_HEX_CHARS = 16;
private static final Charset charset = CharsetUtil.ISO_8859_1;
private MQQueueManager qMgr;
private final MQQueue requestQueue;
private final String queueNamePattern = "TEST.SESSION.*";
private String replyQueueName;
private final MQQueue replyQueue;
private final MQGetMessageOptions getOptions = new MQGetMessageOptions();
private static final String MQ_MANAGER = "MY_QM";
private static final String REQUEST_QUEUE = "TEST.REQUESTS";
private static final String MODEL_QUEUE = "TEST.SESSION.MODEL";
final private Object locker = new Object();
#GuardedBy("this")
boolean stopped = false;
int rcvd = 0;
public static void main(String[] args) {
try {
Requester rq = new Requester(MQ_MANAGER, REQUEST_QUEUE, MODEL_QUEUE);
List<String> poem = writePoem();
Random requestIds = new Random();
Random delays = new Random(1000);
int cnt = 0;
int position = 0;
for (int i = 0; i < 50; ++i) {
if (i == poem.size()) {
int requestId = requestIds.nextInt(99999) + 1;
String text = poem.stream().collect(Collectors.joining("\n"));
String request = appRequestFrom(text, requestId);
rq.write(request);
System.out.println("Requester: sent request no " + (++cnt) + " - " + requestId);
}
position %= poem.size();
String line = poem.get(position);
int requestId = requestIds.nextInt(99999) + 1;
String request = appRequestFrom(line, requestId);
rq.write(request);
System.out.println("Requester: sent request no " + (++cnt) + " - " + requestId);
position++;
try {
Thread.sleep((long) Math.ceil((Math.pow(
delays.nextDouble(), 4) * MAX_MILLIS_BETWEEN_REQUESTS) + 1));
} catch (InterruptedException e) {
// ignore
}
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// ignore
}
rq.close();
} catch (MQException e) {
e.printStackTrace();
}
}
public Requester(String mqManagerName, String requestQueueName, String modelQueueName) throws MQException {
super();
System.out.println("Requester: establishing mq session (mq manager: " + mqManagerName +
"/ request queue: " + requestQueueName + " / model queue: " + modelQueueName +")");
qMgr = new MQQueueManager(mqManagerName);
// get request queue
int openOptions = MQOO_OUTPUT + MQOO_FAIL_IF_QUIESCING;
requestQueue = qMgr.accessQueue(requestQueueName, openOptions);
// get dynamic reply queue
int inputOptions = MQOO_INPUT_EXCLUSIVE + MQOO_FAIL_IF_QUIESCING;
replyQueue = new MQQueue(qMgr,
modelQueueName,
inputOptions,
"",
queueNamePattern,
"");
replyQueueName = replyQueue.getName();
System.out.println("Requester: created temporary reply queue " + replyQueueName);
getOptions.options = MQGMO_NO_SYNCPOINT +
MQGMO_NO_WAIT +
MQGMO_FAIL_IF_QUIESCING;
// catch-up (for those replies not retrieved after a request was put)
Executors.newSingleThreadExecutor().execute(new Runnable() {
#Override
public void run() {
// read options
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = MQGMO_NO_SYNCPOINT +
MQGMO_WAIT +
MQGMO_FAIL_IF_QUIESCING;
getOptions.waitInterval = WAIT_WHILE_EMPTY;
while(proceed()) {
try {
if (!retrieveMessage(getOptions)) {
try {
Thread.sleep(getOptions.waitInterval);
} catch (InterruptedException e1) {}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
private boolean retrieveMessage(MQGetMessageOptions getOptions) throws IOException {
MQMessage msg = new MQMessage();
try {
msg.clearMessage();
msg.seek(0);
replyQueue.get(msg, getOptions);
System.out.println("Requester: reply no " + ++rcvd + " received - id: " +
Long.parseLong(new String(msg.messageId, Charset.forName("ISO_8859_1")), 16));
byte[] buf = new byte[msg.getDataLength()];
String message = new String(buf, charset);
System.out.println("Requester: message received:\n" + message);
} catch (MQException e) {
if (e.reasonCode == MQRC_NO_MSG_AVAILABLE) {
return false;
}
}
return true;
}
public byte[] write(String message) {
int positionRequestId = 24;
int endIndex = positionRequestId + 16;
CharSequence requestId = message.substring(positionRequestId, endIndex);
StringBuffer sb = new StringBuffer("00000000");
sb.append(requestId);
byte[] id = sb.toString().getBytes(charset);
MQMessage mqMsg = new MQMessage();
mqMsg.characterSet = 819;
mqMsg.encoding = MQENC_INTEGER_NORMAL;
mqMsg.format = MQFMT_STRING;
mqMsg.messageType = MQMT_REQUEST;
mqMsg.messageId = id;
mqMsg.correlationId = id;
mqMsg.replyToQueueName = replyQueueName;
try {
mqMsg.writeString(message);
mqMsg.seek(0);
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = MQPMO_NO_SYNCPOINT;
requestQueue.put(mqMsg, pmo);
} catch (IOException e) {
e.printStackTrace();
} catch (MQException e) {
e.printStackTrace();
}
// try to read from reply queue fail immediately
try {
retrieveMessage(getOptions);
} catch (IOException e) {
e.printStackTrace();
}
return id;
}
public void close() {
stop();
try {
Thread.sleep(2 * WAIT_WHILE_EMPTY);
} catch (InterruptedException e1) {
// ignore
}
try {
if (requestQueue != null) {
requestQueue.close();
}
if (qMgr != null) {
qMgr.disconnect();
}
} catch (MQException e) {
// ignore
}
}
public boolean proceed() {
synchronized(locker) {
return !stopped;
}
}
public void stop() {
synchronized(locker) {
stopped = true;
}
}
private static List<String> writePoem() {
List<String> poem = new ArrayList<>();
poem.add("Das Nasobem");
poem.add("von Joachim Ringelnatz");
poem.add("");
poem.add("Auf seiner Nase schreitet");
poem.add("einher das Nasobem,");
poem.add("von seineme Kind begleitet -");
poem.add("es steht noch nicht im Brehm.");
poem.add("");
poem.add("Es steht noch nicht im Meyer");
poem.add("und auch im Brockhaus nicht -");
poem.add("es tritt aus meiner Leier");
poem.add("zum ersten Mal ans Licht.");
poem.add("");
poem.add("Auf seiner Nase schreitet");
poem.add("- wie schon gesagt - seitdem");
poem.add("von seinem Kind begleitet");
poem.add("einher das Nasobem.");
poem.add("");
poem.add("");
return poem;
}
private static String iToHex(int num, int places) {
StringBuilder sb = new StringBuilder();
char[] digits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
for (int i = 0; i < places; ++i) {
sb.append(digits[num % places]);
num /= places;
}
return sb.reverse().toString();
}
private static String iToHex(int num) {
return iToHex(num, LONG_WIDTH_IN_HEX_CHARS);
}
private static String appRequestFrom(String msgBody, int requestId) {
int headerLength = 72;
// includes message body length field here!
int bodyLength = msgBody.length();
StringBuilder sb = new StringBuilder();
sb.append("GHI "); // magic
sb.append("1"); // version major
sb.append("0"); // version minor
sb.append("0"); // flags
sb.append("1"); // app message type SYNCHRONOUS REQUEST
sb.append(iToHex(headerLength + bodyLength)); // message length
sb.append(iToHex(requestId)); // request id
sb.append(iToHex(0)); // timeout
sb.append(iToHex(bodyLength)); // message body length
sb.append(msgBody); // message body
return sb.toString();
}
}
Responder.java:
package com.hellerim.imq.comm.responder;
import static com.ibm.mq.constants.CMQC.*;
import java.io.EOFException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import io.netty.util.CharsetUtil;
import net.jcip.annotations.GuardedBy;
public class Responder
{
private MQQueueManager qMgr;
private MQQueue requestQueue;
private Map<String, MQQueue> replyQueues = new HashMap<>();
private final Object locker = new Object();
static final private int WAIT_WHILE_EMPTY = 100; // ms
#GuardedBy("locker")
private boolean stopped = false;
Thread fetcherThread = null;
private final static byte MESSAGE_TYPE_REPLY = 52; // '4'
public final static String MQ_MANAGER = "MY_QM";
public final static String REQUEST_QUEUE = "TEST.REQUESTS";
public static void main( String[] args ) throws MQException, IOException
{
System.out.println( "running reponder application" );
try {
new Responder(MQ_MANAGER, REQUEST_QUEUE).start();
} catch(Exception e) {
e.printStackTrace();
}
}
public Responder(String mqManagerName, String requestQueueName) throws MQException {
System.out.println("establishing mq session (mq manager: " + mqManagerName +
" / request queue: " + requestQueueName + ")");
qMgr = new MQQueueManager(mqManagerName);
int openOptions = MQOO_INPUT_SHARED + MQOO_FAIL_IF_QUIESCING;
requestQueue = qMgr.accessQueue(requestQueueName, openOptions);
}
public MQQueue getReplyQueue(String replyQueueName) throws MQException {
if (replyQueues.containsKey(replyQueueName)) {
return replyQueues.get(replyQueueName);
}
int openOptions = MQOO_OUTPUT + MQOO_FAIL_IF_QUIESCING;
MQQueue replyQueue = qMgr.accessQueue(replyQueueName, openOptions);
replyQueues.put(replyQueueName, replyQueue);
System.out.println("Responder: opened dynamic reply queue");
return replyQueue;
}
private void start() throws IOException {
Runnable fetcher = new Runnable() {
#Override
public void run() {
int cnt = 0;
while(proceed()) {
MQMessage msg = new MQMessage();
try {
//msg.clearMessage();
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = MQGMO_NO_SYNCPOINT +
MQGMO_WAIT +
MQGMO_FAIL_IF_QUIESCING;
getOptions.waitInterval = WAIT_WHILE_EMPTY;
requestQueue.get(msg, getOptions);
System.out.println("Responder: message no " + ++cnt + " received");
MQQueue replyQueue = null;
try {
replyQueue = getReplyQueue(msg.replyToQueueName);
} catch(MQException e) {
if (e.completionCode == MQCC_FAILED && e.reasonCode == MQRC_UNKNOWN_OBJECT_NAME) {
// dynamic reply queue does not exist any more => message out of date
continue;
}
throw e;
}
// set message type for reply
if (msg.getDataLength() < 56) {
System.out.println("invalid message:");
System.out.println(Msg2Text(msg));
continue;
}
System.out.println(Msg2Text(msg));
int typePosition = 7;
msg.seek(typePosition);
msg.writeByte(MESSAGE_TYPE_REPLY);
msg.seek(0);
String text = Msg2Text(msg);
MQMessage msgOut = new MQMessage();
msgOut.characterSet = 819;
msgOut.encoding = MQENC_INTEGER_NORMAL;
msgOut.format = MQFMT_STRING;
msgOut.messageType = MQMT_REPLY;
msgOut.messageId = msg.messageId;
msgOut.correlationId = msg.correlationId;
msgOut.seek(0);
msgOut.writeString(text);
msgOut.seek(0);
System.out.println(text);
// System.out.println("Responder: message received");
MQPutMessageOptions pmo = new MQPutMessageOptions(); // accept the defaults, same
pmo.options = MQPMO_NO_SYNCPOINT;
replyQueue.put(msgOut, pmo);
System.out.println("Responder: message no " + cnt + " returned");
} catch (MQException e) {
if (e.reasonCode == MQRC_NO_MSG_AVAILABLE) {
; // NOOP
} else {
try {
msg.seek(0);
System.out.println(msg);
} catch (EOFException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
e.printStackTrace();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {}
}
} catch (IOException e) {
e.printStackTrace();
}
}
shutdown();
}
};
Thread task = new Thread(fetcher);
task.run();
System.out.print("press <ENTER> to terminate ");
System.in.read();
System.out.println();
synchronized(locker) {
stopped = true;
}
try {
task.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static String Msg2Text(MQMessage msg) {
int length;
String text = "";
try {
length = msg.getDataLength();
byte[] buf = new byte[length];
msg.seek(0);
msg.readFully(buf);
text = new String(buf, CharsetUtil.ISO_8859_1);
msg.seek(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return text;
}
private boolean proceed() {
synchronized(locker) {
return !stopped;
}
}
private void shutdown() {
System.out.print("\nshutting down responder... ");
for (MQQueue queue : replyQueues.values()) {
try {
queue.close();
} catch (MQException e) { }
}
replyQueues.clear();
try {
qMgr.close();
} catch (MQException e) { }
System.out.println("done.");
}
}
Is there any idea what might be wrong?
It looks like you have created a buffer the right size for the message data and printed that, without moving the data into it.
In retrieveMessage:
byte[] buf = new byte[msg.getDataLength()];
String message = new String(buf, charset);
System.out.println("Requester: message received:\n" + message);
You might need to call the readFully (or similar) method to get the data.
If you know that your message payload is text (string) then you can do this:
String msgStr = msg.readStringOfByteLength(msg.getMessageLength());
System.out.println("Requester: message received:\n" + msgStr);
I'm using a java server to facilitate online multiplayer in my game made with GameMaker Studio, the players will send data to the java server which will process the data and send it to the players. The problem is that when a player with a slow internet connection is not being able to handle the amount of data being send to it, it will cause the server to freeze for all players (the server will no longer process any data send by other players).
I have simulated slow internet speeds by using NetLimiter and setting the download speed of one laptop at 5 kb/s, while maintaining proper speed at other laptops. I have tried to send ACK packets from the java server to the client and if it doesn't respond in 1 second no more data will be send to that client (and eventually the client will be kicked). This has reduced the chance of freezing the server, but it will still happen occasionally.
Main.java
import java.net.Socket;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.io.IOException;
import java.util.HashMap;
import java.net.ServerSocket;
import java.net.SocketTimeoutException;
public class Main
{
static ServerSocket serverSocket_;
static HashMap<String, ServerInformation> servers_;
static int verboseLevel_;
static int threadTimeout_;
static int masterPort_;
static int serverNumber_;
static int socketTimeOut_;
static {
Main.serverSocket_ = null;
Main.servers_ = new HashMap<String, ServerInformation>();
Main.verboseLevel_ = 5;
Main.threadTimeout_ = 10;
Main.masterPort_ = 6510;
Main.serverNumber_ = 1;
Main.socketTimeOut_ = 6000;
}
public static void main(final String[] args) {
try {
setupServerAndCleanup(Main.masterPort_);
while (true) {
handleIncomingConnection();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
static void setupServerAndCleanup(final int port) throws IOException {
(Main.serverSocket_ = new ServerSocket()).setReuseAddress(true);
Main.serverSocket_.bind(new InetSocketAddress(Main.masterPort_));
System.out.println("Server socket up and running on port " + Main.masterPort_);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
if (Main.serverSocket_ != null) {
try {
Main.serverSocket_.close();
System.out.println("Server socket closed, port released");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}));
}
static void handleIncomingConnection() throws IOException {
final Socket clientSocket = Main.serverSocket_.accept();
clientSocket.setSoTimeout(Main.socketTimeOut_);
final ClientThread client = new ClientThread(clientSocket);
client.start();
}
}
ClientThread.java
Case 1 is the part dealing with sending data to the clients, in particular this line:
thread2.out_.print(msg);
If more data is being send than one client can handle the server will freeze for all other clients as well.
import java.util.Iterator;
import java.io.IOException;
import java.io.Reader;
import java.io.InputStreamReader;
import java.util.regex.Pattern;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class ClientThread extends Thread
{
Socket clientSocket_;
String clientIp_;
String serverIp_;
ServerInformation server_;
PrintWriter out_;
BufferedReader in_;
boolean prepareTermination_;
boolean terminated_;
private static final Pattern numberPattern;
static {
numberPattern = Pattern.compile("\\d+");
}
public ClientThread(final Socket sock) {
this.clientSocket_ = sock;
this.clientIp_ = this.clientSocket_.getRemoteSocketAddress().toString();
this.serverIp_ = null;
this.server_ = null;
this.prepareTermination_ = false;
this.terminated_ = false;
}
#Override
public void run() {
try {
this.out_ = new PrintWriter(this.clientSocket_.getOutputStream(), true);
this.in_ = new BufferedReader(new InputStreamReader(this.clientSocket_.getInputStream()));
long lastActionTime = System.currentTimeMillis();
while (true) {
if (this.in_.ready() || System.currentTimeMillis() - lastActionTime >= 1000 * Main.threadTimeout_) {
if (System.currentTimeMillis() - lastActionTime >= 1000 * Main.threadTimeout_) {
//this.logDebugMessage(3, "Thread was killed due to prolonged inactivity (" + Main.threadTimeout_ + " seconds)");
this.terminateThread();
return;
}
final String tempInputLine;
if(((tempInputLine = this.in_.readLine()) == null )){
this.terminateThread(); //end thread
return;
}
else
{
lastActionTime = System.currentTimeMillis();
final String inputLine = tempInputLine.trim();
if (ClientThread.numberPattern.matcher(inputLine).matches()){
final int val = Integer.parseInt(inputLine);
switch (val) {
case 1: { //send data to other players
final int parseCount = Integer.parseInt(this.in_.readLine().trim());
final StringBuilder msg = new StringBuilder();
for (int j = 0; j < parseCount; ++j) {
msg.append(String.valueOf(this.in_.readLine().trim()) + "|");
}
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
if (thread2 != this) {
thread2.out_.print(msg);
thread2.out_.flush();
}
}
//this.logDebugMessage(5, "Packet for others: '" + msg.toString() + "'");
break;
}
case 2: { //remove game server
//this.logDebugMessage(1, "A game server has been deleted, ip: " + ipServer);
Main.servers_.remove(this.server_.ip_);
this.serverIp_ = null;
for (final ClientThread thread : this.server_.ipToClientThread_.values()) {
thread.prepareTermination_ = true;
}
this.terminateThread();
return;
}
case 3: { //connect new client
final String ipServer = this.in_.readLine().trim();
final String ipClient = this.in_.readLine().trim();
this.logDebugMessage(1, "A client wishes to connect to a server, client: " + ipClient + ", server: " + ipServer);
final ServerInformation info = Main.servers_.getOrDefault(ipServer, null);
if (info == null) {
System.out.println("Connection to the server failed, no such server in the server list");
this.out_.print("*" + 1 + "|" + 1 + "~" + "|");
this.out_.flush();
break;
}
this.server_ = info;
this.server_.ipToClientThread_.put(ipClient, this);
this.logDebugMessage(1, "Connection success");
this.logDebugMessage(5,"Map: " + this.server_.ipToClientThread_);
this.out_.print("*" + 1 + "|" + 2 + "~" + "|");
this.out_.flush();
break;
}
case 4: { //disconnect client
final String ipClient = this.in_.readLine().trim();
this.server_.ipToClientThread_.remove(ipClient);
this.logDebugMessage(1, String.valueOf(ipClient) + " disconnected from the server at " + this.server_.ip_);
this.serverIp_ = null;
this.terminateThread();
return;
}
case 5: { //host create new game
if (Main.serverNumber_ > 1000000) {
Main.serverNumber_ = 10;
}
Main.serverNumber_ += 1;
final String ipServer = Integer.toString(Main.serverNumber_); //unique server number
final String ipHost = this.in_.readLine().trim(); //host
final String name = this.in_.readLine().trim(); //Server name
final String description = this.in_.readLine().trim(); //class
final String servervar1 = this.in_.readLine().trim(); //max players
final String servervar3 = this.in_.readLine().trim(); //current lap
final String servervar4 = this.in_.readLine().trim(); //total laps
final String servervar5 = this.in_.readLine().trim(); //status
final String servervar6 = this.in_.readLine().trim(); //Password
final String servervar7 = this.in_.readLine().trim(); //Online version
final String servervar8 = this.in_.readLine().trim(); //Game server
final long servervar9 = System.currentTimeMillis(); //server creation time
//this.logDebugMessage(1, "A game server has been registered, ip: " + ipServer + ", name: " + name + ", description: " + description + ", servervar1: " + servervar1);
final ServerInformation gameServer = new ServerInformation(name, servervar1, servervar3, servervar4, servervar5, servervar6, servervar7, servervar8, servervar9, ipHost, ipServer, this.clientSocket_, this.out_, this.in_);
gameServer.description_ = description;
gameServer.ipToClientThread_.put(ipHost, this);
this.server_ = gameServer;
Main.servers_.put(ipServer, gameServer);
this.serverIp_ = ipServer;
break;
}
default: {
this.logDebugMessage(0, "Unrecognized case: '" + inputLine + "', " + val);
break;
}
}
}
else if (inputLine.length() > 0) {
this.logDebugMessage(0, "Unformated '" + inputLine + "'");
if (this.server_ != null) {
this.server_.out_.print(inputLine);
this.server_.out_.flush();
}
}
if (this.prepareTermination_) {
this.terminateThread();
return;
}
continue;
}
}
}
}
catch (SocketTimeoutException e) {
e.printStackTrace();
try {
this.terminateThread();
}
catch (IOException e2) {
e2.printStackTrace();
}
}
catch (IOException e3) {
e3.printStackTrace();
try {
this.terminateThread();
}
catch (IOException e4) {
e4.printStackTrace();
}
}
}
//debug messages
void logDebugMessage(final int requiredVerbose, final String msg) {
if (Main.verboseLevel_ >= requiredVerbose) {
System.out.println("[" + this.clientIp_ + "] " + msg);
}
}
//terminate thread
void terminateThread() throws IOException {
if (!this.terminated_) {
if (this.serverIp_ != null) {
Main.servers_.remove(this.serverIp_);
}
this.clientSocket_.close();
this.in_.close();
this.out_.close();
this.logDebugMessage(3, "Cleanup successful");
this.terminated_ = true;
}
}
}
How to avoid the server from freezing if more data is being send to a client than it can handle, so that the server can continue sending data to the other clients?
Edit
So I have tried using ExecutorService, but I must be doing something completely wrong because no data is being send by the java server.
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
if (thread2 != this) {
executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
thread2.out_.print(msg);
thread2.out_.flush();
}
});
executorService.shutdown();
}
}
It would be great if you could show me how to implement ExecutorService the right way.
If a delay in the client processing doesn't matter, this part should be done in a distinct flow execution for each client :
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
thread2.out_.print(msg);
thread2.out_.flush();
}
For example :
for (final ClientThread thread2 : this.server_.ipToClientThread_.values()) {
if (thread2 != this) {
new Thread(()-> {
thread2.out_.print(msg);
thread2.out_.flush();
})
.start();
}
}
Note that creating Threads has a cost. Using ExecutorService could be a better idea.
I am trying to perform actions in ES, so far I believe that I was able established connection correctly using Jest(http request) and now I am trying to create a new topic and post some information so it will be visible throw the elasticsearch head plugin, I run my code I dont receive any Exception but nothing happens as well,
public class ElasticSearch {
private String ES_HOST = "localhost";
private String ES_PORT = "9200";
private static JestClient jestClient = null;
public JestClient getElasticSearchClient() {
return jestClient;
}
public void connectToElasticSearch() {
try {
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(
new HttpClientConfig.Builder("http://" + ES_HOST + ":" + ES_PORT)
.multiThreaded(true)
// //Per default this implementation will create no more than 2 concurrent
// connections per given route
// .defaultMaxTotalConnectionPerRoute(<YOUR_DESIRED_LEVEL_OF_CONCURRENCY_PER_ROUTE>)
// // and no more 20 connections in total
// .maxTotalConnection(<YOUR_DESIRED_LEVEL_OF_CONCURRENCY_TOTAL>)
.build());
jestClient = factory.getObject();
} catch (Exception e) {
e.printStackTrace();
}
}
public void createIndex(String indexName, String indexType) throws IOException {
// jestClient.execute(new CreateIndex.Builder(indexName).build());
PutMapping putMapping = new PutMapping.Builder(
indexName,
indexType,
"{ \"my_type\" : { \"properties\" : { \"message\" : {\"type\" : \"string\", \"store\" : \"yes\"} } } }"
).build();
jestClient.execute(putMapping);
}
public void postInES() throws IOException {
String source = jsonBuilder()
.startObject()
.field("user", "kimchy")
.field("postDate", "date")
.field("message", "trying out Elastic Search")
.endObject().string();
}
public static void main(String[] args) throws IOException {
ElasticSearch es = new ElasticSearch();
es.connectToElasticSearch();
es.getElasticSearchClient();
es.createIndex("ES TEST", "TEST");
es.postInES();
}
I am using:
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.2.4</version>
</dependency>`enter code here`
I will appreciate your help
thanks
Thanks.
I found few problems in my code above and I was able to fix it, first when using java the port has to be 9300 and not 9200, I actually changed my entire code and decided to use TransportClient instead of JestClient which helped me. in case anyone else needs or had a similar problem I will share my code here hope it will help others
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Map;
/**
* #author YoavT #Date 6/26/2018 #Time 9:20 AM
*/
public class ElasticSearch{
private String ES_HOST = "localhost";
private int ES_PORT = 9300;
private TransportClient client = null;
protected boolean connectToElasticSearch(String clusterName) {
boolean flag = false;
try {
Settings settings =
Settings.builder()
.put("cluster.name", clusterName)
.put("client.transport.ignore_cluster_name", true)
.put("client.transport.sniff", true)
.build();
// create connection
client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new TransportAddress(InetAddress.getByName(ES_HOST), ES_PORT));
System.out.println(
"Connection " + clusterName + "#" + ES_HOST + ":" + ES_PORT + " established!");
flag = true;
} catch (Exception e) {
e.printStackTrace();
flag = false;
}
return flag;
}
/**
* Check the health status of the cluster
*/
public boolean isClusterHealthy(String clusterName) {
connectToElasticSearch(clusterName);
final ClusterHealthResponse response =
client
.admin()
.cluster()
.prepareHealth()
.setWaitForGreenStatus()
.setTimeout(TimeValue.timeValueSeconds(2))
.execute()
.actionGet();
if (response.isTimedOut()) {
System.out.println("The cluster is unhealthy: " + response.getStatus());
return false;
}
System.out.println("The cluster is healthy: " + response.getStatus());
return true;
}
/**
* Previous step is (check if cluster is healthy) The cluster is ready now and we can start with
* creating an index. Before that, we check that the same index was not created previously.
*/
public boolean isIndexRegistered(String indexName, String clusterName) {
connectToElasticSearch(clusterName);
// check if index already exists
final IndicesExistsResponse ieResponse =
client.admin().indices().prepareExists(indexName).get(TimeValue.timeValueSeconds(1));
// index not there
if (!ieResponse.isExists()) {
return false;
}
System.out.println("Index already created!");
return true;
}
/**
* If the index does not exist already, we create the index. *
*/
public boolean createIndex(String indexName, String numberOfShards, String numberOfReplicas, String clusterName) {
connectToElasticSearch(clusterName);
try {
CreateIndexResponse createIndexResponse =
client
.admin()
.indices()
.prepareCreate(indexName.toLowerCase())
.setSettings(
Settings.builder()
.put("index.number_of_shards", numberOfShards)
.put("index.number_of_replicas", numberOfReplicas))
.get();
if (createIndexResponse.isAcknowledged()) {
System.out.println(
"Created Index with "
+ numberOfShards
+ " Shard(s) and "
+ numberOfReplicas
+ " Replica(s)!");
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static void main(String[] args) throws IOException {
ElasticSearch elasticSearch = new ElasticSearch();
elasticSearch.connectToElasticSearch("elasticsearch");
boolean isHealthy = elasticSearch.isClusterHealthy("elasticsearch");
System.out.println("is cluster healthy= " + isHealthy);
boolean isIndexExsist = elasticSearch.isIndexRegistered("Test", "elasticsearch");
System.out.println("is index exsist = " + isIndexExsist);
boolean createIndex = elasticSearch.createIndex("TestIndex", "3", "1", "elasticsearch");
System.out.println("Is index created = " + createIndex);
boolean bulkInsert = elasticSearch.bulkInsert("TestIndex", "Json", "elasticsearch");
System.out.println("Bulk insert = " + bulkInsert);
long deleteBulk = elasticSearch.deleteBulk("TestIndex", "name", "Mark Twain", "elasticsearch");
System.out.println("Delete bulk = " + deleteBulk);
}
/**
* We basically want to index a JSON array consisting of objects with the properties name and age. We use a bulk insert to insert all the data at once.
* In our tests it happened that the cluster health status was not ready when we tried to run a search/delete query directly after the insert. Consequently,
* we added the setRefreshPolicy( RefreshPolicy.IMMEDIATE ) method to signalize the server to refresh the index after the specified request.
* The data can now be queried directly after.
*
* #param indexName
* #param indexType
* #return
* #throws IOException
*/
public boolean bulkInsert(String indexName, String indexType, String clusterName) throws IOException {
connectToElasticSearch(clusterName);
boolean flag = true;
BulkRequestBuilder bulkRequest = client.prepareBulk();
// for (int i = 0; i < listOfParametersForInsertion.length; i++) {
bulkRequest
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.add(
client
.prepareIndex(indexName, indexType, null)
.setSource(
XContentFactory.jsonBuilder()
.startObject()
.field("name", "Mark Twain")
.field("age", 75)
.endObject()));
// }
BulkResponse bulkResponse = bulkRequest.get();
if (bulkResponse.hasFailures()) {
// process failures by iterating through each bulk response item
System.out.println("Bulk insert failed!");
flag = false;
}
return flag;
}
/**
* After successfully querying data, we try to delete documents using a key-value pair to get
* deeper into the Elasticsearch behavior.
*/
public long deleteBulk(String indexName, String key, String value, String clusterName) {
connectToElasticSearch(clusterName);
BulkByScrollResponse response =
DeleteByQueryAction.INSTANCE
.newRequestBuilder(client)
.filter(QueryBuilders.matchQuery(key, value))
.source(indexName)
.refresh(true)
.get();
System.out.println("Deleted " + response.getDeleted() + " element(s)!");
return response.getDeleted();
}
/**
* To query the data, we use a SearchResponse in combination with a scroll. A scroll is basically
* the Elasticsearch counterpart to a cursor in a traditional SQL database. Using that sort of
* query is quite an overkill for our example and just for demonstration purposes. It is rather
* used to query large amounts of data (not like five documents in our case) and not intended for
* real-time user requests.
*
* #param indexName
* #param from
* #param to
*/
public void queryResultsWithFilter(String indexName, int from, int to, String clusterName, String filterField) {
connectToElasticSearch(clusterName);
SearchResponse scrollResp =
client
.prepareSearch(indexName)
// sort order
.addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)
// keep results for 60 seconds
.setScroll(new TimeValue(60000))
// filter for age
.setPostFilter(QueryBuilders.rangeQuery(filterField).from(from).to(to))
// maximum of 100 hits will be returned for each scroll
.setSize(100)
.get();
// scroll until no hits are returned
do {
int count = 1;
for (SearchHit hit : scrollResp.getHits().getHits()) {
Map<String, Object> res = hit.getSourceAsMap();
// print results
for (Map.Entry<String, Object> entry : res.entrySet()) {
System.out.println("[" + count + "] " + entry.getKey() + " --> " + entry.getValue());
}
count++;
}
scrollResp =
client
.prepareSearchScroll(scrollResp.getScrollId())
.setScroll(new TimeValue(60000))
.execute()
.actionGet();
// zero hits mark the end of the scroll and the while loop.
} while (scrollResp.getHits().getHits().length != 0);
}
}
In my application,i have activeMq to send the message from client to server and vice versa.I run it as a standalone server.So when a client machine sends the message,the messages are passed in the activeMq queue and then retrieve by the server(my Application) if and only if the transaction is done locally,meaning the client machine and server(my application) live in the same computer. But when i run the client and server from two different computer meaning server in one and client in another then the client can only establish connection to the server but the messages are not passed to the activeMq queue.I think this is something with activeMq problem.
can anyone tell me how to solve this?
thanks
here is the code which passes the data sent by client to the queue.
package event.activeMq;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.console.command.store.amq.CommandLineSupport;
import org.apache.activemq.util.IndentPrinter;
public class ProducerTool extends Thread {
private Destination destination;
private int messageCount = 1;
private long sleepTime;
private boolean verbose = true;
private int messageSize = 1000;
private static int parallelThreads = 1;
private long timeToLive;
private String user = ActiveMQConnection.DEFAULT_USER;
private String password = ActiveMQConnection.DEFAULT_PASSWORD;
private String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private String subject = "CLOUDD.DEFAULT";
private boolean topic;
private boolean transacted;
private boolean persistent;
private static Object lockResults = new Object();
private static String DateTime="";
private static String TaskID="";
private static String UniqueEventID="";
private static String Generator="";
private static String GeneratorBuildVsn="";
private static String Severity="";
private static String EventText="";
private static String SubsystemID="";
private static String EventNumber="";
private static String atmId="";
public void element(String[] element) {
this.DateTime = element[0];
this.TaskID = element[1];
this.Generator = element[2];
this.Severity = element[3];
this.EventText = element[4];
this.SubsystemID = element[5];
this.EventNumber = element[6];
this.GeneratorBuildVsn = element[7];
this.UniqueEventID = element[8];
this.atmId = element[9];
}
public static void main(String[] args) {
System.out.println("came here");
ArrayList<ProducerTool> threads = new ArrayList();
ProducerTool producerTool = new ProducerTool();
producerTool.element(args);
producerTool.showParameters();
for (int threadCount = 1; threadCount <= parallelThreads; threadCount++) {
producerTool = new ProducerTool();
CommandLineSupport.setOptions(producerTool, args);
producerTool.start();
threads.add(producerTool);
}
while (true) {
Iterator<ProducerTool> itr = threads.iterator();
int running = 0;
while (itr.hasNext()) {
ProducerTool thread = itr.next();
if (thread.isAlive()) {
running++;
}
}
if (running <= 0) {
System.out.println("All threads completed their work");
break;
}
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
public void showParameters() {
System.out.println("Connecting to URL: " + url);
System.out.println("Publishing a Message with size " + messageSize + " to " + (topic ? "topic" : "queue") + ": " + subject);
System.out.println("Using " + (persistent ? "persistent" : "non-persistent") + " messages");
System.out.println("Sleeping between publish " + sleepTime + " ms");
System.out.println("Running " + parallelThreads + " parallel threads");
if (timeToLive != 0) {
// System.out.println("Messages time to live " + timeToLive + " ms");
}
}
public void run() {
Connection connection = null;
try {
// Create the connection.
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
connection = connectionFactory.createConnection();
connection.start();
// Create the session
Session session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
if (topic) {
destination = session.createTopic(subject);
} else {
destination = session.createQueue(subject);
}
// Create the producer.
MessageProducer producer = session.createProducer(destination);
if (persistent) {
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
} else {
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
}
if (timeToLive != 0) {
producer.setTimeToLive(timeToLive);
}
// Start sending messages
sendLoop(session, producer);
// System.out.println("[" + this.getName() + "] Done.");
synchronized (lockResults) {
ActiveMQConnection c = (ActiveMQConnection) connection;
// System.out.println("[" + this.getName() + "] Results:\n");
c.getConnectionStats().dump(new IndentPrinter());
}
} catch (Exception e) {
// System.out.println("[" + this.getName() + "] Caught: " + e);
e.printStackTrace();
} finally {
try {
connection.close();
} catch (Throwable ignore) {
}
}
}
protected void sendLoop(Session session, MessageProducer producer) throws Exception {
for (int i = 0; i < messageCount || messageCount == 0; i++) {
TextMessage message = session.createTextMessage(createMessageText(i));
if (verbose) {
String msg = message.getText();
if (msg.length() > 50) {
msg = msg.substring(0, 50) + "...";
}
// System.out.println("[" + this.getName() + "] Sending message: '" + msg + "'");
}
producer.send(message);
if (transacted) {
// System.out.println("[" + this.getName() + "] Committing " + messageCount + " messages");
session.commit();
}
Thread.sleep(sleepTime);
}
}
private String createMessageText(int index) {
StringBuffer buffer = new StringBuffer(messageSize);
buffer.append("DateTime "+DateTime+" EventNumber "+EventNumber+" TaskID "+TaskID+" AtmId "+atmId+
" Generator "+Generator+" GeneratorBuildVsn "+GeneratorBuildVsn+" Severity "+Severity+
" UniqueEventID "+UniqueEventID+" EventText "+EventText+" SubsystemID "+SubsystemID+" End ");
if (buffer.length() > messageSize) {
return buffer.substring(0, messageSize);
}
for (int i = buffer.length(); i < messageSize; i++) {
buffer.append(' ');
}
DateTime="";
EventNumber="";
TaskID="";
atmId="";
Generator="";
GeneratorBuildVsn="";
Severity="";
UniqueEventID="";
EventText="";
SubsystemID="";
return buffer.toString();
}
public void setPersistent(boolean durable) {
this.persistent = durable;
}
public void setMessageCount(int messageCount) {
this.messageCount = messageCount;
}
public void setMessageSize(int messageSize) {
this.messageSize = messageSize;
}
public void setPassword(String pwd) {
this.password = pwd;
}
public void setSleepTime(long sleepTime) {
this.sleepTime = sleepTime;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setTimeToLive(long timeToLive) {
this.timeToLive = timeToLive;
}
public void setParallelThreads(int parallelThreads) {
if (parallelThreads < 1) {
parallelThreads = 1;
}
this.parallelThreads = parallelThreads;
}
public void setTopic(boolean topic) {
this.topic = topic;
}
public void setQueue(boolean queue) {
this.topic = !queue;
}
public void setTransacted(boolean transacted) {
this.transacted = transacted;
}
public void setUrl(String url) {
this.url = url;
}
public void setUser(String user) {
this.user = user;
}
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
}
you need to update your questin with answers on this questions:
What os do you use?
Do you have a firewall like software on pc?
Could you provide here ActiveMQ conf file?
Could you provide a function
which implemented connection establishment?
upd:
I do't understand all your logic but i thk bug here:
try {
Thread.sleep(1000);
} catch (Exception e){
e.printStackTrace();
}
And never never never catch all exceptions! it's very dangerous.
if you want to catch exception, you need to handle it.
I'm trying to monitor temperature from a remote device using a TC65 modem. To request, 'C' has to be sent with a carriage return at the end. The problem is, I only get this on my phone: "This is test sms. The current temperature is " without the temperature I requested. I tried communicating with the thermostat using HyperTeminal without a problem.
Could you help me with instream.read? The output is double (accurate by two decimals).
Here's my code. Thanks.
package example.rs232demo;
import javax.microedition.midlet.*;
import java.io.*;
import javax.microedition.io.*;
import com.siemens.icm.io.*;
public class RS232Demo extends MIDlet {
CommConnection commConn;
InputStream inStream;
OutputStream outStream;
private ATCommand ATC;
public static String phone = "+97455781868";
public static String message = "This is test sms.";
/**
* RS232Demo - default constructor
*/
public RS232Demo() {
//System.out.println("RS232Demo: Constructor");
//System.out.println("Available COM-Ports: " + System.getProperty("microedition.commports"));
try {
//String strCOM = "comm:com0;blocking=on;baudrate=115200";
String strCOM = "comm:com0;blocking=on;baudrate=9600;bitsperchar=7;parity=even";
commConn = (CommConnection)Connector.open(strCOM);
//System.out.println("CommConnection(" + strCOM + ") opened");
//System.out.println("Real baud rate: " + commConn.getBaudRate());
inStream = commConn.openInputStream();
outStream = commConn.openOutputStream();
//System.out.println("InputStream and OutputStream opened");
} catch(IOException e) {
//System.out.println(e);
notifyDestroyed();
}
}
/**
* startApp()
*/
public void startApp() throws MIDletStateChangeException {
int ch = 0;
//System.out.println("RS232Demo: startApp");
//System.out.println("Looping back received data, leave with 'Q'...");
try {
outStream.write('C');
outStream.write('\r');
ch = inStream.read();
} catch(IOException e) {
//System.out.println(e);
}
try
{
this.ATC = new ATCommand(false);
}
catch (ATCommandFailedException ex)
{
ex.printStackTrace();
}
send_Simple_SMS(phone, message, ch);
try
{
this.ATC.release();
}
catch(ATCommandFailedException ex)
{
ex.printStackTrace();
}
destroyApp(true);
}
public void pauseApp() {
//System.out.println("RS232Demo: pauseApp()");
}
public int send_Simple_SMS(String phone, String message, int ch)
{
int res = -1;
String AT = "";
String response = "";
synchronized (System.out)
{
}
if(ATC==null){return res;}
try
{
synchronized (ATC)
{
ATC.send("AT+CMGF=1\r");
ATC.send("AT+IFC=1,1\r");
response = "";
response = ATC.send("AT+CMGS=?\r");
if (response.trim().indexOf("OK") < 0)
{
return res;
}
response = ATC.send("AT+CMGS=" + phone + '\r' + '\n');
//System.out.println("Sending.");
response = ATC.send(message + "The current temperature is " + (char)ch + '\032');
//System.out.println("Sent.");
if (response.trim().indexOf("OK") >= 0)
{
res = 0;
}
ATC.notifyAll();
}
}
catch (ATCommandFailedException ex)
{
ex.printStackTrace();
res = -1;
}
return res;
}
public void destroyApp(boolean cond) {
//System.out.println("RS232Demo: destroyApp(" + cond + ")");
try {
inStream.close();
outStream.close();
commConn.close();
//System.out.println("Streams and connection closed");
} catch(IOException e) {
//System.out.println(e);
}
notifyDestroyed();
}
}
Problem is here:
response = ATC.send(message + "The current temperature is " + (char)ch + '\032');
It converts ch to corrensponding character, not to number string.
Try the following:
response = ATC.send(message + "The current temperature is " + ch + '\032');