Combining java and nodejs for android app - java

I'm working on Android game which is turn based, and I've chosen Nodejs for the server side. I've been exploring for about two weeks how to communicate from the Android client side to the Nodejs server. Is there any way to communicate between the two.
Kindly help me if any one have any experience with such a project.

There are lots of options for something like this depending on what your game requires for communicating between client and server. For instance looking up "TCP clients for android" here shows up answers like this. If fast updates are important between server and client then UDP is one option, if your game can cope with the loss of some packets in the middle.
Besides TCP/UDP you also have things like WebSockets for Android.

Combining Android & nodejs is no problem. First you have to define a middelware. You can use REST-Webservices or any other technology for the communication between the node server and the android client. There are many standard APIs and protocols. I would use Websocket for the communication. You can find Android / Node.js APIs with WebSocket support here:
http://cjihrig.com/blog/creating-your-own-node-js-websocket-echo-server/
https://github.com/Worlize/WebSocket-Node
http://jwebsocket.org/mobile/android/android_part1.htm
http://code.google.com/p/weberknecht/

You can use Volley in Android to make a json POST or GET request.
And for the NODE JS you can use node's built-in http module to create a simple HTTP server and then receive data from the req object.
const http=require('http');
const stringDecoder=require('string_decoder').StringDecoder;
var httpServer=http.createServer(function(req,res){
unifinedServer(req,res);
});
//Just another method.
var unifinedServer=function(req,res){
var decoder=new stringDecoder('utf-8');
var buffer='';
//reading the post data.
req.on('data',function(data){
buffer+=decoder.write(data);
});
//Reading of data is completed.
req.on('end',function(){
buffer+=decoder.end();
// Do what ever you want to do with the POST data.
});
}
//The Server is listening on a specific port.
httpServer.listen(7000,function(){
console.log("Server is now listening on Port..."+7000);
});
For the Android Code you can do this with volley:
String url = "http://example.com";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.POST, url, postJsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
mTextView.setText("Response: " + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);

Related

Java Custom Google Analytics 4 Server-Side Event User-IP

In my current Java project, it's easy to track server-side user events in the "old" Google Analytics Universal Project with simple REST calls to Google Analytics. So that location tracking was working, i could override the server ip with the user ip, according to the parameter "&uip=1.2.3.4" (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters?hl=de#uip).
As upgrading to GA4 is recommended, I was able to change all the REST parameters in my project and show my events in the new dashboard, except for the user location. I can't find any information about such a parameter. I tried using still "uip" but now all my requests are located to the country of my server.
Unfortunately it's not possible to track the event client side, because my project is a simple REST API, returning only JSON data.
Does anyone have an idea, if there's such a parameter like "uip" for ga4 or if this isn't possible anymore?
In the following way I setup my parameters:
private String getQueryParameters(MeasurementEvent event) {
StringBuilder body = new StringBuilder();
body.append("?v=").append(version);
body.append("&tid=").append(trackingId);
body.append("&cid=").append(event.getClientId());
body.append("&en=").append(eventName);
body.append("&aip=1");
if (StringUtils.hasText(event.getAction())) {
body.append("&ep.useraction=").append(event.getAction());
}
if (StringUtils.hasText(event.getCategory())) {
body.append("&ep.awsregion=").append(event.getCategory());
}
if (StringUtils.hasText(event.getLabel())) {
body.append("&ep.softwarename=").append(event.getLabel());
}
if (StringUtils.hasText(event.getRemoteAddress())) {
body.append("&uip=").append(event.getRemoteAddress());
}
if (StringUtils.hasText(event.getUrl())) {
body.append("&dl=").append(event.getUrl());
}
return body.toString();
}

Sending a command to android things from an android device

