Android App using RabbitMQ of cloudfoundry - android

Hi i am trying to develop a chat application in Android using RabbitMQ.
The code is working fine with my locally installed rabbitMQ server.
Inordrer to send message to the queue my android APP needs the address of the robbitMQ server it is talking to.
Can I make use of RabbitMQ on cloudfoundry, replacing my local rabbitMQ in the application code ?
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("<RobbitMQ server>");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout", true);
channel.queueDeclare(QUEUE_NAME, false, false, false, null);

You'll face a couple of issues with this:
the address of the RabbitMQ service on cloudfoundry.com will be dynamically-assigned... you can look it up from the environment on cloudfoundry.com within a web app, but you can't easily get it in a remote native Android app.
right now, you can't make a remote AMQP connection into a service on cloudfoundry.com - only within the Cloud Foundry vcap environment. So even if you had the address, an AMQP connection via JMS directly from an Android app wouldn't work.
How about running RabbitMQ on an EC2 instance? or what about building a web app backend for your Android app, which talked to RabbitMQ running in a Cloud Foundry instance, with Android talking to the backend via SockJS?

Related

Google Cloud socket.io server, client not keeping persistent connection

I have a Node.js server using socket.io to connect Android apps and I've been hosting it locally by just running it in my IDE and connecting to my local IPv4 address but I want it to work without me having to keep my PC running constantly so I've tried using Google Cloud and managed to get it mostly working but the client doesn't keep the connection and disconnects consistently.
I followed this tutorial up to step 4 after that I ran gcloud app deploy.
My Node.js server is in one file, it has these declarations at the top.
const express = require("express");
const app = express();
const http = require("http");
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
I then have this for the initial client connection.
io.on("connection", (socket) => {
console.log("User connected.");
Everything inside of this is just listeners for what gets emitted by the client so I don't think they're the problem.
And then outside of that I have
server.listen(8080, () => {
console.log("Server is listening");
});
I don't know if anything from the package.json file is relevant but I can provide it if need be.
After deploying to Google Cloud using the tutorial there are a few things in the logs that may be the reason behind the problem.
Waiting for network connection open. Subject:"app/invalid" Address:127.0.0.1:8080
Waiting for network connection open. Subject:"app/invalid" Address:127.0.0.1:8081
Wait successful. Subject:"app/invalid" Address:127.0.0.1:8080 Attempts:97 Elapsed:485.916418ms
App is listening on port 8080. We recommend your app listen on the port defined by the PORT environment variable to take advantage of an NGINX layer on port 8080.
These might have simple solutions but I have very little experience with server hosting.
Once my Android client connects to the server, the log outputs "User connected." as it should, then around 10 seconds later it does it again and this repeats. There's no error I can see between the connections just a few socket.io POST/GET requests.
I tried adding session affinity to the app.yaml but hasn't solved it either.
This is my app.yaml if any changes need to be made here
runtime: nodejs16
env: standard
instance_class: F1
automatic_scaling:
min_idle_instances: automatic
max_idle_instances: automatic
min_pending_latency: automatic
max_pending_latency: automatic
network:
session_affinity: true
Thanks for any help, if I need to provide any other files I can do so.
Socket communication requires persistent network connections. So, App Engine Flexible provides an option to keep the network connection alive.
I think you are deploying your app in App Engine Standard , which does not support this option.
So, you can deploy your app in App Engine Flexible and you need to include the following configuration in your app.yaml
network:
session_affinity: true
For refence on session affinity, please refer to this page https://cloud.google.com/appengine/docs/flexible/nodejs/using-websockets-and-session-affinity#session_affinity
So, your updated app.yaml can look like this
runtime: nodejs
env: flex
network:
session_affinity: true
Please refer to this page for supported yaml configuration for flexible environment - https://cloud.google.com/appengine/docs/flexible/nodejs/reference/app-yaml
Messages you have pasted are most likely not indicating a problem. Your application is running in a sandbox environment for which a container instance and a web server must be initialized the first time that your app engine service receives a request. This is also called Loading request and the messages you see indicate the startup of your container instance and your webserver.
You can take a look at Google's own documentation regarding handling requests in node.js or follow a quickstart guide.
If there are no other logs during the disconnection, I would suggest checking the quotas to see if you're not exceeding any.

How to force MQTT broker to NOT clean session from Android Paho client?

I'm trying to use MQTT (Paho library on Android, mosquitto message broker on a linux server) to pass moves in a turn-based game, replacing a custom server I wrote years ago. Its simplicity and pub-sub design seem perfect: each device subscribes to a unique id as "topic" and communicates that as its "address." Then other devices can reach it by publishing to that address.
It works perfectly in my test Linux client (connecting using the mosquitto-dev library on Ubuntu). And it works perfectly on Android WHEN THE ANDROID APP IS RUNNING. In the Linux client case, if a message is sent while the app isn't running or connected the app receives the message as soon as it does connect and subscribe. On Android, however, this doesn't happen. Only messages sent (or resent) by another client while the android client is subscribed are ever delivered.
I'm new to MQTT, but it seems pretty clear that the "cleanSession" connection parameter is what controls this: unless you "clean" a session, you get everything that was published to your topic while you were not subscribed. On the Linux client side, passing "true" to mosquitto_new(..., clean_session, ...) does indeed prevent my Linux client from getting pre-connection messages. But on the Android side, calling .setCleanSession(boolean) has no effect when the MqttConnectOptions instance is passed to .connect().
I'm using 1.1.+ of paho. Per the tags in the repo at https://github.com/eclipse/paho.mqtt.android.git, v1.1.1 is the latest.
implementation "org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.+"
implementation "org.eclipse.paho:org.eclipse.paho.android.service:1.1.+"
I suspect that this is simply a bug in the Android Paho library (which doesn't seem to have been worked on in four years.) But I hope I'm wrong! Is there a way to accomplish what I want?
Alternatively, is there a better library? The googling I've done suggests that in spite of its age Paho is still what most Android devs are using to speak MQTT.
Thanks!
About the cleanSession flag.
The Client and Server can store Session state to enable reliable messaging to continue across a sequence of Network Connections. This bit is used to control the lifetime of the Session state.
If CleanSession is set to 0, the Server MUST resume communications with the Client based on state from the current Session (as identified by the Client identifier). If there is no Session associated with the Client identifier the Server MUST create a new Session. The Client and Server MUST store the Session after the Client and Server are disconnected. After the disconnection of a Session that had CleanSession set to 0, the Server MUST store further QoS 1 and QoS 2 messages that match any subscriptions that the client had at the time of disconnection as part of the Session state. It MAY also store QoS 0 messages that meet the same criteria.
More about cleanSession on : https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/csprd02/mqtt-v3.1.1-csprd02.html
If I understand correctly your requirement, then indeed you need to use clenSession=true. You can also try publishing and subscribing with QoS=0. Some brokers do not store QoS=0 messages, mosquitto as well. (as per https://mosquitto.org/man/mqtt-7.html)
I've found a workaround, and in the process confirmed my suspicion that the MqttAndroidClient class is broken in not honoring that setting. Instead of using MqttConnectOptions I tried using MqttAsyncClient. The code changes are trivial, though underneath there's considerable change as the Android client knows about and uses background Services. With the simple change of using this different class, I'm able to connect & subscribe and immediately receive all messages that were published while I was not connected.

Azure mobile node.js backend deploy port issue

I'm new on node.js and azure.
I want to develop a mobile app which insert and select data in a table.
For the android part - client side I use the code from here.
For the node.js part - server side I use the code from the same repository this code
When I deploy the node.js project on azure I give an error:
I have this message if a use any code for mobile node.js.
In Container diag, the problem is at PORT:
Check your Application Settings to make sure that the PORT setting of your container is correct. You can also view Application Logs to determine if there was a wrong PORT set.
In application logs the port is 8080:
ERROR - Container antaresmobilejs_0_7b069d42 for site antaresmobilejs
has exited, failing site start ERROR - Container
antaresmobilejs_0_7b069d42 didn't respond to HTTP pings on port: 8080,
failing site start. See container logs for debugging.
In my node.js code, I set the port to 8080, but I don't find the port settings in application settings.
Actually, the Node.js backend port for Azure Mobile Apps should be set as below if using Express.js.
app.listen(process.env.PORT || 3000);
It was introduced in the offical document How to use the Mobile Apps Node.js SDK, as the figure below.
It also be coded in the offcal sample code https://github.com/Azure/azure-mobile-apps-quickstarts/blob/master/backend/node/TodoSample/app.js#L35
The code process.env.PORT will read the default port specified by Azure from the environment, and the web.config file will help node backend app to start up by IIS.
The real port of API endpoint for client is 80, because the node app hosted in IIS.

Sending alerts / notifications from server side to android application without internet access

I need to send a push notificiation from a webapp to an android app.
Basically I just want to inform the android client that new data is available on the server. So it only has to be a string + vibration/sound of the phone.
The (big) problem here is that I am inside a corporate network without access to the internet. This is why I cannot use GCM.
So far I found the following options to accomplish the task without GCM:
Use XMPP
WebSockets
Ajax Polling
Is it possible to include WebSockets or AjaxPolling into a native Android app to trigger events like vibrate?
Is there an easier solution, without that much overhead as with xmpp, since I just need to send a short notification? So far I understand that I need somethink like SMACK XMPP for Android + e.g. Openfire and XMPPHP on the server side for this scenario.
Since nobody replied, I want to provide you with an approach I now try to pursue.
I use Laravel to write the API. It comes with an out-of-the-box support for Redis, which is awesome to Broadcasts Events -> https://laravel.com/docs/5.1/events
The following is just a quick example:
Redis::publish('test', json_encode($data));
Those events are received from a Socket.IO Server-Instance running on the same machine.
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('test');
....
server.listen(3000);
Socket.IO has an android client implementation, which allows me to connect to the socket.io server in a native android app.
Here is an example: http://socket.io/blog/native-socket-io-and-android/
private Socket mSocket;
{
try {
mSocket = IO.socket("http://localhost:3000");
} catch (URISyntaxException e) {}
}

Can I connect with WebSocket in an Android app?

I have an Android app and I want to send a text from the Android application to the webpage using HTML5 WebSocket.
Is this possible and if so how?
I'm aware of 2 libs for Android supporting WebSockets from native apps
http://code.google.com/p/weberknecht
https://github.com/tavendo/AutobahnAndroid
Autobahn supports RFC6455 (the final WS spec), integrates well with UI and service apps and support RPC and PubSub over WebSockets.
Disclaimer: I am the author of Autobahn.
A simple google search for 'android websockets' turned up this. He is referring to a GitHub project called websocket-android-phonegap.
Answer is Yes, it is possible to send a text from app to a web page.
WebSocket works on the very principle of server and client over TCP/IP. Just a wrapper created over the TCP/IP layer and built a new data format which is defined by IETF. Details of the data format is available at -
[https://www.rfc-editor.org/rfc/rfc6455][1]
Server accepts websocket connection if requested in correct format. Client here is the web application in which javascript objects are defined solely for this purpose in HTML5.
Easy to use APIs:
Client side programming of the websockets are very easy with new APIs and objects defined.
APIs(events) available for the developer: onopen, onclose, onmessage. All these functions should be defined by the developers java script file.
onopen: The function is called when the server accepts the connections succesfully
onclose: The function is called when the socket connection is closed
onmessage: The function is called when the data is received from the server.
send : the function is not event based but should be triggered when the client has the information to share with the server.

Categories

Resources