I am develop android chat app (xmpp server -prosody- and android smack library)
I created group room successfully and invite members but when I try to send message to the group this stanza error appears :
<message to='rokayah89#eonaws.com/Roo' from='room31#conference.eonaws.com' id='123' type='error'><error type='cancel'><not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></message>
my code for send Message:
MultiUserChat muc = manager.getMultiUserChat(roomBarJid);
Message msg = new Message(roomBarJid);
msg.setType(Message.Type.groupchat);
msg.setBody("Hi there");
msg.setStanzaId("123");
msg.setSubject("Rokayah ..... ");
msg.setTo(roomBarJid);
try {
if (muc != null) {
muc.sendMessage(msg);
} Log.d("GROUP", "The message send..............");
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
and this is listener for receive message:
StanzaFilter filter = new StanzaTypeFilter(Message.class);
mConnection.addSyncStanzaListener(new StanzaListener() {
#Override
public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException {
Message message = (Message) packet;
String body = message.getBody();
Log.d("GROUP" , "here :" +body);
}
}, filter);
I don't know what is wrong with send and receive the listener give me null message body.
Any Help pls!!
you have to first join the room before sending the XMPP message.
to join the xmpp room you have to send a presence stanza that will be like this:
<presence
from='hag66#shakespeare.lit/pda'
id='n13mt3l'
to='coven#chat.shakespeare.lit/thirdwitch'>
<x xmlns='http://jabber.org/protocol/muc'/>
</presence>
In java this will be like:
Presence joinPresence = new Presence(Presence.Type.available);
joinPresence.setTo(mThreadId);
joinPresence.addExtension(new MUCInitialPresence());
XMPPConnection conx = Application.getInstance().getXMPPConection();
PacketFilter responseFilter = new AndFilter(new FromMatchesFilter(mThreadId), new PacketTypeFilter(Presence.class));
PacketCollector response = conx.createPacketCollector(responseFilter);
conx.sendPacket(joinPresence);
Presence presence = (Presence) response.nextResult(SmackConfiguration.getPacketReplyTimeout());
response.cancel();
if (presence == null) {
Log.e("XMPP", "No response from server.");
} else if (presence.getError() != null) {
Log.e("XMPP", presence.getError().toString());
}
First of all, you need to join a room and make sure other group users also join the group as well, for that you have to send a group join invitation like below.
public static void inviteToGroup(String inviteuser, String groupName) {
if (TextUtils.isEmpty(inviteuser) || TextUtils.isEmpty(groupName)) return;
try {
EntityBareJid mucJid = JidCreate.entityBareFrom(groupName + "#" + Constants.GRP_SERVICE);
Resourcepart nickname = Resourcepart.from(userId);
mucChatManager = MultiUserChatManager.getInstanceFor(MyApplication.connection);
mucChat = mucChatManager.getMultiUserChat(mucJid);
Message message = new Message();
// message.setType(Type.normal);
message.setSubject(Constants.GROUP_CHAT_MSG_MODE);
message.setBody(Constants.GROUP_GREETINGS);
EntityBareJid eJId = JidCreate.entityBareFrom(inviteuser + "#" + Constants.XMPP_DOMAIN);
/*MucEnterConfiguration.Builder mucEnterConfiguration
= mucChat.getEnterConfigurationBuilder(nickname).requestHistorySince(sinceDate);*/
MucEnterConfiguration.Builder mucEnterConfiguration
= mucChat.getEnterConfigurationBuilder(nickname).requestNoHistory();
mucChat.join(mucEnterConfiguration.build());
LogM.e("Room joined");
// mucChat.invite(message, eJId, groupName);
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (MultiUserChatException.NotAMucServiceException e) {
e.printStackTrace();
}
}
Here is my code for send Group Message you need to add message Type as a Type.groupchat.
public boolean sendGrpMessage(ChatPojo chatPojo, String grp_name) {
try {
final String body = gson.toJson(chatPojo);
Message msg = new Message();
msg.setType(Type.groupchat);
msg.setSubject("chat");
msg.setBody(body);
EntityBareJid mucJid = JidCreate.entityBareFrom(grp_name + "#" + Constants.GRP_SERVICE);
mucChatManager = MultiUserChatManager.getInstanceFor(MyApplication.connection);
mucChat = mucChatManager.getMultiUserChat(mucJid);
mucChat.sendMessage(msg);
//DataManager.getInstance().updateReceiptReceived(msgReceipt,Constants.MESSAGE_STATUS_NOT_DELIVERED);
return true;
} catch (XmppStringprepException | InterruptedException | SmackException.NotConnectedException e) {
Log.d(TAG, "sendGrpMessage() Error = [" + e.getMessage() + "]");
return false;
}
}
after that add group message listener
StanzaFilter filter = MessageTypeFilter.GROUPCHAT;
MyApplication.connection.addAsyncStanzaListener(new StanzaListener() {
#Override
public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
Message message = (Message) packet;
if (message.getType() == Type.groupchat && message.getBody() != null) {
LogM.e("+++++++++++++++++++++++++++GROUPCHAT+++++++++++++++++++++++++++++++++");
LogM.e("from: " + message.getFrom());
LogM.e("xml: " + message.getType().toString());
LogM.e("Got text [" + message.getBody() + "] from [" + message.getFrom() + "]");
LogM.e("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
} else if (message.getType() == Type.error) {
Toast.makeText(service, "error type", Toast.LENGTH_SHORT).show();
}
}
}, filter);
Related
I use MicareClassic 1k card that have data in sector 0 block 0 and 1. Data is in the format of
tagdata
And i try to read those blocks using following code segment
String resolveNfcIntent(Intent intent) {
final StringBuilder out=new StringBuilder();
String action = intent.getAction();
String msg = "";
String cardStudentId="";
String cardStudentName="";
String mifareKeyA="first 12 hex chars";
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
final Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
final byte keyByte[] = Util.hexStringToByteArray(mifareKeyA);
final Handler mHandler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
MifareClassic mfc = MifareClassic.get(tagFromIntent);
if (mfc == null) {
out.append("card not supported\n");
} else {
String msg;
try {
byte[] data;
out.append("Try to connect card\n");
mfc.connect();// caused IOException when close called from another thread;
out.append("card connected\n");
boolean authenticated = false;
final int SECTOR_INDEX = 0;
out.append("Try to authenticate with key A\n");
authenticated = mfc.authenticateSectorWithKeyA(SECTOR_INDEX, keyByte);
out.append("isCardAuthorizedWith Key A: " + authenticated + "\n");
if (authenticated) {
final int BLOCK_FIRST = mfc.sectorToBlock(SECTOR_INDEX);//Return the first block of a given sector.
final int BLOCK_ID = BLOCK_FIRST + 1;
final int BLOCK_NAME = BLOCK_FIRST + 2;
out.append("try to read id block " + BLOCK_ID + " \n");
data = mfc.readBlock(BLOCK_ID);//causes TagLostException, IOException
String cardStudentId = new String(data, Charset.forName("UTF-8")).trim();
out.append("id read: '" + cardStudentId + "'\ntry to read name block " + BLOCK_NAME + "\n");
data = mfc.readBlock(BLOCK_NAME);
String cardStudentName = new String(data, Charset.forName("UTF-8")).trim();
out.append("name read '" + cardStudentName + "'\n");
} else { // Authentication failed - Handle it
msg = "Nfc card Authentication failed";
out.append(msg + "\n");
Toast.makeText(MainActivity.this, "Nfc card Authentication failed", Toast.LENGTH_SHORT).show();
}
} catch (TagLostException e) {
msg = "Nfc card leaves before read";
out.append(msg + "\n");
} catch (IOException e) {
msg = "Nfc card IO error, try again later";
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
} catch (NullPointerException e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
out.append(sw.toString());
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
out.append(sw.toString());
} finally {
if (mfc != null) {
try {
out.append("try to close tag\n");
mfc.close();
out.append("tag closed\n");
} catch (IOException e) {
out.append("IOError in closing tag connection\n");
Log.e(TAG, "Error closing tag...", e);
}
}
}
}
mHandler.post(new Runnable() {
#Override
public void run() {
txt.setText(out.toString());
}
});
}
}).start();
}
return out.toString();
}
most cases it works well but some times it shows authentication failed error when authenticateWithKeyA() function called here.
i digging more but i can't find what the exact problem is. please guide me right direction.
Thanks
I have been trying to create an android chat app using smack 4.1. Message sending and receiving is working fine, but the problem is same message is getting several times with in the mXmppConnection.addAsyncStanzaListener.I don't know if i have missed to add something to the connection.
This is my connection class:
XMPPTCPConnectionConfiguration.Builder configBuilder = new XMPPTCPConnectionConfiguration.builder();
configBuilder.setUsernameAndPassword(mUser, "password#123");
configBuilder.setPort(5555);
configBuilder.setServiceName("tvm.myname.com");
configBuilder.setDebuggerEnabled(true); configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
try
{
XMPPTCPConnection mConnection = new XMPPTCPConnection(configBuilder.build());
mConnection.connect();
mConnection.login();
}
catch (SmackException e)
{
}
And this the code where message receives:
mXmppConnection.addAsyncStanzaListener(new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
Message message = (Message)packet;
Log.i("XMPPClient", "****** message " + message);
// code for handling message
} `enter code here`
},null);
The real problem is i am getting the message several times..the value of message is printing in the logs several time. Please help me....
FINALLY GOT SOLUTION
The issue is not with the client but due to careless coding. I have been assigning single instance of connection object to a class variable and listener is adding to these reference object every time. So that leads to calling listener multiple times....The fix is done by adding listener to the singleton connection object.
I don't know is there any best approach for keeping the xmpp connection stable through out the application.If anyone knows a better solution please post the answer here. I am using a global connection variable, all the chat operations are done by making use of this static connection variable. This is working for me.
For sending and receiving messages using smack we need to make connection with xmpp server.
public static AbstractXMPPConnection getInstance(Context context) {
mContext = context;
sendMessageCallBack = (XmppSendMessageCallBack) context;
if (mConnection == null) {
mInstance = new XmppClient();
mUser = new Preferences(context).getPhone();
setUserToServer();
}
return mConnection;
}
private static void setUserToServer() {
new Thread(new Runnable() {
#Override
public void run() {
try {
Looper.prepare();
/** connecting to server ***/
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
configBuilder.setServiceName(Constants.HOST_URL);
configBuilder.setDebuggerEnabled(true);
configBuilder.setSendPresence(true);
configBuilder.setConnectTimeout(XMPPTCPConnectionConfiguration.DEFAULT_CONNECT_TIMEOUT);
configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
String[] sslProtocols = {"starttls"
, "no_sslv3"
, "no_tlsv1"};
configBuilder.setEnabledSSLProtocols(sslProtocols);
mConnection = new XMPPTCPConnection(configBuilder.build());
mConnection.setPacketReplyTimeout(120000);
mConnection.connect();
// Log into the server
if(mConnection!=null) {
mConnection.login(mUser, "password#123");
reConnectionSetUp();
PingManager pingManager = PingManager.getInstanceFor(mConnection);
pingManager.setPingInterval(60000);
pingManager.pingMyServer();
pingManager.registerPingFailedListener(new PingFailedListener() {
#Override
public void pingFailed() {
if (mConnection != null && !mConnection.isConnected())
setUserToServer();
}
});
setUpListenersForXmppConnection(mConnection);
}
} catch (SmackException.ConnectionException e) {
Log.e("XmppClient", "ConnectionException :", e);
Toast.makeText(mContext,"failed to connect to server",Toast.LENGTH_SHORT).show();
} catch (SmackException.NoResponseException e) {
Log.e("XmppClient", "NoResponseException :", e);
Toast.makeText(mContext,"Connection time out please try again",Toast.LENGTH_SHORT).show();
} catch (XMPPException e) {
Log.e("XmppClient", "XMPPException :", e);
}catch (IOException e) {
Log.e("XmppClient", "IOException :", e);
}catch (SmackException.NotConnectedException e) {
Log.e("XmppClient", "NotConnectedException :", e);
reConnectionSetUp();
}catch (SmackException e) {
Log.e("XmppClient", "SmackException :", e);
}catch (NullPointerException e) {
Log.e("XmppClient", "NullPointerException :", e);
}
}
}).start();
}
private static void setUpListenersForXmppConnection(AbstractXMPPConnection xmppConnection){
try {
if(xmppConnection!=null) {
sendOnlineStatus();
/** adding connection listener **/
xmppConnection.addConnectionListener(mInstance);
/** adding privacy manager to connection **/
if(xmppConnection!=null)
mPrivacyListManager = PrivacyListManager.getInstanceFor(xmppConnection);
/** adding packet listener for receving incoming packets **/
StanzaFilter filter = MessageTypeFilter.NORMAL;
if(xmppConnection!=null && mInstance!=null)
xmppConnection.addSyncStanzaListener(mInstance, null);
}
} catch (SmackException e) {
Log.e("XmppClient", "IOException :", e);
} catch (XMPPException e) {
Log.e("XmppClient", "XMPPException :", e);
e.printStackTrace();
} catch (NullPointerException e) {
Log.e("XmppClient", "NullPointerException :", e);
} catch (ConcurrentModificationException e){
Log.e("XmppClient", "ConcurrentModificationException :", e);
} catch (IllegalArgumentException e){
e.printStackTrace();
}catch (RetrofitError e){
Log.e("XmppClient", "RetrofitError :", e);
}
}
When we receive a message the following method will be invoked
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
if(packet instanceof Message) {
Message message = (Message) packet;
// Do your task
}
}
We can send message by creating a message object of smack like this,
Message message = new Message();
message.setFrom(senderId);
message.setBody(body);
message.setSubject(subject);
message.setTo(receiverId);
try {
if(mConnection!=null){
ChatManager chatManager = ChatManager.getInstanceFor(mConnection);
if(chatManager!=null){
chatManager.createChat(message.getTo(), new ChatStateListener() {
#Override
public void stateChanged(Chat chat, ChatState state) {
Log.e("XMPPClient", "******* stateChanged "+state);
}
#Override
public void processMessage(Chat chat, Message message) {
Log.e("XMPPClient", "******* processMessage "+message.getSubject());
}
}).sendMessage(message);
}
}
sendMessageCallBack.messageSuccessfullySend(message.getStanzaId(), status);
}catch (SmackException.NotConnectedException e){
Log.e("XMPPClient", "******* NotConnectedException ", e);
sendMessageCallBack.messageSendingFailed("");
}catch(NullPointerException e){
Log.e("XMPPClient", "******* NullPointerException ", e);
sendMessageCallBack.messageSendingFailed("");
}catch (Exception e){
sendMessageCallBack.messageSendingFailed("No Network");
}
Same problem I have faced but I got the solution, you don't unregistered your BroadcastReceiver when you logout from app below is code of logout and also you make all the connection is singleton.
try {
Presence pr=new Presence(Presence.Type.unavailable);
pr.setStatus(RoosterConnection.getConnection().getUser() + "false");
RoosterConnection.getConnection().sendStanza(pr);
if (mConnection != null) {
mConnection.disconnect();
}
// mBus.unregister(this);
mConnection = null;
// Unregister the message broadcast receiver.
if (uiThreadMessageReceiver != null) {
mApplicationContext.unregisterReceiver(uiThreadMessageReceiver);
uiThreadMessageReceiver = null;
}
Intent intent = new Intent(this,LoginActivity.class);
startActivity(intent);
finish();}catch(SmackException.NotConnectedException e){ e.printStackTrace();}catch(InterruptedException e){
e.printStackTrace();}
Just use addSyncStanzaListener instead addAsyncStanzaListener
My application listens to a socket. The application is connected to the socket using the following method.
public void connect() {
this.connectionStatus = CONNECT_STATUS_CONNECTING;
Log.v(AppConstants.DEBUG_TAG, userId + " : Connecting to Server");
if (mThread != null && mThread.isAlive()) {
return;
}
mThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread Action Started");
String secret = createSecret();
int port = (mURI.getPort() != -1) ? mURI.getPort() : (mURI.getScheme().equals("wss") ? 443 : 80);
String path = TextUtils.isEmpty(mURI.getPath()) ? "/" : mURI.getPath();
if (!TextUtils.isEmpty(mURI.getQuery())) {
path += "?" + mURI.getQuery();
}
String originScheme = mURI.getScheme().equals("wss") ? "https" : "http";
URI origin = new URI(originScheme, "//" + mURI.getHost(), null);
SocketFactory factory = mURI.getScheme().equals("wss") ? getSSLSocketFactory() : SocketFactory.getDefault();
mSocket = factory.createSocket(mURI.getHost(), port);
PrintWriter out = new PrintWriter(mSocket.getOutputStream());
out.print("GET " + path + " HTTP/1.1\r\n");
out.print("Upgrade: websocket\r\n");
out.print("Connection: Upgrade\r\n");
out.print("Host: " + mURI.getHost() + "\r\n");
out.print("Origin: " + origin.toString() + "\r\n");
out.print("Sec-WebSocket-Key: " + secret + "\r\n");
out.print("Sec-WebSocket-Version: 13\r\n");
if (mExtraHeaders != null) {
for (NameValuePair pair : mExtraHeaders) {
out.print(String.format("%s: %s\r\n", pair.getName(), pair.getValue()));
}
}
out.print("\r\n");
out.flush();
HybiParser.HappyDataInputStream stream = new HybiParser.HappyDataInputStream(mSocket.getInputStream());
// Read HTTP response status line.
StatusLine statusLine = parseStatusLine(readLine(stream));
if (statusLine == null) {
Log.v(AppConstants.DEBUG_TAG, "Received no reply from server.");
throw new HttpException("Received no reply from server.");
} else if (statusLine.getStatusCode() != HttpStatus.SC_SWITCHING_PROTOCOLS) {
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
// Read HTTP response headers.
String line;
boolean validated = false;
while (!TextUtils.isEmpty(line = readLine(stream))) {
Header header = parseHeader(line);
if (header.getName().equals("Sec-WebSocket-Accept")) {
String expected = createSecretValidation(secret);
String actual = header.getValue().trim();
if (!expected.equals(actual)) {
Log.v(AppConstants.DEBUG_TAG, "Bad Sec-WebSocket-Accept header value.");
throw new HttpException("Bad Sec-WebSocket-Accept header value.");
}
validated = true;
}
}
if (!validated) {
Log.v(AppConstants.DEBUG_TAG, "No Sec-WebSocket-Accept header.");
throw new HttpException("No Sec-WebSocket-Accept header.");
}
onConnect();
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread should be connected by now");
// Now decode websocket frames.
mParser.start(stream);
} catch (EOFException ex) {
Log.d(AppConstants.DEBUG_TAG, "WebSocket EOF!", ex);
onDisconnect(0, "EOF");
} catch (SSLException ex) {
// Connection reset by peer
Log.d(AppConstants.DEBUG_TAG, "Websocket SSL error!", ex);
onDisconnect(0, "SSL");
} catch (Exception ex) {
onError(ex);
}
}
});
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread about to be started");
mThread.start();
}
Here the problem is when I leave the application for 15 or more idle, the connection automatically closes and app becomes unusable.What is the reason behind it and how to resolve this?
Probably, it is the server that closes the idle connection. Send Ping (or Pong) periodically to keep the connection.
BTW, I guess your code is based on a certain open-source WebSocket library. If so, note that it is not of commercial quality. It does not perform even the closing handshake on disconnect().
My android app is connected to the server through socket, which is coded in node.js. When the is left in the foreground for 15 minutes it losses connection to the server. The following is the code that connects the sockt to the server
public void connect() {
this.connectionStatus = CONNECT_STATUS_CONNECTING;
Log.v(AppConstants.DEBUG_TAG, userId + " : Connecting to Server");
if (mThread != null && mThread.isAlive()) {
return;
}
mThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread Action Started");
String secret = createSecret();
int port = (mURI.getPort() != -1) ? mURI.getPort() : (mURI.getScheme().equals("wss") ? 443 : 80);
String path = TextUtils.isEmpty(mURI.getPath()) ? "/" : mURI.getPath();
if (!TextUtils.isEmpty(mURI.getQuery())) {
path += "?" + mURI.getQuery();
}
String originScheme = mURI.getScheme().equals("wss") ? "https" : "http";
URI origin = new URI(originScheme, "//" + mURI.getHost(), null);
SocketFactory factory = mURI.getScheme().equals("wss") ? getSSLSocketFactory() : SocketFactory.getDefault();
mSocket = factory.createSocket(mURI.getHost(), port);
mSocket.setKeepAlive(true);
PrintWriter out = new PrintWriter(mSocket.getOutputStream());
out.print("GET " + path + " HTTP/1.1\r\n");
out.print("Upgrade: websocket\r\n");
out.print("Connection: Upgrade\r\n");
out.print("Host: " + mURI.getHost() + "\r\n");
out.print("Origin: " + origin.toString() + "\r\n");
out.print("Sec-WebSocket-Key: " + secret + "\r\n");
out.print("Sec-WebSocket-Version: 13\r\n");
if (mExtraHeaders != null) {
for (NameValuePair pair : mExtraHeaders) {
out.print(String.format("%s: %s\r\n", pair.getName(), pair.getValue()));
}
}
out.print("\r\n");
out.flush();
HybiParser.HappyDataInputStream stream = new HybiParser.HappyDataInputStream(mSocket.getInputStream());
// Read HTTP response status line.
StatusLine statusLine = parseStatusLine(readLine(stream));
if (statusLine == null) {
Log.v(AppConstants.DEBUG_TAG, "Received no reply from server.");
throw new HttpException("Received no reply from server.");
} else if (statusLine.getStatusCode() != HttpStatus.SC_SWITCHING_PROTOCOLS) {
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
// Read HTTP response headers.
String line;
boolean validated = false;
while (!TextUtils.isEmpty(line = readLine(stream))) {
Header header = parseHeader(line);
if (header.getName().equals("Sec-WebSocket-Accept")) {
String expected = createSecretValidation(secret);
String actual = header.getValue().trim();
if (!expected.equals(actual)) {
Log.v(AppConstants.DEBUG_TAG, "Bad Sec-WebSocket-Accept header value.");
throw new HttpException("Bad Sec-WebSocket-Accept header value.");
}
validated = true;
}
}
if (!validated) {
Log.v(AppConstants.DEBUG_TAG, "No Sec-WebSocket-Accept header.");
throw new HttpException("No Sec-WebSocket-Accept header.");
}
onConnect();
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread should be connected by now");
// Now decode websocket frames.
mParser.start(stream);
} catch (EOFException ex) {
Log.d(AppConstants.DEBUG_TAG, "WebSocket EOF!", ex);
onDisconnect(0, "EOF");
} catch (SSLException ex) {
// Connection reset by peer
Log.d(AppConstants.DEBUG_TAG, "Websocket SSL error!", ex);
onDisconnect(0, "SSL");
} catch (Exception ex) {
onError(ex);
}
}
});
Log.v(AppConstants.DEBUG_TAG, userId + " : Thread about to be started");
mThread.start();
}
anu solution to this problem?
After googling a lot I found out a solution to this problem. Add timeout to the socket connection.
mSocket.setSoTimeout(10*1000);
If there isn't any response, after 10 seconds it will throw SocketTimeoutException and in the catch of this exception close the connection if exists, then connect again.
catch (SocketTimeoutException e) {
if (mSocket.isConnected()) {
disconnect();
}
connect();
}
This is a simple example that shows how to set the timeout on a java socket :
sockAdr = new InetSocketAddress(SERVER_HOSTNAME, SERVER_PORT);
socket = new Socket();
timeout = 5000; // 5 seconds
socket.connect(sockAdr, timeout);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream());
while ((data = reader.readLine())!=null)
log.e(TAG, "received -> " + data);
log.e(TAG, "Socket closed !");
Thanks for paying attention over the question...
I am making a XMPP chat application with the help of ejabbered and asmack_4.1 library.
I have installed a PSI client for windows to chat with the android device.
I am able to perform text chat between devices.
I am also able to send file from device to PSI client and PSI client to android device.
But the problem is to send files device to device.
I am using below code to send and receive files :
File send :
public void fileTransfer(String filenameWithPath, Bitmap thumbnail, String userId) {
// FileTransferManager manager = new FileTransferManager(connection);
FileTransferManager manager = FileTransferManager.getInstanceFor(connection);
// OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer("usre2#myHost/Smack");
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(userId + "/Admin"); // "/Good" depends on server
// OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(userId + "/Directors-iMac");
File file = new File(filenameWithPath);
try {
transfer.sendFile(file, "test_file");
} catch (SmackException e) {
e.printStackTrace();
}
while (!transfer.isDone()) {
if (transfer.getStatus().equals(FileTransfer.Status.error)) {
System.out.println("ERROR!!! " + transfer.getError());
} else if (transfer.getStatus().equals(FileTransfer.Status.cancelled)
|| transfer.getStatus().equals(FileTransfer.Status.refused)) {
System.out.println("Cancelled!!! " + transfer.getError());
}
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (transfer.getStatus().equals(FileTransfer.Status.refused) || transfer.getStatus().equals(FileTransfer.Status.error)
|| transfer.getStatus().equals(FileTransfer.Status.cancelled)) {
System.out.println("refused cancelled error " + transfer.getError());
} else {
System.out.println("Success");
}
}
File Receiving :
public void fileReciever(AbstractXMPPConnection connection) {
//**************************************
// Create the file transfer manager
final FileTransferManager managerListner = FileTransferManager.getInstanceFor(connection);
// FileTransferNegotiator.setServiceEnabled(connection, true);
FileTransferNegotiator negotiator = FileTransferNegotiator.getInstanceFor(connection);
Log.i("File transfere manager", "created");
// Create the listener
managerListner
.addFileTransferListener(new FileTransferListener() {
#Override
public void fileTransferRequest(FileTransferRequest request) {
Log.i("Recieve File", "new file transfere request new file transfere request new file transfere request");
Log.i("file request", "from" + request.getRequestor());
IncomingFileTransfer transfer = request.accept();
Log.i(RECIEVE_FILE_ALERT_DIALOG, "accepted");
try {
transfer.recieveFile(new File("/sdcard/" + request.getFileName()));
while (!transfer.isDone() || (transfer.getProgress() < 1)) {
Log.i(RECIEVE_FILE_ALERT_DIALOG, "still receiving : " + (transfer.getProgress()) + " status " + transfer.getStatus());
if (transfer.getStatus().equals(FileTransfer.Status.error)) {
// Log.i("Error file",
// transfer.getError().getMessage());
Log.i("Recieve File",
"cancelling still receiving : "
+ (transfer.getProgress())
+ " status "
+ transfer.getStatus());
transfer.cancel();
break;
}
}
} /*catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/ catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
//**************************************
}
Note : In fileTransfer() method, I am using below line:
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(userId + "/Admin"); // "/Good" depends on server
I am able to send files from Android device to PSI desktop application and vice versa but i am not able to transfer files between android devices.