I am recently working on a project that requires sending a command from my android mobile app to the android things on my raspberry pi 3. How can I achieve this through a WiFi connection?
I only need to send a String to the device.
If one of your devices isn't connected to internet, you could :
Option 1 :
use Google Nearby Connections API , the API choose the best way to communicate (eg: Bluetooth, Wifi...).
See https://github.com/googlesamples/android-nearby/tree/master/connections
Option 2 :
Use Socket to communicate but your devices need to be on the same network. If they aren't connected to the same network, you can connect them using WIFI P2P.
Using Android Things, you can use the Nearby Messages API, which gives you the ability to communicate to and transfer messages between two Android devices within their apps. Here's a code snippet:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mMessageListener = new MessageListener() {
#Override
public void onFound(Message message) {
Log.d(TAG, "Found message: " + new String(message.getContent()));
}
#Override
public void onLost(Message message) {
Log.d(TAG, "Lost sight of message: " + new String(message.getContent()));
}
}
mMessage = new Message("Hello World".getBytes());
}
#Override
public void onStart() {
super.onStart();
...
Nearby.getMessagesClient(this).publish(mMessage);
Nearby.getMessagesClient(this).subscribe(mMessageListener);
}
#Override
public void onStop() {
Nearby.getMessagesClient(this).unpublish(mMessage);
Nearby.getMessagesClient(this).unsubscribe(mMessageListener);
...
super.onStop();
}
If you use system like Raspbian you can transform your Raspberry into a server.Then, You will have different ways to send your command:
Option 1: Set up an Http server on your raspberry (PHP, NodeJS, JEE, ...) and send command via HTTP Request.
Option 2: Set up a Socket Server on your raspberry (Socket.io, raw socket, ...) and send command via socket client
Option 3 Set up MQTT Server on your raspberry and send command via MQTT client (this last option is the way to go when talking about Internet of Things). Note that the program which receive command should implement MQTT Client as MQTT is based on pub/sub pattern.
You can use nanoHttpd on Android things and other library such as retrofit or volley on the Android device.
Check out this example for controlling a car via an Http API: https://github.com/plattysoft/IotCar

Sending notifications One to One (Firebase) [duplicate]

I am thinking about keeping all registration ids(push token) in DB and sending notifications to user from iPhone. I tried something like this but did not get any notification.
func sendPNMessage() {
FIRMessaging.messaging().sendMessage(
["body": "hey"],
to: TOKEN_ID,
withMessageID: "1",
timeToLive: 108)
}
What I am doing wrong or maybe it is impossible at all?
Currently it's not possible to send messages from the application itself.
You can send messages from the Firebase Web Console, or from a custom server using the server-side APIs.
What you might want to do is to contact a server (like via http call) and that server will send the message to the user.
This way ensure that the API-KEY of the server is protected.
PS: the sendMessage(..) api is called upstream feature, and can be used to send messages from your app to your server, if you server has an XMPP connection with the FCM server.
Yes you can send push notification through Firebase.Please make sure do NOT include the server-key into your client. There are ways "for not so great people" to find it and do stuff... The Proper way to achieve that is for your client to instruct your app-server to send the notification.
You have to send a HTTP-Post to the Google-API-Endpoint.
You need the following headers:
Content-Type: application/json
Authorization: key={your_server_key}
You can obtain your server key within in the Firebase-Project.
HTTP-Post-Content: Sample
{
"notification": {
"title": "Notification Title",
"text": "The Text of the notification."
},
"project_id": "<your firebase-project-id",
"to":"the specific client-device-id"
}
Google Cloud Functions make it now possible send push notifications from device-to-device without an app server.
From the Google Cloud Functions documentation:
Developers can use Cloud Functions to keep users engaged and up to
date with relevant information about an app. Consider, for example, an
app that allows users to follow one another's activities in the app.
In such an app, a function triggered by Realtime Database writes to
store new followers could create Firebase Cloud Messaging (FCM)
notifications to let the appropriate users know that they have gained
new followers.
Example:
The function triggers on writes to the Realtime Database path where followers are stored.
The function composes a message to send via FCM.
FCM sends the notification message to the user's device.
Here is a demo project for sending device-to-device push notifications with Firebase and Google Cloud Functions.
Diego's answer is very accurate but there's also cloud functions from firebase it's very convenient to send notifications in every change in the db. For example let's say you're building chat application and sending notification in every new follower change.
This function sample is very good example.
For more information about cloud functions you can check official docs.
I have an app that has a "send feedback to developer" section. I also have a User collection in my firestore database. When a user logs into the app, I have that Users data update their FCM token with the following code in my SceneDelegate.swift:
import Firebase
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
authListener = Auth.auth().addStateDidChangeListener({ (auth, user) in
Auth.auth().removeStateDidChangeListener(self.authListener!)
if user != nil {
DispatchQueue.main.async {
let docRef = Firestore.firestore().collection("User").document((user?.email)!)
docRef.getDocument { (snapshot, error) in
guard let snapshot = snapshot else {return}
Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let token = token {
docRef.updateData(["FCMtoken":token])
print("FCM registration token: \(token)")
}
}
}
}
}
})
guard let _ = (scene as? UIWindowScene) else { return }
}
then in my feedback view controller i have this code to send my specific device (but you can look up/fetch which specific device you want in your database where the FCMtoken is stored where i have INSERT-DEVICE-TOKEN-HERE). The url to send to is "https://fcm.googleapis.com/fcm/send" and you can find YOUR-APP-FCM-KEY by going to your project settings in firebase, going to cloud messaging tab and its the server key.
func sendMePushNotification() {
let token = "INSERT-DEVICE-TOKEN-HERE"
if let url = URL(string: "https://fcm.googleapis.com/fcm/send") {
var request = URLRequest(url: url)
request.allHTTPHeaderFields = ["Content-Type":"application/json", "Authorization":"key=YOUR-APP-FCM-KEY"]
request.httpMethod = "POST"
request.httpBody = "{\"to\":\"\(token)\",\"notification\":{\"title\":\"Feedback Sent!\",\"body\":\"\(self.feedbackBox.text!)\",\"sound\":\"default\",\"badge\":\"1\"},\"data\": {\"customDataKey\": \"customDataValue\"}}".data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data, urlresponse, error) in
if error != nil {
print("error")
} else {
print("Successfully sent!.....")
}
}.resume()
}
}
Use onesignal,you can send device to notifications or device to segments ,it can work with firebase in this way
Use onesignal functions to create a specific id,save it in a firebase database ,then when the id can be put in another function that is used to send a notification
Notes: 1-i am using it in my apps with firebase works perfectly
2-i can submit that code,just someone comments so i can find this answer

