how to send deliverSmResp with cloudhopper asynchrous - java

hope everyone is fine with this pandemic.
I receive a sms from a SMSC, and i would like to send him a deliver_sm_resp.
I try to implement it like that :
#Override
public PduResponse firePduRequestReceived(PduRequest pduRequest) {
logger.warn("***** BIND RECEIVER *****");
DeliverSm sms = null;
if ((pduRequest != null) && pduRequest.getName().equals("deliver_sm")) {
sms = (DeliverSm) pduRequest;
}
if ((pduRequest != null) && pduRequest.getName().equals("enquire_link")) {
return pduRequest.createResponse();
}
if ( sms !=null && (int)sms.getDataCoding() == 0 ) {
//message content is English
logger.warn("***** New Message Received *****");
logger.warn("From: " + sms.getSourceAddress().getAddress());
logger.warn("To: " + sms.getDestAddress().getAddress());
logger.warn("Content: " + new String(sms.getShortMessage()));
DeliverSm deliver = new DeliverSm();
deliver.setSourceAddress(sms.getSourceAddress());
deliver.setDestAddress(sms.getDestAddress());
deliver.setDataCoding(sms.getDataCoding());
try {
deliver.setShortMessage(sms.getShortMessage());
} catch (SmppInvalidArgumentException e) {
e.printStackTrace();
}
deliver.setSequenceNumber(sms.getSequenceNumber());
//deliver.setCommandLength(sms.getCommandLength());
deliver.setCommandStatus(sms.getCommandStatus());
runDeliverSmRespSmppSessionHandler(session, deliver);
}
return super.firePduRequestReceived(pduRequest);
}
i call runDeliverSmRespSmppSessionHandler asynchrously, like that :
public class RunDeliverSmRespSmppSessionHandler extends DefaultSmppSessionHandler implements Runnable {
.
.
.
public void run() {
logger.info("welcome to deliver TestSmppSessionHandler RUN");
sendRequestPdu(session, deliver);
}
private void sendRequestPdu(SmppSession session, DeliverSm deliver) {
logger.info("welcome to deliver TestSmppSessionHandler sendRequestPdu");
try {
WindowFuture<Integer,PduRequest,PduResponse> future = session.sendRequestPdu(deliver, 10000, false);
if (!future.await()) {
logger.error("Failed to receive deliver_sm_resp within specified time");
} else if (future.isSuccess()) {
DeliverSmResp deliverSmResp = (DeliverSmResp)future.getResponse();
logger.info("deliver_sm_resp: commandStatus [" + deliverSmResp.getCommandStatus() + "=" + deliverSmResp.getResultMessage() + "]");
} else {
logger.error("Failed to properly receive deliver_sm_resp: " + future.getCause());
}
} catch (Exception e) {
logger.error("message catched in smDeliver : "+e.getMessage()+" get stackTrace : "+e.getStackTrace());
}
}
Unfortunally, i had this error in sendRequestPdu():
04-04-2020 23:15:41 ERROR TestSmppSessionHandler:61 - Failed to receive deliver_sm_resp within specified time
04-04-2020 23:16:06 WARN EnquireLinkTask:37 - Enquire link failed, executing reconnect:
com.cloudhopper.smpp.type.SmppTimeoutException: Unable to accept offer within [10000 ms] (window full)
at com.cloudhopper.smpp.impl.DefaultSmppSession.sendRequestPdu(DefaultSmppSession.java:508)
at com.cloudhopper.smpp.impl.DefaultSmppSession.sendRequestAndGetResponse(DefaultSmppSession.java:464)
Thank you for your helping

to send a response to inform the SMSC than you received your SMS, you have to use
private void sendResponsePdu(SmppSession session, DeliverSmResp deliver) {
logger.info("welcome to deliver TestSmppSessionHandlerV2 sendRequestPdu");
try {
session.sendResponsePdu(deliver);
logger.info("message deliver response sent successfully !!!");
} catch (Exception e) {
logger.error("message catched in smDeliver : "+e.getMessage()+" get stackTrace : "+e.getStackTrace());
}
About DeliverSmResp deliver, you can initialize like that :
DeliverSmResp deliver_sm_resp = new DeliverSmResp();
deliver_sm_resp.setCommandLength(17);
deliver_sm_resp.setCommandStatus(sms.getCommandStatus());
deliver_sm_resp.setSequenceNumber(sms.getSequenceNumber());
deliver_sm_resp.setMessageId("");

Related

Android JavaMail Detect If Server Goes Offline

I'm currently developing an email application with a background service used in conjunction with the JavaMail Idle functionality. The background service keeps the idle functionality working by issuing a check every 29 minutes (as the server being used (Exchange server)) can sometimes drop the connection after 30 minutes of being connected.
Whilst this works perfectly, if the Exchange server is offline, then the application will continue to attempt to reconnect to the IMAP folder indefinately. I have noticed spikes in data usage between the hours of 3AM & 6AM (a typical Exchange update time).
To avoid the increased data usage, I am looking to implement functionality where the app should attempt to reconnect to the IMAP folder three times and then display a warning to the user that the server is offline and a new connection attempt will be retried in 30 minutes.
In order to achieve this, how would I be able to detect if the Exchange server is actually offline/updating & would any exceptions be thrown, if the app cannot connect to the IMAP folder? As if an exception would be thrown, then I could save a local int variable and increment it by one every time the exception is thrown and then show the alert to the user on the third time.
My current code implementation can be seen below:
public void checkInboxEmail(final String host, final String user, final String password) {
Log.d(TAG, "checkEmail");
this.host = host;
this.user = user;
this.password = password;
new Thread(new Runnable() {
#Override
public void run() {
try {
Log.d(TAG, "checkEmail - run()");
long databaseRecords;
//create properties field
Properties properties = new Properties();
properties.put("mail.store.protocol", "imaps");
properties.put("mail.imaps.ssl.trust", "*");
properties.put("mail.debug", "true");
emailSession = Session.getInstance(properties, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password);
}
});
IMAPStore imapStore = (IMAPStore) emailSession.getStore("imaps");
// imapStore.connect();
imapStore.connect(host, user, password);
if (imapStore.isConnected()) {
Log.d("MailPush", "Successfully connected to IMAP");
} else {
Log.d("MailPush", "Not connected to IMAP");
}
final IMAPFolder folder = (IMAPFolder) imapStore.getFolder("Inbox");
folder.open(IMAPFolder.READ_WRITE);
databaseRecords = dbManager.getReceivedEmailRecordsCount();
if (databaseRecords < folder.getMessageCount()) {
Log.d(TAG, "Receiving Mail...");
receiveMail(folder.getMessages());
} else {
Log.d(TAG, "Records match.");
}
Folder[] fdr = imapStore.getDefaultFolder().list();
for (Folder fd : fdr)
System.out.println(">> " + fd.getName());
folder.addMessageCountListener(new MessageCountListener() {
public void messagesAdded(MessageCountEvent e) {
System.out.println("Message Added Event Fired");
Log.d(TAG, "MESSAGE TYPE: " + e.getType());
//ADDED = 1 & REMOVED = 2
try {
Message[] messages = e.getMessages();
System.out.println("messages.length---" + messages.length);
for (Message message : messages) {
if (!message.getFlags().contains(Flags.Flag.SEEN)) {
//Message is new (hasn't been seen) > Message Details
System.out.println("---------------------------------");
System.out.println("Email Number " + (message.getMessageNumber()));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
System.out.println("Text: " + message.getContent().toString());
String from = message.getFrom()[0].toString();
String cc = InternetAddress.toString(message.getRecipients(Message.RecipientType.CC));
Log.d(TAG, "CC 1: " + cc);
Address[] recipients = message.getRecipients(Message.RecipientType.CC);
cc = InternetAddress.toString(recipients);
Log.d(TAG, "CC 2: " + cc);
//Check Encryption Details > Add SEEN Flag > Add to database
checkEncryption((MimeMessage) message, from, cc);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void messagesRemoved(MessageCountEvent e) {
System.out.println("Message Removed Event fired");
}
});
folder.addMessageChangedListener(new MessageChangedListener() {
public void messageChanged(MessageChangedEvent e) {
System.out.println("Message Changed Event fired");
}
});
startListening(folder);
//close the store and folder objects
// emailFolder.close(false);
// store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private void startListening(IMAPFolder imapFolder) {
Log.d(TAG, "startListening");
// We need to create a new thread to keep alive the connection
Thread t = new Thread(
new KeepAliveRunnable(imapFolder), "IdleConnectionKeepAlive"
);
t.start();
while (!Thread.interrupted()) {
Log.d(TAG, "Starting IDLE");
try {
Log.d(TAG, "Setting IDLE");
imapFolder.idle();
} catch (FolderClosedException fex) {
//Server closes connection.
Log.d(TAG, "FolderClosedException. Server potentially dropped connection. Retrying connection...");
fex.printStackTrace();
if (!isServiceRunning(MyService.class)) {
Log.d(TAG, "Service isn't running. Starting service...");
//Start service
Intent intent = new Intent(context, MyService.class);
intent.putExtra("host", host);
intent.putExtra("email", user);
intent.putExtra("password", password);
context.startService(intent);
} else {
Log.d(TAG, "Service is already running. Checking email...");
checkInboxEmail(host, user, password);
}
} catch (MessagingException e) {
//Idle isn't supported by server.
Log.d(TAG, "Messaging exception during IDLE: ");
e.printStackTrace();
}
}
// Shutdown keep alive thread
if (t.isAlive()) {
Log.d(TAG, "Interrupting thread");
t.interrupt();
}
}
private static class KeepAliveRunnable implements Runnable {
private final String TAG = getClass().getName();
private static final long KEEP_ALIVE_FREQ = 60000 * 29; // 29 minutes (Exchange connection drops after 20-30 minutes)
private IMAPFolder folder;
KeepAliveRunnable(IMAPFolder folder) {
this.folder = folder;
}
#Override
public void run() {
while (!Thread.interrupted()) {
try {
Thread.sleep(KEEP_ALIVE_FREQ);
// Perform a messageCount check just to keep alive the connection
Log.d(TAG, "Performing a messageCount check to keep the connection alive");
folder.getMessageCount();
} catch (InterruptedException e) {
// Ignore, just aborting the thread...
Log.d(TAG, "Interrupted...");
e.printStackTrace();
} catch (MessagingException e) {
// Shouldn't really happen...
Log.d(TAG, "Unexpected exception while keeping alive the IDLE connection");
e.printStackTrace();
}
}
}
}
private void receiveMail(Message[] messages) {
try {
System.out.println("messages.length---" + messages.length);
for (Message message : messages) {
if (!message.getFlags().contains(Flags.Flag.SEEN)) {
//Message is new (hasn't been seen) > Message Details
System.out.println("---------------------------------");
System.out.println("Email Number " + (message.getMessageNumber()));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
System.out.println("Text: " + message.getContent().toString());
String from = message.getFrom()[0].toString();
String cc = InternetAddress.toString(message.getRecipients(Message.RecipientType.CC));
//Check Encryption Details > Add SEEN Flag > Add to database
checkEncryption((MimeMessage) message, from, cc);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
If the server is up but not accepting connections, the connect will fail immediately (with an exception). If the server is down, and you've set a connect timeout, the connect will fail after the timeout (with an exception).
To clarify #BillShannon's answer, if the server host is up but Exchange is not accepting connections, the connect will fail immediately with a ConnectException: connection refused. If the server host is down, the connect will fail after the timeout with a ConnectException: connect timeout (or possibly a SocketTimeoutException), regardless of whether you've set a connect timeout, as the platform always has one.

How can loop continue before method is finished?

I have multiple threads(runnables) in my program. On of theme is handling RS232 communication.
My problem is that code inside the loop is not executed in the order that is written:
while(!serialData.dataToSend.isEmpty())
{
try {
SerialMsgToSend msgObject = serialData.dataToSend.remove();
if(msgObject.type == msgObject.HOLDING_REGISTER)
{
Thread.sleep(COMMAND_WAIT_TIME);
Toolkit.getDefaultToolkit().beep();
modBusManager.singleRegisterWriteToMultipleRegisters(msgObject.unit, msgObject.startRegisterAdress, msgObject.data);
}
else if(msgObject.type == msgObject.COIL)
{
Thread.sleep(COMMAND_WAIT_TIME);
Toolkit.getDefaultToolkit().beep();
modBusManager.writeToCoil(msgObject.unit, msgObject.startRegisterAdress, msgObject.data[0] == 1);
}
Thread.sleep(5000);
readUnitsData(msgObject.unit);
Thread.sleep(5000);
if(msgObject.RESPONSE > 0)
{
serialData.listeners[msgObject.unit - 1].sendResponseToServer(msgObject.RESPONSE);
}
} catch (Exception ex) {
log.error("Exception on sending data: " + ex.toString());
}
}
First I write to ModBus register with calling:
modBusManager.singleRegisterWriteToMultipleRegisters(msgObject.unit, msgObject.startRegisterAdress, msgObject.data);
After that I want to wait 5 seconds that registers are updated, then read them and send information to server.
I read the data with calling method:
readUnitsData(msgObject.unit);
And then I am using listener to tell another thread to send data to server:
serialData.listeners[msgObject.unit - 1].sendResponseToServer(msgObject.RESPONSE);
My problem is that data is sent to server before it gets read/updated so I send old data. I am used that code is executed in the order that is written. Am I using threads in a wrong way or what could be the problem?
Here is method which I call to read data:
private void readUnitsData(int unitID)
{
if(mtxData.climatList[unitID] != null)
{
try
{
log.info("Serial reading data for: " + unitID);
int[] coils = modBusManager.readCoils(unitID + 1,0,87);
String[] holding = modBusManager.readHoldingRegisters(unitID + 1,0,64); //(int slaveAdress, int registerAdress, int registerQuntaity)
if(coils != null && holding != null)
{
System.out.println("send to listner: " + unitID);
serialData.listeners[unitID].newHoldingAndCoilData(holding, coils);
}
} catch (Exception ex)
{
log.error("Exception on run: " + ex.toString());
}
}
}
And method inside other runnable, which is connected to listener:
#Override
public void sendResponseToServer(int responseType)
{
try
{
log.info("listener for sendStatusToServer called: " + responseType);
Thread.sleep(15000);
switch(responseType)
{
case 1:
communicationManager.sendStatus();
break;
case 2:
communicationManager.sendSettings();
break;
}
}catch(Exception ex)
{
log.error("Exception on sendResponseToServer: " + ex);
}
}
I did like #Markus Mitterauer proposed and took apart the code. I found that that it was problem with one of the unitID's which was wrong. Because of that I didn't get any values when reading registers and listener wasn't triggered correctly.

Facebook messenger app using asmack android xmpp

I was trying to fetch facebook friends and send message using asmack library over XMPP.I took reference from this site for facebook messaging.But after executing the code below i got exception.
public class MyActivity extends Activity {
public int state = 0;
private static final String TAG = "MyActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(new Runnable() {
public void run() {
//XMPPConnection xmpp = new XMPPConnection("jabber.iitsp.com");
XMPPConnection xmpp = new XMPPConnection("chat.facebook.com");
try {
xmpp.connect();
// for other jabber accounts, truncate after the #
//xmpp.login("username", "password");
// for gtalk / gmail, include the #
xmpp.login("fb-username#chat.facebook.com", "your-fb-password");
} catch (XMPPException e) {
Log.v(TAG, "Failed to connect to " + xmpp.getHost());
e.printStackTrace();
}
ChatManager chatmanager = xmpp.getChatManager();
Chat newChat = chatmanager.createChat("friend#chat.facebook.com", new MessageListener() {
// THIS CODE NEVER GETS CALLED FOR SOME REASON
public void processMessage(Chat chat, Message message) {
try {
Log.v(TAG, "Got:" + message.getBody());
chat.sendMessage(message.getBody());
} catch (XMPPException e) {
Log.v(TAG, "Couldn't respond:" + e);
}
Log.v(TAG, message.toString());
}
});
// Send something to friend#chat.facebook.com
try {
newChat.sendMessage("my message");
} catch (XMPPException e) {
Log.v(TAG, "couldn't send:" + e.toString());
}
// Accept only messages from friend#chat.facebook.com
PacketFilter filter
= new AndFilter(new PacketTypeFilter(Message.class),
new FromContainsFilter("friend#chat.facebook.com"));
// Collect these messages
PacketCollector collector = xmpp.createPacketCollector(filter);
while(true) {
Packet packet = collector.nextResult();
if (packet instanceof Message) {
Message msg = (Message) packet;
// Process message
Log.v(TAG, "Got message:" + msg.getBody());
}
}
}
}).start();
//setContentView(this);
}}
I got following errors during execution of the code:-
1) java.security.KeyStoreException: java.security.NoSuchAlgorithmException: KeyStore jks implementation not found
2) SASL authentication failed using mechanism PLAIN:
Then my program crashed
java.lang.IllegalStateException: Not connected to server.
Any help would be appreciated.

Can't send or receive presence with ASmack

I am trying to develop a XMPP chat client for Android (using Java connected to C#/Unity). I have got the Java -> Unity/C# connection working perfectly. I have also downloaded Asmack and can generate a library and my of wrapper class for initilazing a connection to a OpenFire XMPP server. However, I cannot seem to get Presence sent or recieved. I can log in, register new user and populate their roster, send messages, but cannot send any presence.
The code auto registrate users who never have used the app before. It also uses a preset friend list, and auto populates the roster with these friends.
The code is as follow (sorry for all the debug lines, can't use breakpoints when using Unity):
public class ASmackWrapper
{
private XMPPConnection connection;
private String[] friends;
private static final String eventClass = "ASmackEventListener";
private static ASmackWrapper wrapper;
public static ASmackWrapper instance()
{
System.out.println("instancecreator of ASmackWrapper 1!");
if (wrapper == null)
wrapper = new ASmackWrapper();
return wrapper;
}
public ASmackWrapper()
{
System.out.println("constructor of ASmackWrapper");
}
public boolean tryToRegister(String user, String pass){
AccountManager acManager = connection.getAccountManager();
try {
Map<String, String> attributes = new HashMap<String,String>();
attributes.put("email", "MY email");
acManager.createAccount(user, pass,attributes);
} catch (XMPPException e) {
System.out.println("cant autoregister user "+ user +" ... with pass: "+pass+" on server. error:" + e.getLocalizedMessage());
if (e.getLocalizedMessage().contains("conflict"))
return false; // Wrong password, since there is already an account with that id!
return false;
}
return true;
}
public void setFriends(String[] _friends) {
friends = _friends;
}
public void start(String host, String user, String pass)
{
System.out.println("Java: openConenction host:"+host);
ConnectionConfiguration cc = new ConnectionConfiguration(host,5222);
//cc.setSendPresence(true);
this.connection = new XMPPConnection(cc);
Connection.DEBUG_ENABLED = true;
try {
this.connection.connect();
} catch (XMPPException e) {
System.out.println("Error connecting to server");
return;
}
if(!this.connection.isConnected()) {
System.out.println("Java: is not connected");
onError("Connection failed");
return;
}
boolean loginStatus = login(user, pass);
if (!loginStatus) {
onError("Login Failed");
return;
}
RosterListener rl = new RosterListener() {
public void entriesAdded(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {
System.out.println("presence changed!" + presence.getFrom() + " "+presence.getStatus());
onPresence(presence);
}
};
if (connection.getRoster() != null) {
connection.getRoster().setSubscriptionMode(Roster.SubscriptionMode.accept_all);
System.out.println("7");
connection.getRoster().addRosterListener(rl);
}
onAuthenticate("");
System.out.println("10");
//Set presence to online!
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("Online, Programmatically!");
presence.setPriority(24);
presence.setMode(Presence.Mode.available);
connection.sendPacket(presence);
}
private void addFriends() throws Exception {
if (friends == null) {
System.out.println("No friends to add");
return;
}
System.out.println("Number of friends to add: "+friends.length);
for (int i = 0;i<friends.length;i++) {
System.out.println("Create user in roster: "+friends[i]);
connection.getRoster().createEntry("fb"+friends[i], "No name_",null);
}
}
private boolean login(String jid, String password) {
System.out.println("1");
boolean isLoggedIn=true;
try {
this.connection.login(jid, password);
} catch (XMPPException e) {
isLoggedIn=false;
}
System.out.println("2");
if(!isLoggedIn) {
boolean isRegistred = tryToRegister(jid,password);
if (isRegistred) {
connection.disconnect();
try {
connection.connect();
connection.login(jid, password);
} catch (XMPPException e) {
onError("Could not connect and login after registring");
return false;
}
} else {
return false;
}
}
try {
addFriends();
} catch (Exception e) {
onError("Could not add friends to roster");
}
ChatManager chatmanager = connection.getChatManager();
chatmanager.addChatListener(new ChatManagerListener()
{
public void chatCreated(final Chat chat, final boolean createdLocally)
{
System.out.println("OK Chat created!");
chat.addMessageListener(new MessageListener()
{
public void processMessage(Chat chat, Message message)
{
onMessage(chat, message);
}
});
}
});
return true;
}
public void sendMessage(String rec, String message) {
System.out.println("sendMessage(string,string) to host :"+connection.getHost());
Chat chat = connection.getChatManager().createChat(rec+"#"+connection.getHost(), new MessageListener() {
public void processMessage(Chat chat, Message message) {
// Print out any messages we get back to standard out.
System.out.println("Probably an error, since we got a instant reply on sent message. Received message body: " + message.getBody() + " from:"+message.getFrom() + " to:"+message.getTo());
}
});
try {
chat.sendMessage(message);
System.out.println("Message sent");
} catch (XMPPException e) {
System.out.println("Error sending message: "+e.toString());
e.printStackTrace();
}
}
public void logout () {
System.out.println("Login out...");
connection.disconnect();
}
public void getOnlineFriends() {
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
for(RosterEntry rosterEntry: entries) {
String user = rosterEntry.getUser();
Presence presence = roster.getPresence(user);
System.out.println("Presence : "+presence);
System.out.println("Presence type: "+presence.getType());
System.out.println("Presence mode: "+presence.getMode());
}
//Set presence to online!
Presence presence = new Presence(Presence.Type.available);
presence.setStatus("Online, Programmatically!");
presence.setPriority(24);
presence.setMode(Presence.Mode.available);
connection.sendPacket(presence);
}
private void onMessage(Chat chat, Message message) {
String m = ("Received message: " + (message != null ? message.getBody() : "NULL"));
System.out.println(m);
UnityPlayer.UnitySendMessage(eventClass, "Message", m);
}
private void onError(String message) {
UnityPlayer.UnitySendMessage(eventClass, "Error", message);
}
private void onAuthenticate(String message) {
UnityPlayer.UnitySendMessage(eventClass, "Authenticate", message);
}
private void onPresence(Presence presence) {
String user = presence.getFrom();
if (presence.getType() == Presence.Type.available)
UnityPlayer.UnitySendMessage(eventClass, "Online", user);
else
UnityPlayer.UnitySendMessage(eventClass, "Offline", user);
System.out.println("Java: Presence changed, from:" +presence.getFrom() + " type:"+presence.getType() + " toString:"+presence.toString());
}
}
The presence is checked in two ways, by setting a presence listener and by fetching the status after login. This SO page suggest waiting 5 sec before getting the precense: Unable to get presence of roster by using smack, openfire
I have tried that as well by calling getOnlineFriends from a button, more than 5 sec after login. The listener never gets called. It just fires once after login, once for each on the roster with a presence = null.
Edit: After turning on Debug mode on Asmack I see the following reply to my presence send message:
SENT <presence id="3sG7l-11"><status>Online, Programmatically!</status><priority>24</priority></presence>
RCV <presence id="6s7BX-5" to="787122012#xxx.tripnet.se/Smack" from="10000063946242" type="error">
<error code="404" type="cancel">
<remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error></presence>
The server log:
org.jivesoftware.openfire.nio.ConnectionHandler - Closing connection due to error while processing message:
<iq id="566-4" type="error" from="xxx.tripnet.se/f55aea72" to="xxx.tripnet.se">
<error /><error type="cancel" code="501">
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error>
<ping xmlns="urn:xmpp:ping" /></iq>
java.lang.IllegalArgumentException: IQ must be of type 'set' or 'get'. Original IQ:
<iq id="566-4" type="error" from="xxx.tripnet.se/f55aea72" to="xxx.tripnet.se">
<error/><error type="cancel" code="501">
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>
<ping xmlns="urn:xmpp:ping"/></iq>
at org.xmpp.packet.IQ.createResultIQ(IQ.java:384)
I have also tried to pass along setSendPresence = true to the connectionconfiguration passed in connect(), but no difference.
I have also tried to set the subscription mode manually in OpenFire server to "both" (from "none") on both users, but with no effect.
Got it working! It was probably due to that I did not use the correct format on my jid's in the roster list. The correct format had to be user#myserver.se, not just user.
Write a RosterListener and see if it works.
public void rosterOnlineStatus(){
Roster roster = connection.getRoster();
Presence status = new Presence(Type.available);
status.setStatus("Hello This is Phaneendra");
roster.addRosterListener(new RosterListener() {
#Override
public void presenceChanged(Presence presence) {
System.out.println(presence.getFrom()+ "is "+presence+" "+presence.getStatus());
presence.getStatus();
}
#Override
public void entriesUpdated(Collection<String> addresses) {}
#Override
public void entriesDeleted(Collection<String> addresses) {}
#Override
public void entriesAdded(Collection<String> addresses) {}
});
}
See if adding the RosterListener will work?

Full-duplex server socket implementaion, seperate read and write thread?

I want to read and write(randomly from server to client) on same server socket (java application). My client to server write and read work fine in a loop. At server with response write properly.
But if i am trying to write at server randomly some command. i do not have solution, first of all my question is :
is it possible at server side to write command to client ramdonly on same socket?
if possible, any suggestion or pointer how to do it?
please give me some pointer where I can read the material about this scenario ?
thanks in advance.
public class ContentServerSocket extends ServerSocket {
private final static int PORT = 4444;
protected static boolean XYZGONE = false;
public static Content content;
public ContentServerSocket(xyzService service) throws IOException {
super(PORT);
while (true) {
Log.d(TAG, "Waiting for new request from client(content) ....");
new HandleRequest(accept(), service).start();
}
}
public static void xyzRunAway() {
Log.d(TAG," Content Serv er 1 ");
XYZGONE = true;
}
}
class HandleRequest extends Thread {
private final static String TAG = "ContentServerSocket:Thread for a request:";
private Socket client;
private xyzService service;
private static Context context;
HandleRequest(Socket client, SuggestionService service) {
this.client = client;
this.service = service;
context = xyzService.serviceContext();
}
public void run() {
while (true) {
try {
Log.d(TAG, " Step 1: client: Received request MSG for Check... ");
PrintWriter out = new PrintWriter(client.getOutputStream(),
true);
BufferedReader in = new BufferedReader(new InputStreamReader(
client.getInputStream(), "utf-8"));
String request = "";
String tmpLine = null;
Log.d(TAG, " Step Xyz waiting data from the client ... ");
while ((tmpLine = in.readLine()) != null) {
if (tmpLine.length() > 0) {
request += tmpLine;
//if (tmpLine.toLowerCase().contains("</contentInfo>")) {
if (tmpLine.contains("</contentInfo>")) {
Log.d(TAG, " Server : broke because of </contentInfo>");
break;
}
} else {
Log.d(TAG, " Step NULL : ");
request = "";
}
}
Log.d("Robin", " Step 2: Actual request received from the client : : " + request);
if (request.length() == 0) {
Log.d("Robin",
" client got 0 length request, thread stop!");
throw new Exception();
}
//XMLParser xmlParser = new XMLParser(new ByteArrayInputStream(
// request.getBytes("UTF-8")));
Log.d(TAG, " Step 3 : ");
RequestParser readxmlrequest = new RequestParser(request);
String requestType = readxmlrequest.parsingXmlRequestFromContent();
Log.d(TAG, " Step 4 requestType : " + requestType);
//TODO : need to get the result and pas to the out.println..
//String result = processXML(xmlParser);
String result = responseToContentRequest(readxmlrequest,requestType);//null; //TODO need to complete.
Log.d(TAG, " Step 5 result : "+result);
(((((((((())))))))))";
if (result != null && result.length() > 0) {
//oos.writeObject(result);
Log.d("Robin", " Writing response to socket ... ");
out.println(result + "\n");
out.flush();
Log.d("Robin", " Writing flush completed ");
}
if(ContentServerSocket.XYZGONE) {
Log.d(TAG," XYZGONE >>>>>>>> ");
ContentServerSocket.XYZGONE = false;
String tmp = "<ssr> OK Done .......</ssr>";
out.println(tmp + "\n");
Log.d("Content Server Socket ", "xyz:" + tmp);
out.flush();
}
} catch (IOException ioException) {
Log.d("Robin", " IOException on socket listen: " + ioException);
}
catch (Exception e) {
Log.d("Robin", " outer exception: " + e.toString());
break;
}
finally {
if (client == null || client.isClosed()
|| !client.isConnected()) {
Log.d(" Robin ", " client is null");
break;
}
}
//break;
}
Log.d("Robin", " thread stop... ");
}
So , I fixed it . I just need to maintain two different thread.
1) read.
2)write.
In the above code i just started one more thread for write .
insert the code in Run function of above code.
====================================================
Runnable r1 = new Runnable() {
public void run() {
try {
while (true) {
System.out.println("Hello, world!");
if(ContentServerSocket.XYZGONE) {
Log.d(TAG," XYZGONEY >>>>>>>> ");
ContentServerSocket.XYZGONE = false;
String tmp = "<ssr> OK Done .......</ssr>";
out.println(tmp + "\n");
Log.d("Content Server Socket ", "XYZGONE :" + tmp);
out.flush();
}
Thread.sleep(1000L);
}
} catch (InterruptedException iex) {}
}
};
Thread thr1 = new Thread(r1);
==================================
Then Start the thread in the wile loop of read.
with the following code with a check.
====================================
if(!thr1.isAlive())thr1.start();
Thanks everyone, who respond my question..
Yes it is possible to write data from multiple threads on a server or on a client to an existing socket. However you have to make sure the requests do not overlap, and the receiving side actually knows what is written from who.
If you use a line based protocol you can define each message is a single line. In that case you should synchronize multiple threads in a way that only one is writing parts of that line at any given moment.
Your code is a bit too big to understand where your problem is, sorry.
Maybe this tutorial helps? There are quite many out there:
http://www.javaworld.com/javaworld/jw-12-1996/jw-12-sockets.html

Categories

Resources