I use Quickblox for chat room
My code:
final QBChatDialog dialog = DialogUtils.buildPrivateDialog(id);
dialog.setType(QBDialogType.PRIVATE);
QBRestChatService.createChatDialog(dialog).performAsync(new QBEntityCallback<QBChatDialog>() {
#Override
public void onSuccess(QBChatDialog result, Bundle params) {
try {
QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setBody("Hi there!");
dialog.sendMessage(chatMessage);
} catch (SmackException.NotConnectedException e) {
Log.i("errorCheck", "Chat: NO : " + e.getMessage());
}
}
#Override
public void onError(QBResponseException responseException) {
Log.i("errorCheck", "Chat: FAIL" + responseException.getMessage());
}
});
I get this error :
Client is not, or no longer, connected. error
But I'm sure my client is connected
You need to do the following before sending message:
qbChatDialog.initForChat(QBChatService.getInstance());
Related
I am trying to learn basic MQTT integration in Android. I am using a mosquitto broker to publish and subscribe messages. I am running the code on a real device and getting this exception :
Unable to connect to server (32103) - java.net.ConnectException:
failed to connect to /192.168.0.103 (port 1883) after
30000ms: isConnected failed: ECONNREFUSED
Here's my code:
public class HomeActivity extends AppCompatActivity{
private MqttAndroidClient client;
private final MemoryPersistence persistence = new MemoryPersistence();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://192.168.0.103:1883", "androidSampleClient", persistence);
mqttAndroidClient.setCallback(new MqttCallback() {
#Override
public void connectionLost(Throwable cause) {
System.out.println("Connection was lost!");
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("Message Arrived!: " + topic + ": " + new String(message.getPayload()));
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("Delivery Complete!");
}
});
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
System.out.println("Connection Success!");
try {
System.out.println("Subscribing to /test");
mqttAndroidClient.subscribe("/test", 0);
System.out.println("Subscribed to /test");
System.out.println("Publishing message..");
mqttAndroidClient.publish("/test", new MqttMessage("Hello world testing..!".getBytes()));
} catch (MqttException ex) {
}
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
System.out.println("Connection Failure!");
System.out.println("throwable: " + exception.toString());
}
});
} catch (MqttException ex) {
System.out.println(ex.toString());
}
}
}
I've tried using different ports but the error is same. Can anyone help what am i doing wrong?
As you are getting started, you need to see see how different implementations work. Take a look at my implementation. I use a separated class for MQTT specific stuff.
MqttUtil.java
public class MqttUtil {
private static final String MQTT_TOPIC = "test/topic";
private static final String MQTT_URL = "tcp://localhost:1883";
private static boolean published;
private static MqttAndroidClient client;
private static final String TAG = MqttUtil.class.getName();
public static MqttAndroidClient getClient(Context context){
if(client == null){
String clientId = MqttClient.generateClientId();
client = new MqttAndroidClient(context, MQTT_URL, clientId);
}
if(!client.isConnected())
connect();
return client;
}
private static void connect(){
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
mqttConnectOptions.setKeepAliveInterval(30);
try{
client.connect(mqttConnectOptions, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d(TAG, "onSuccess");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.d(TAG, "onFailure. Exception when connecting: " + exception);
}
});
}catch (Exception e) {
Log.e(TAG, "Error while connecting to Mqtt broker : " + e);
e.printStackTrace();
}
}
public static void publishMessage(final String payload){
published = false;
try {
byte[] encodedpayload = payload.getBytes();
MqttMessage message = new MqttMessage(encodedpayload);
client.publish(MQTT_TOPIC, message);
published = true;
Log.i(TAG, "message successfully published : " + payload);
} catch (Exception e) {
Log.e(TAG, "Error when publishing message : " + e);
e.printStackTrace();
}
}
public static void close(){
if(client != null) {
client.unregisterResources();
client.close();
}
}
}
And you can simply use it in your HomeActivity. Check it below:
public class HomeActivity extends AppCompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get Mqtt client singleton instance
MqttUtil.getClient(this);
// Publish a sample message
MqttUtil.publishMessage("Hello Android MQTT");
}
}
For testing purposes, use your Mosquitto sub client and see if you get the message.
Hope that helps!
try using port 8883
String clientId = MqttClient.generateClientId();
final MqttAndroidClient client =
new MqttAndroidClient(this.getApplicationContext(), "ssl://iot.eclipse.org:8883",
clientId);
try {
MqttConnectOptions options = new MqttConnectOptions();
InputStream input =
this.getApplicationContext().getAssets().open("iot.eclipse.org.bks");
options.setSocketFactory(client.getSSLSocketFactory(input, "eclipse-password"));
IMqttToken token = client.connect(options);
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
// We are connected
Log.d(TAG, "onSuccess");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
// Something went wrong e.g. connection timeout or firewall problems
Log.d(TAG, "onFailure");
}
});
} catch (MqttException | IOException e) {
e.printStackTrace();
}
I am using the code from the official documentation of smack API to send message to a specific Jabber ID.
CLick Here
I am able to receive messages from a room using below code.
public void joinChatRoom(){
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
multiUserChat = manager.getMultiUserChat("test#-mbp-9");
try {
multiUserChat.join("user");
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
ChatManager.getInstanceFor(connection).addChatListener(new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally) {
chat.addMessageListener(new ChatMessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
System.out.println(message.getBody());
}
});
}
});
System.out.println("Test");
}
My Question is that how can I send message to a specific JID because i am not able to work it out even after a lot of googling what i am missing. Connection is fine user is also authenticating but below code is now working for send message.
public void sendMsg() {
if (connection.isConnected()) {
// Assume we've created an XMPPConnection name "connection"._
chatmanager = ChatManager.getInstanceFor(connection);
newChat = chatmanager.createChat("user123#csofts-mbp-9", new ChatMessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
System.out.println("Received Message:"+message);
}
});
try {
System.out.println("check the message....");
newChat.sendMessage("Howdy!alksd;lsakdsa;lkdsa;lksa;lsa");
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
Any Help will be appreciated Thanks.
Here is example of sending message code from my last project:
private void sendMessage(String body, String toJid) {
try {
Jid jid = JidCreate.from(toJid + "#" + MyApplication.CHAT_DOMAIN);
Chat chat = ChatManager.getInstanceFor(mConnection)
.createChat(jid.asJidWithLocalpartIfPossible());
chat.sendMessage(body);
} catch (Exception e) {
}
}
UPDATE:
How to receive a message:
When you are authenticated:
ChatManager.getInstanceFor(mConnection).addChatListener(YourConnectionClass.this);
(YourConnectionClass should implement ChatManagerListener and ChatMessageListener)
Also you need to implement the methods below:
#Override
public void chatCreated(Chat chat, boolean b) {
chat.addMessageListener(ChatConnection.this);
}
#Override
public void processMessage(Chat chat, Message message) {
if (message.getType().equals(Message.Type.chat) || message.getType().equals(Message.Type.normal)) {
if (message.getBody() != null) {
Jid jid = message.getFrom();
Localpart localpart = jid.getLocalpartOrNull();
...
}
}
}
Please follow few steps for one to one communication in xmpp:
In StanzaListener you have got all message with adding connection between two person but if you want specific get two person chat then use ChatMessageListener.
Step 1. Declare as a global variables
ChatManagerListener chatListener;
ChatMessageListener messageListener;
Chat chat;
private Jid opt_jid;
StanzaListener packetListener;
Step 2. Use this code in oncreate or in fragment
Note: Make sure you have connected with chat server.
try {
String opt_jidStr = "user_" + userid;
try {
opt_jid = JidCreate.bareFrom(Localpart.from(opt_jidStr), Domainpart.from(Common.HOST));
PurplkiteLogs.logError(TAG,"opt jid :" + opt_jid);
} catch (XmppStringprepException e) {
e.printStackTrace();
}
messageListener = new ChatMessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
AppLogs.logInfo(TAG, "chat get me something " + message.getBody());
}
};
packetListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
if (packet instanceof Message) {
final Message message = (Message) packet;
}
}
};
chatListener = new ChatManagerListener() {
#Override
public void chatCreated(Chat chatCreated, boolean local) {
onChatCreated(chatCreated);
}
};
XMPP.getInstance().getConnection(acitiviy)).addAsyncStanzaListener(stanzaListener, null);
ChatManager.getInstanceFor(XMPP.getInstance().getConnection(acitiviy)))
.addChatListener(chatManagerListener);
ServiceDiscoveryManager sdm = ServiceDiscoveryManager
.getInstanceFor(XMPP.getInstance().getConnection(acitiviy)));
sdm.addFeature("jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
try {
String addr1 = XMPP.getInstance().getUserLocalPart(getActivity());
String addr2 = opt_jid.toString();
if (addr1.compareTo(addr2) > 0) {
String addr3 = addr2;
addr2 = addr1;
addr1 = addr3;
}
chat = ChatManager.getInstanceFor(
XMPP.getInstance().getConnection(acitiviy)))
.getThreadChat(party1 + "-" + party2);
AppLogs.logInfo(TAG, "chat value single chat :" + chat + " , " + addr2 + " , " + addr1);
// for subscribed the user
Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo(opt_jidStr);
XMPP.getInstance().getConnection(acitiviy)).sendStanza(packet);
// for subscribed the user
if (chat == null) {
chat = ChatManager.getInstanceFor(
XMPP.getInstance().getConnection(acitiviy))
.createChat(jid, party1 + "-" + party2,
messageListener);
AppLogs.logInfo(TAG, "chat value single chat 1 :" + chat);
} else {
chat.addMessageListener(messageListener);
AppLogs.logInfo(TAG, "chat value single chat 2:" + chat);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch(Exception e) {
e.printStackTrace();
}
Step 3. Methods for one to one chat purposer
void onChatCreated(Chat chatCreated) {
if (chat != null) {
if (chat.getParticipant().getLocalpart().toString().equals(
chatCreated.getParticipant().getLocalpart().toString())) {
chat.removeMessageListener(messageListener);
chat = chatCreated;
chat.addMessageListener(messageListener);
}
} else {
chat = chatCreated;
chat.addMessageListener(messageListener);
}
}
void sendMessage(String message) {
if (chat != null) {
try {
chat.sendMessage(message);
} catch (SmackException.NotConnectedException e) {
} catch (Exception e) {
}
}
}
Step 4. On destroy
XMPP.getInstance().removeChatListener(getActivity(), chatListener);
if (chat != null && messageListener != null) {
XMPP.getInstance().getConnection(acitiviy)).removeAsyncStanzaListener(stanzaListener);
chat.removeMessageListener(messageListener);
}
Hope this will help you and if you want more information take a look from here.
Thankyou
I'm developing a simple WebSocket in Android using AndroidAsync library:
http://www.koushikdutta.com/AndroidAsync
My Client code:
private void conectar() {
//String uri = "ws://192.167.101.142:1234";
String uri = "http://192.167.101.166:1234";
AsyncHttpClient asyncHttpClient = AsyncHttpClient.getDefaultInstance();
//asyncHttpClient.websocket(new AsyncHttpGet(uri), "my-protocol", new AsyncHttpClient.WebSocketConnectCallback() {
//asyncHttpClient.websocket(uri, "https", new AsyncHttpClient.WebSocketConnectCallback() {
//asyncHttpClient.websocket(new AsyncHttpGet(uri), null, new AsyncHttpClient.WebSocketConnectCallback() {
//asyncHttpClient.websocket(new AsyncHttpGet(uri), "SSL", new AsyncHttpClient.WebSocketConnectCallback() {
asyncHttpClient.websocket(uri, null, new AsyncHttpClient.WebSocketConnectCallback() {
#Override
public void onCompleted(Exception ex, WebSocket webSocket) {
Log.e(TAG, "webSocket is null");
Log.e(TAG, "Metodo onCompleted");
if (ex != null) {
Log.e(TAG, ex.getMessage(), ex);
return;
}
//Log.e(TAG, "webSocket.isOpen(): " + webSocket.isOpen());
webSocket.send("a string");
webSocket.send(new byte[10]);
webSocket.setStringCallback(new WebSocket.StringCallback() {
public void onStringAvailable(String s) {
System.out.println("I got a string: " + s);
Log.e(TAG, "I got a string: " + s);
//showToast("I got a string: " + s);
}
});
webSocket.setDataCallback(new DataCallback() {
#Override
public void onDataAvailable(DataEmitter emitter, ByteBufferList byteBufferList) {
System.out.println("I got some bytes!");
Log.e(TAG, "I got some bytes!");
// note that this data has been read
byteBufferList.recycle();
}
});
}
});
}
My Server code:
private void conectar() {
AsyncHttpServer server = new AsyncHttpServer();
server.listen(PORTA);
server.get("/", new HttpServerRequestCallback() {
#Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
response.send("Hello!!!");
}
});
server.websocket("/", new AsyncHttpServer.WebSocketRequestCallback() {
#Override
public void onConnected(final WebSocket webSocket, AsyncHttpServerRequest request) {
Log.e(TAG, "Metodo: onConnected");
_sockets.add(webSocket);
//Use this to clean up any references to your websocket
webSocket.setClosedCallback(new CompletedCallback() {
#Override
public void onCompleted(Exception ex) {
Log.e(TAG, "Metodo onCompleted from webSocket object");
try {
if (ex != null)
Log.e("WebSocket", "Error");
} finally {
_sockets.remove(webSocket);
}
}
});
webSocket.setStringCallback(new WebSocket.StringCallback() {
#Override
public void onStringAvailable(String s) {
Log.e(TAG, "Metodo onStringAvailable from webSocket object");
if ("Hello Server".equals(s))
webSocket.send("Welcome Client!");
}
});
}
});
Anyone knows tell me why Can't I connect my server?
I have tested the server code in another app websocket tester from google play.
The app server it's Ok.
However I cannot connect from my client app?
I'm implement Autobahn to connnect to a server through WebSockets. When I hit connect, it opens the socket correctly and logs that socket is opened. I then try to send a request to the server which is simply {"request":"getSoftwareVersion"} , when the server receives this, it should send back the software version in a JSON object, the trouble is, that onMessage is never hit. Here is my code:
public class AutoBahnConnectRequest extends Request{
private static WebSocketConnection mAutoBahnConnection;
private String mSocketHostAddress;
private final static String m_TAG = AutoBahnConnectRequest.class.getSimpleName();
public AutoBahnConnectRequest(String SocketHostAddress){
this.mAutoBahnConnection = new WebSocketConnection();
this.mSocketHostAddress = SocketHostAddress;
}
#Override
protected Void doInBackground(Void... params){
try {
mAutoBahnConnection.connect(mSocketHostAddress, new WebSocketHandler(){
#Override
public void onOpen() {
String requestSoftware = "{\"request\":\"getSoftwareVersion\"}";
Log.i(m_TAG, requestSoftware);
Log.i(m_TAG, "Status: Connected to " + mSocketHostAddress);
mAutoBahnConnection.sendTextMessage(requestSoftware);
}
#Override
public void onTextMessage(String payload) {
Log.i(m_TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.i(m_TAG, "Connection lost."+ reason);
}
});
} catch (WebSocketException e) {
Log.d(m_TAG, e.toString());
}
return null;
}
}
This has been implemented with a html client like so (not with autobahn):
function getSoftwareVersion() {
socket_di.send('{"request":"getSoftwareVersion"}');
}
and the onMessage receives the data. Can someone please tell me if I'm doing something wrong here?
Thank you.
I have figured out my issue regarding this. The WebSocket connection required a protocol and options to be added. So I changed this:
mAutoBahnConnection.connect(mSocketHostAddress, new WebSocketHandler(){
#Override
public void onOpen() {
String requestSoftware = "{\"request\":\"getSoftwareVersion\"}";
Log.i(m_TAG, requestSoftware);
Log.i(m_TAG, "Status: Connected to " + mSocketHostAddress);
mAutoBahnConnection.sendTextMessage(requestSoftware);
}
#Override
public void onTextMessage(String payload) {
Log.i(m_TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.i(m_TAG, "Connection lost."+ reason);
}
});
} catch (WebSocketException e) {
Log.d(m_TAG, e.toString());
}
to this:
mAutoBahnConnection.connect(mSocketHostAddress,new String[]{"this is my protocol"} ,new WebSocketHandler(){
#Override
public void onOpen() {
String requestSoftware = "{\"request\":\"getSoftwareVersion\"}";
Log.i(m_TAG, requestSoftware);
Log.i(m_TAG, "Status: Connected to " + mSocketHostAddress);
mAutoBahnConnection.sendTextMessage(requestSoftware);
}
#Override
public void onTextMessage(String payload) {
Log.i(m_TAG, "Got echo: " + payload);
}
#Override
public void onRawTextMessage(byte[] payload) {
try {
rawText = new String(payload, "UTF-8");
Log.i(m_TAG, "ON RAW TEXT");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
#Override
public void onBinaryMessage(byte[] payload) {
Log.i(m_TAG, "ON BINARY MESSAGE");
}
#Override
public void onClose(int code, String reason) {
Log.i(m_TAG, "Connection lost."+ reason);
}
}, options);
} catch (WebSocketException e) {
Log.d(m_TAG, e.toString());
}
How to get Offline and online user in quickblox private chat between two user.
If two user Jone and kally if kally is offline than how to get status of offline user Kally my code here. Please check and help me.
try {
QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setBody(inputbox.getText().toString());
chatMessage.setProperty("save_to_history", "1");
long time = System.currentTimeMillis()/1000;
chatMessage.setProperty("date_sent", time + "");
privateChat.sendMessage(chatMessage);
showMessage(chatMessage);
inputbox.setText("");
} catch (XMPPException e) {
Log.e("XMPPException",e.toString());
} catch (SmackException.NotConnectedException e) {
Log.e("Not Connected Exception",e.toString());
}catch (NullPointerException e) {
Log.e("NullPointerException", e.toString());
}catch (Exception e) {
Log.e("Exception", e.toString());
}
QBPrivateChatManagerListener privateChatManagerListener = new QBPrivateChatManagerListener() {
#Override
public void chatCreated(final QBPrivateChat privateChat, final boolean createdLocally) {
if(!createdLocally){
privateChat.addMessageListener(privateChatMessageListener);
}
}
};
QBMessageListener<QBPrivateChat> privateChatMessageListener = new QBMessageListener<QBPrivateChat>() {
#Override
public void processMessage(QBPrivateChat privateChat, final QBChatMessage chatMessage) {
Log.w(Tag, "new incoming message: chatMessage" + chatMessage);
showMessage(chatMessage);
playBeepSound(mContext);
}
#Override
public void processError(QBPrivateChat privateChat, QBChatException error, QBChatMessage originMessage){
Log.w(Tag, "new incoming message: originMessage" + originMessage);
}
#Override
public void processMessageDelivered(QBPrivateChat privateChat, String messageID){
Log.w(Tag, "new incoming message:messageID " + messageID);
}
#Override
public void processMessageRead(QBPrivateChat privateChat, String messageID){
Log.w(Tag, "new incoming message:messageID messageID" + messageID);
}
};
private void createNewDialog(){
privateChatManager = QBChatService.getInstance().getPrivateChatManager();
privateChatManager.createDialog(opponentId, new QBEntityCallbackImpl<QBDialog>() {
#Override
public void onSuccess(QBDialog dialog, Bundle args) {
//Log.e("QBdialog", ""+dialog);
//Log.e("id", dialog.getDialogId());
setUpListener();
isQBDialog = true;
}
#Override
public void onError(List<String> errors) {
Log.e("errors", ""+errors);
isQBDialog = false;
}
});
}
private void setUpListener(){
privateChatManager.addPrivateChatManagerListener(privateChatManagerListener);
privateChat = privateChatManager.getChat(opponentId);
if (privateChat == null) {
privateChat = privateChatManager.createChat(opponentId, privateChatMessageListener);
privateChat.addIsTypingListener(privateChatIsTypingListener);
}else{
privateChat.addMessageListener(privateChatMessageListener);
privateChat.addIsTypingListener(privateChatIsTypingListener);
}
}
i am follow link for chat
http://quickblox.com/developers/Android_XMPP_Chat_Sample
I have also tried to implement quickblox chat for one on one chat, which then I got stuck as the documentation is not so sufficient. Then I found out socket.io which is more convenient for one on one chat.follow the link: http://socket.io/blog/native-socket-io-and-android/. You also have to find a free node.js hosting company. I can suggest you the heroku.com
You can add listener for tracking users statuses - RosterListener.
For example:
https://github.com/QuickBlox/q-municate-android/blob/master/Q-municate_core/src/main/java/com/quickblox/q_municate_core/qb/helpers/QBFriendListHelper.java
Q-municate tracks users statuses in real time (private and group chats).