Java websocket with proxy

I have been trying all day and night for couple of days trying to make websocket to work using proxy in Java. I tried different library like
https://github.com/TooTallNate/Java-WebSocket
https://github.com/AsyncHttpClient/async-http-client
But sadly these library doesn't support proxy with credentials. If you guys have known any other library that supports proxy then I would be appreciated.
Thanks in advance
Try nv-websocket-client library. It supports authentication at a proxy server. Note that, however, the current implementation supports Basic Authentication only.
// 1. Create a WebSocketFactory instance.
WebSocketFactory factory = new WebSocketFactory();
// 2. Set up information about a proxy server.
// Credentials can be set here.
ProxySettings settings = factory.getProxySettings();
settings.setServer("http://proxy.example.com");
settings.setCredentials("id", "password");
// 3. Connect to a WebSocket endpoint via the proxy.
WebSocket ws = factory.createSocket("ws://websocket.example.com");
// 4. Add a listener to receive WebSocket events.
ws.addListener(new WebSocketAdapter() {
#Override
public void onTextMessage(WebSocket ws, String message) {
// Received a text message.
......
}
});
// 5. Perform a WebSocket opening handshake.
ws.connect();
// 6. Send frames.
// 6-1. Text
ws.sendText("Hello.");
// 6-2. Binary
byte[] binary = ......;
ws.sendBinary(binary);
// 6-3. Ping
ws.sendPing("Are you there?");
// 6-4. Pong (unsolicited pong; RFC 6455, 5.5.3. Pong)
ws.sendPong("I'm OK.");
// 6-5. Fragmented Frames
ws.sendText("How ", false)
.sendContinuation("are ")
.sendContinuation("you?", true);
// 6-6. Periodical Ping
ws.setPingInterval(60 * 1000);
// 6-7. Periodical Pong (unsolicited pong; RFC 6455, 5.5.3. Pong)
ws.setPongInterval(60 * 1000);
// 6-8. Close (if you want to send one manually).
ws.sendClose(WebSocketCloseCode.NORMAL, "Bye.");
// 7. Disconnect
ws.disconnect();
Blog
WebSocket client library (Java SE 1.5+, Android)
http://darutk-oboegaki.blogspot.jp/2015/05/websocket-client-library-java-se-15.html
GitHub
https://github.com/TakahikoKawasaki/nv-websocket-client
JavaDoc
http://takahikokawasaki.github.io/nv-websocket-client/
Maven
<dependency>
<groupId>com.neovisionaries</groupId>
<artifactId>nv-websocket-client</artifactId>
<version>1.3</version>
</dependency>
The size of nv-websocket-client-1.3.jar is 62,854 bytes and it does not require any external dependencies.
You can try Tyrus (reference implementation of WebSocket API in Java EE); client side does not require any Java EE server to be running and if you are using Java 7, the client could be minimized to ~500kb.
Client behing proxy and Dependencies should provide enough info to try.

