# Here is my settings.cfg file:
# Thank you.Here is what i tried.My settings.cfg file
[DEFAULT]
# Settings which apply to all the Sessions.
ConnectionType=initiator
LogonTimeout=30
ReconnectInterval=20
ResetOnLogon=Y
FileLogPath=C:\Work\QuickFIXJ\logs
FileStorePath=C:\Work\QuickFIXJ\logs
[SESSION]
# Settings specifically for one session
BeginString=FIX.4.4
SenderCompID=XYZ
TargetCompID=TYZ
TimeZone=Asia/Tokyo
StartTime=16:00:00
EndTime=13:30:00
HeartBtInt=60
SocketConnectPort=7200
SocketConnectHost=123.123.123.123
UseDataDictionary=Y
DataDictionary=C:\Work\QuickFIXJ\datadictionary\FIX44.xml
[GATEWAY]
Port=4444
[TRANSPORT]
Port=4444
and then
//initiator code:
public class TestQuickFixJConnectivity {
public static void main(String[] args) {
SocketInitiator socketInitiator = null;
try {
SessionSettings sessionSettings = new SessionSettings("C:\\Work\\QuickFixJ\\sessionSettings.txt");
Application application = new TestApplicationImpl();
FileStoreFactory fileStoreFactory = new FileStoreFactory(sessionSettings);
FileLogFactory logFactory = new FileLogFactory(sessionSettings);
MessageFactory messageFactory = new DefaultMessageFactory();
socketInitiator = new SocketInitiator(application,
fileStoreFactory, sessionSettings, logFactory,
messageFactory);
socketInitiator.start();
SessionID sessionId = socketInitiator.getSessions().get(0);
sendLogonRequest(sessionId);
int i = 0;
do {
try {
Thread.sleep(1000);
System.out.println(socketInitiator.isLoggedOn());
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
} while ((!socketInitiator.isLoggedOn()) && (i < 30));
} catch (ConfigError e) {
e.printStackTrace();
} catch (SessionNotFound e) {
e.printStackTrace();
} catch (Exception exp) {
exp.printStackTrace();
} finally {
if (socketInitiator != null) {
socketInitiator.stop(true);
}
}
}
private static void sendLogonRequest(SessionID sessionId) throws SessionNotFound {
Logon logon = new Logon();
Message msg=new Message();
Header header = msg.getHeader();
logon.set(new HeartBtInt(60));
logon.set(new ResetSeqNumFlag(true));
header.setField(new BeginString("FIX.4.4"));
header.setField(new MsgType("AP"));
header.setField(new SenderCompId("XYZ"));
header.setField(new TagetCompId("TYZ"));
header.setField(new ResetSeqNumFlag(true));
//here i m setting all the fields in the csv report .
msg.setField(705,new SortQty(""));
// ....
//below statement returning false
boolean sent = Session.sendToTarget(msg, sessionId);
System.out.println("Logon Message Sent : " + sent);
}
}
Please find my observations below:
In the event logs I am seeing as Created session: and the message which I am trying to send. Also I could see that the sender sequence number is getting incremented in the logs.
Messages.log and header.logs are blank and body.log has the message which i am trying to send.
Also onCreate and ToApp are being called when I try to run the code.
I want to know whether i have sent the message successfully ?
Also boolean sent = Session.sendToTarget(msg, sessionId); is returning false.
I don't see ToAdmin and FromAdmin being executed in my code. Also Do I need to write the acceptor code as well for the same, or just the initiator code will be fine. The DataDictionary which i am using has all the fields set, but I am not sure whether its being used by QuickFixJ when i try to execute the code.
Please advise whats going wrong in this?
OK your settings file looks ok and you're saying it works, but I don't think you need GATEWAY and TRANSPORT headings
As for your code, all you need to do to start with is setup the default QuickFIX Application, FileStoreFactory, LogFactory, MessageFactory and Initiator which you have done.
The default QuickFIX automatically logs on to the Target in your settings file, and if the logon is accepted then it begins to heartbeat. From your comments it sounds like this is happening.
So what's going wrong is your sendLogonRequest is not necessary. Also, if you do send "extra" logons then the target FIX engine will probably reject or ignore them. The reject message would be seen in the logs or file store.
So then you have the QuickFIX API with which to start with you can simply output messages to your own log.
Something like this
public void fromApp(Message msg, SessionID s) throws UnsupportedMessageType, FieldNotFound, IncorrectTagValue
{
log.debug(String.valueOf(LocalTime.now()) + " INITIATOR: FromApp " + msg.toString());
}
public void toApp(Message msg, SessionID s)
{
log.info(String.valueOf(LocalTime.now()) + " INITIATOR: ToApp " + msg.toString());
}
public void fromAdmin(Message msg, SessionID s) throws FieldNotFound, IncorrectTagValue
{
Log.trace("INITIATOR: FromAdmin " + msg.getClass() + " " + msg.toString());
}
public void onCreate(SessionID s)
{
log.info("INITIATOR: OnCreate " + s.toString());
}
public void onLogout(SessionID s)
{
log.error("INITIATOR: OnLogout " + s.toString());
}
public void onLogon(SessionID s)
{
log.info("INITIATOR: OnLogon " + s.toString());
}
public void toAdmin(Message msg, SessionID s)
{
log.trace("INITIATOR: ToAdmin " + msg.getClass() + " " + msg.toString());
}
Then when you want to send a message, try something like this:
QuoteReqID id = new QuoteReqID("1234");
// Create Quote Request message
QuoteRequest qr = new QuoteRequest(id);
// Setup outgoing group and specify an index for each group tag
NoRelatedSym g = new NoRelatedSym();
String instrument = m.getString("EUR/USD");
Symbol symbol = new Symbol(instrument);
g.setField(1, symbol);
QuoteRequestType qt = new QuoteRequestType(102);
g.setField(2, qt);
OrderQty qty = new OrderQty("1000000");
g.setField(3, qty);
SettlType sType = new SettlType("B");
g.setField(4, sType);
SettlDate sDate = new SettlDate("20170315");
g.setField(5, sDate);
Account account = new Account("357647");
g.setField(6, account);
// add group to request
qr.addGroup(g);
Session s = Session.lookupSession(i.getSessions().get(0));
s.send(qr);
Related
I am new, so my question is relatively easy, I guess.
I am using Websphere Application Server platform and default JMS provider to send and receive message from queue. This is how my app looks like:
Saytime is my main servlet which reroute my code to a .jsp file. The "Produce" button sends the app following code and generate the message written in box:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String queueName = "jms/helloqueue";
Context jndiContext = null;
QueueConnectionFactory queueConnectionFcatory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
QueueSender queueSender = null;
Queue queue = null;
TextMessage textMessage = null;
response.setContentType("text/html");
request.setCharacterEncoding("UTF-8"); // To information the that you may use Unicode characters
response.setCharacterEncoding("UTF-8");
String txt = request.getParameter("text");
try {
Properties initialProperties = new Properties();
initialProperties.put(InitialContext.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
initialProperties.put(InitialContext.PROVIDER_URL, "iiop://localhost:2810");
jndiContext = new InitialContext(initialProperties);
} catch (NamingException e) {
e.printStackTrace();
System.exit(1);
}
try {
queueConnectionFcatory = (QueueConnectionFactory) jndiContext.lookup("jms/helloqcf");
queue = (Queue) jndiContext.lookup(queueName);
} catch (NamingException e) {
e.printStackTrace();
System.exit(1);
}
try {
queueConnection = queueConnectionFcatory.createQueueConnection();
queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queueSender = queueSession.createSender(queue);
textMessage = queueSession.createTextMessage();
textMessage.setText(txt);
queueSender.send(textMessage);
} catch (JMSException e) {
System.out.println("JMS Exception occured: "+ e.getMessage());
} finally {
if(queueConnection != null){
try{
Thread.sleep(6000);
queueConnection.close();
} catch(Exception e){}
}
}
RequestDispatcher rd = request.getRequestDispatcher("saytime");
rd.forward(request,response);
}
The "Receive" button sends my app to following servlet code and receives the message from queue:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String queueName = "jms/helloqueue";
Context jndiContext = null;
QueueConnectionFactory queueConnectionfactory = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
QueueReceiver queueReceiver = null;
Queue queue = null;
String text = null;
try {
Properties initialProperties = new Properties();
initialProperties.put(InitialContext.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
initialProperties.put(InitialContext.PROVIDER_URL,"iiop://localhost:2810");
jndiContext = new InitialContext(initialProperties);
} catch (NamingException e) {
System.out.println("JNDI exception occured: " + e.getMessage());
System.exit(1);
}
try {
queueConnectionfactory = (QueueConnectionFactory) jndiContext.lookup("jms/helloqcf");
queue = (Queue) jndiContext.lookup(queueName);
} catch (NamingException e) {
System.exit(1);
}
try {
queueConnection = queueConnectionfactory.createQueueConnection();
queueSession = queueConnection.createQueueSession(true,Session.AUTO_ACKNOWLEDGE);
queueReceiver = queueSession.createReceiver(queue);
//queueReceiver.setMessageListener(listener);
queueConnection.start();
text = queueReceiver.receive().toString();
} catch(JMSException e) {
System.out.println("Exception occured: "+ e.getMessage());
} finally {
if (queueConnection != null) {
try {
queueConnection.close();
} catch (JMSException e) {
}
}
}
if(text != null) {
request.setAttribute("message", text.toString());
}
RequestDispatcher rd = request.getRequestDispatcher("saytime");
rd.forward(request,response);
}
After that I print the message with this little code in my .jsp file:
<%
String getValues = (String) request.getAttribute("message");
%>
<%
if (getValues != null) {
out.println("<p>" + getValues + "</p>");
} else {
out.println("<p> There is no message </p>");
}
%>
The problem is this: I am able to take my produced message, but the button continues to receive the message till the count on JMSXDeliveryCount hit 5. Mostly JMSXDeliveryCount start with 1 and total I can receive the message 5 times. I want to receive it only once and then message to disappear.
Additionally, I want to know how I can print only my message. I print with additional details like you see in the picture. If it's possible, I don't want that.
I tried to limit redelivery number, but I am unable to come up with right code I guess. Also, I tried to use different acknowledgement mode but, it did not work either.
I got really confused with it, some help would be perfect. Thanks.
The problem is you're creating the consumer's session as transacted. See this line:
queueSession = queueConnection.createQueueSession(true,Session.AUTO_ACKNOWLEDGE);
The acknowledgement mode will be ignored since the session is transacted (i.e. you're passing true in the first parameter). This is noted in the documentation which states:
If transacted is set to true then the session will use a local transaction which may subsequently be committed or rolled back by calling the session's commit or rollback methods. The argument acknowledgeMode is ignored.
Therefore, you should either acknowledge the message and commit the session manually, e.g.:
Message message = queueReceiver.receive();
text = message.toString();
message.acknowledge();
queueSession.commit();
Or you should use a non-transacted session and allow the message to be auto-acknowledged according to the acknowledgement mode, e.g.:
queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Typically transacted sessions are only used when multiple operations (i.e. send and receive) need to be combined together atomically. Since you're only consuming a single message here I would recommend you just use a non-transacted session.
Also, you will eventually want to cache the javax.jms.Connection or perhaps use a connection pool rather than creating a connection, session, & producer/consumer for every message. This is an anti-pattern and should be avoided whenever possible.
I have a simple netty connection pool and a simple HTTP endpoint to use that pool to send TCP messages to ServerSocket. The relevant code looks like this, the client (NettyConnectionPoolClientApplication) is:
#SpringBootApplication
#RestController
public class NettyConnectionPoolClientApplication {
private SimpleChannelPool simpleChannelPool;
public static void main(String[] args) {
SpringApplication.run(NettyConnectionPoolClientApplication.class, args);
}
#PostConstruct
public void setup() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.remoteAddress(new InetSocketAddress("localhost", 9000));
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new DummyClientHandler());
}
});
simpleChannelPool = new SimpleChannelPool(bootstrap, new DummyChannelPoolHandler());
}
#RequestMapping("/test/{msg}")
public void test(#PathVariable String msg) throws Exception {
Future<Channel> future = simpleChannelPool.acquire();
future.addListener((FutureListener<Channel>) f -> {
if (f.isSuccess()) {
System.out.println("Connected");
Channel ch = f.getNow();
ch.writeAndFlush(msg + System.lineSeparator());
// Release back to pool
simpleChannelPool.release(ch);
} else {
System.out.println("not successful");
}
});
}
}
and the Server (ServerSocketRunner)
public class ServerSocketRunner {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9000);
while (true) {
Socket socket = serverSocket.accept();
new Thread(() -> {
System.out.println("New client connected");
try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));) {
String inputLine, outputLine;
out.println("Hello client!");
do {
inputLine = in.readLine();
System.out.println("Received: " + inputLine);
} while (!"bye".equals(inputLine));
System.out.println("Closing connection...");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
DummyChannelPoolHandler and DummyClientHandler just print out events that happen, so they are not relevant. When the server and the client are started and I send a test message to test endpoint, I can see the server prints "New client connected" but the message sent by client is not printed. None of the consecutive messages sent by client are printed by the server.
If I try telnet, everything works fine, the server prints out messages. Also it works fine with regular netty client with same bootstrap config and without connection pool (SimpleNettyClientApplication).
Can anyone see what is wrong with my connection pool, I'm out of ideas
Netty versioin: 4.1.39.Final
All the code is available here.
UPDATE
Following Norman Maurer advice. I added
ChannelFuture channelFuture = ch
.writeAndFlush(msg + System.lineSeparator());
channelFuture.addListener(writeFuture -> {
System.out
.println("isSuccess(): " + channelFuture.isSuccess() + " : " + channelFuture.cause());
});
This prints out
isSuccess: false : java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion)
To fix it, I just converted String into ByteBuf
ch.writeAndFlush(Unpooled.wrappedBuffer((msg + System.lineSeparator()).getBytes()));
You should check what the status of the ChannelFuture is that is returned by writeAndFlush(...). I suspect it is failed.
I have tried to establish chat connection between two users using xmpp and OpenFire. But i am not able to send and receive message. I have pasted my code below for reference. Any help will be very helpful.
I established a connection with Smack by
XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setUsernameAndPassword("admin", "admin");
config.setServiceName("172.21.4.199");
config.setHost("172.21.4.199");
config.setPort(5222);
config.setDebuggerEnabled(true);
config.setConnectTimeout(50000);
XMPPTCPConnection connection = new XMPPTCPConnection(config.build());
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
XMPPTCPConnection.setUseStreamManagementDefault(true);
try {
connection.setPacketReplyTimeout(50000);
connection.connect();
Log.d(TAG, "SetupDefaults -- Connected");
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "SetupDefaults -- Connection failed exc: "+e);
}
and its gets succesfully connected. And i try to send a chat by using
ChatManager chatManager = ChatManager.getInstanceFor(connection);
Chat chat = chatManager.createChat("user2#server.local", new ChatMessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
System.out.println("processMessage -- Sent message: " + message);
}
});
try {
chat.sendMessage("Hai.. Lets we chat!");
}catch (Exception e){
Log.d(TAG, "sendChat Exc: "+e.toString());
}
But i couldn't find that processMessage gets triggered. Because that S.O.P doesn't gets triggered. But i gets
SMACK: SENT (0): Hai.. Lets we chat!
SMACK: RECV (0): Hai.. Lets we chat!
in my console while sending a chat.
Simillarly i use,
PacketListener packetListener = new PacketListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
Message message = (Message)packet;
String from = message.getFrom();
String body = message.getBody();
System.out.println("Message from: " + from + " " + body);
}
};
connection.addPacketListener(packetListener, filter);
to receive the chat. But processPacket also doesn't gets triggered.
PacketListner it's something much more general to handle stanzas, it's not what you really need. You just need a ChatMessageListner
ChatManager chatManager;
chatManager = ChatManager.getInstanceFor(connection);
chatManager.addChatListener(
**new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally)
{
if (!createdLocally)
{
chat.addMessageListener(new IncomingMessageListener());;
}
}
})**;
Basic implementation:
class IncomingMessageListener implements ChatMessageListener {
#Override
public void processMessage(Chat arg0, Message message) {
String from = message.getFrom();
String body = message.getBody();
if (body != null)
{
System.out.println(String.format("============ Received message '%1$s' from %2$s\n============", body, from));
guiUpdate.displayMessage(body); /* custom method */
}
else
{
System.out.println("SYSTEM: ping");
}
}
I've got an issue, for which I am unable to post full code (sorry), due to security reasons. The gist of my issue is that I have a ServerBootstrap, created as follows:
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
final ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, 3000));
//Adds the MQTT encoder and decoder
ch.pipeline().addLast("decoder", new MyMessageDecoder());
ch.pipeline().addLast("encoder", new MyMessageEncoder());
ch.pipeline().addLast(createMyHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128).option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// Bind and start to accept incoming connections.
channelFuture = b.bind(listenAddress, listenPort);
With createMyHandlerMethod() that basically returns an extended implementation of ChannelInboundHandlerAdapter
I also have a "client" listener, that listens for incoming connection requests, and is loaded as follows:
final String host = getHost();
final int port = getPort();
nioEventLoopGroup = new NioEventLoopGroup();
bootStrap = new Bootstrap();
bootStrap.group(nioEventLoopGroup);
bootStrap.channel(NioSocketChannel.class);
bootStrap.option(ChannelOption.SO_KEEPALIVE, true);
bootStrap.handler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, getKeepAliveInterval()));
ch.pipeline().addAfter("idleStateHandler", "idleEventHandler", new MoquetteIdleTimeoutHandler());
ch.pipeline().addLast("decoder", new MyMessageDecoder());
ch.pipeline().addLast("encoder", new MyMessageEncoder());
ch.pipeline().addLast(MyClientHandler.this);
}
})
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.TCP_NODELAY, true);
// Start the client.
try {
channelFuture = bootStrap.connect(host, port).sync();
} catch (InterruptedException e) {
throw new MyException(“Exception”, e);
}
Where MyClientHandler is again a subclassed instance of ChannelInboundHandlerAdapter. Everything works fine, I get messages coming in from the "server" adapter, i process them, and send them back on the same context. And vice-versa for the "client" handler.
The problem happens when I have to (for some messages) proxy them from the server or client handler to other connection. Again, I am very sorry for not being able to post much code, but the gist of it is that I'm calling from:
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(someOtherMessage);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
Now here's the problem: the bolded (client) writeAndFlush - never actually writes the message bytes, it doesn't throw any errors. The ChannelFuture returns all false (success, cancelled, done). And if I sync on it, eventually it times out for other reasons (connection timeout set within my code).
I know I haven't posted all of my code, but I'm hoping that someone has some tips and/or pointers for how to isolate the problem of WHY it is not writing to the client context. I'm not a Netty expert by any stretch, and most of this code was written by someone else. They are both subclassing ChannelInboundHandlerAdapter
Feel free to ask any questions if you have any.
*****EDIT*********
I tried to proxy the request back to a DIFFERENT context/channel (ie, the client channel) using the following test code:
public void proxyPubRec(int messageId) throws MQTTException {
logger.log(logLevel, "proxying PUBREC to context: " + debugContext());
PubRecMessage pubRecMessage = new PubRecMessage();
pubRecMessage.setMessageID(messageId);
pubRecMessage.setRemainingLength(2);
logger.log(logLevel, "pipeline writable flag: " + ctx.pipeline().channel().isWritable());
MyMQTTEncoder encoder = new MyMQTTEncoder();
ByteBuf buff = null;
try {
buff = encoder.encode(pubRecMessage);
ctx.channel().writeAndFlush(buff);
} catch (Throwable t) {
logger.log(Level.SEVERE, "unable to encode PUBREC");
} finally {
if (buff != null) {
buff.release();
}
}
}
public class MyMQTTEncoder extends MQTTEncoder {
public ByteBuf encode(AbstractMessage msg) {
PooledByteBufAllocator allocator = new PooledByteBufAllocator();
ByteBuf buf = allocator.buffer();
try {
super.encode(ctx, msg, buf);
} catch (Throwable t) {
logger.log(Level.SEVERE, "unable to encode PUBREC, " + t.getMessage());
}
return buf;
}
}
But the above at line: ctx.channel().writeAndFlush(buff) is NOT writing to the other channel - any tips/tricks on debugging this sort of issue?
someOtherMessage has to be ByteBuf.
So, take this :
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(someOtherMessage);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
... and replace it with this :
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(ByteBuf);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
Actually, this turned out to be a threading issue. One of my threads was blocked/waiting while other threads were writing to the context and because of this, the writes were buffered and not sent, even with a flush. Problem solved!
Essentially, I put the first message code in an Runnable/Executor thread, which allowed it to run separately so that the second write/response was able to write to the context. There are still potentially some issues with this (in terms of message ordering), but this is not on topic for the original question. Thanks for all your help!
I am working on XMPP client for BB with JXA, but JXA api takes time to read from inputstream and through timeout error after 2 mins. I written seperate socket program in J2ME and executed in the BB simulator, it could exchange XML but the inputstream is not quitting from the while loop, gets hang in reading. Please see the below code..
class SocketThread extends Thread
{
public void run()
{
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection("socket://xxxxxx.p1.im:5222");
if (connDesc != null)
{
SocketConnection httpConn;
httpConn = (SocketConnection)connDesc.getConnection();
try
{
InputStream is = httpConn.openInputStream();
OutputStream os = httpConn.openOutputStream();
String a = "<?xml version=\"1.0\"?><stream:stream to=\"xxxxx.p1.im\" xml:lang=\"en\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\">";
os.write(a.getBytes());
byte[] b = new byte[1024];
int len =0;
while ((len = is.read(b)) > 0) {
String str = new String(b);
System.out.println("Server n: " + str);
}
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("got response xml stream..: "
);
}
});
}
catch (IOException e)
{
System.err.println("Caught IOException: "
+ e.getMessage());
}
}
}
}
Above program not coming out of the loop unless until it timesout, please help me out to fix this issue to move forward.
Thanks in advance.
A read timeout means no data arrived within the timeout period. Nothing else.
Your code is wrong in other ways however: you are assuming the read filled the buffer, and ignoring positive values of 'len' when constructing the String, so you are passing yourself junk.