WebSockets, GlassFish, Grizzly -- can't connect

I am trying to get started with WebSockets, and trying to write a simple application to send messages back and forth via a websoket.
However, it looks like the socket that I am trying to create never gets connected. Why can that be?
Below is the code of my WebSockets class. When .onConnect() is called, it logs:
I am socket, I was connected. Am i connected? - false
Update: in JavaScript, where I create the socket in question, the readyState is 1, which means "socket open, communication is possble".
import a.b.Misc; //writes logs.
import com.sun.grizzly.websockets.BaseServerWebSocket;
import com.sun.grizzly.websockets.DataFrame;
import com.sun.grizzly.websockets.WebSocketListener;
public class ChatWebSocket_v2 extends BaseServerWebSocket {
private String user;
public ChatWebSocket_v2(WebSocketListener... listeners) {
super(listeners);
}
public String getUser() {
if (user == null) {
Misc.print("User is null in ChatWebSocket");
throw new NullPointerException("+=The user is null in chat web socket");
}
return user;
}
public void setUser(String user) {
Misc.print("Just set user: " + user);
this.user = user;
}
#Override
public void onMessage(String message) {
Misc.print(message +"\n");
}
#Override
public void onMessage(byte[] message) {
Misc.print(new String(message) +" << Bytes\n");
}
#Override
public void onConnect() {
Misc.print("I am socket, i was connected. Am i connected? - " + this.isConnected());
}
#Override
public void onClose(DataFrame df) {
Misc.print("I am socket, i was closed");
}
}
If you're just trying to make a connection somewhere, you might want to try this instead. There is a live working demo and you can download the javascript code and play with it yourself. Note that the javascript code only works if you have it installed on a server (due to browser security because it's 'fancy'.) There is also a step by step browser-based client tutorial in the works that I will post as soon as it's ready. Most proxy servers haven't been upgraded to handle websockets so they will screw up connection request and most people won't be able to connect to websocket servers from work. Firefox 7 (release) or Google Chrome 14 or later support the latest version of the websocket protocol that the demo server runs.
If you want to try to get the grizzly demo working, you might have some debugging to do and maybe I'll help with that. Note that in comments below the article, other people said they couldn't get it working either and I haven't found any follow up. At this point it seems no better than the echo app above even if we do get it running and is possibly overly complicated and underly documented if you're just trying to get started. But if you want to try to get it running, you should 'git' the latest version of the code here, which was at least committed recently and may be fixed.
Then make sure that app.url in the application javascript file is set to your installation directory. His is hard-coded as:
url: 'ws://localhost:8080/grizzly-websockets-chat/chat',
If you're using Firefox 7, the javascript needs to be modified to use the Moz prefix, for example:
if (typeof MozWebSocket != "undefined") { // window.MozWebSocket or "MozWebSocket" in window
ok
} else if (window.WebSocket) { // he uses if ("WebSocket" in window)
ok
} else {
do your print "browser doesn't support websockets"
}
.... then if the browser supports websockets
websocket = new WebSocket(app.url); or
websocket = new MozWebSocket(app.url);
// depending on which it is.
The HLL websocket server demo code has this all sorted out.
(another) UPDATE: As I work through grizzly myself, I found on the Quick Start in the glassfish admin console, there's a hello sample that's pretty easy to set up and run. You'll find instructions there. The sample directory also contains a war file named: websocket-mozilla; so I guess its supposed to use websockets. Someone who's familiar with jsp should review the source code. All I can see is that it's using an http session. No mention of a websocket at all. It's a lot like the hello sample.

Categories

Resources