I need to implement a standalone application for the server side of gcm to push notifications to the device. Is there any reference i could get other than the one on the Getting started page.People say something about xmpp. Do we need to use this or can we directly use the gcm server side methods.Help.Or is there any other easy way to implement this.I hope i put my question properly.
Here is nice tutorial for GCM server side implementation for java.
URL: java gcm server side implementation
Example code: java gcm server side implementation`{
new Thread(){
public void run(){
try {
//Please add here your project API key: "Key for browser apps (with referers)".
//If you added "API key Key for server apps (with IP locking)" or "Key for Android apps (with certificates)" here
//then you may get error responses.
Sender sender = new Sender("AIzaSyB7Ej255tpTaemk_-Ljmn4GcklldT14Hp4");
// use this to send message with payload data
Message message = new Message.Builder()
.collapseKey("message")
.timeToLive(3)
.delayWhileIdle(true)
.addData("message", "Welcome to Push Notifications") //you can get this message on client side app
.build();
//Use this code to send notification message to a single device
Result result = sender.send(message,
"APA91bEbKqwTbvvRuc24vAYljcrhslOw-jXBqozgH8C2OB3H8R7U00NbIf1xp151ptweX9VkZXyHMik022cNrEETm7eM0Z2JnFksWEw1niJ2sQfU3BjQGiGMq8KsaQ7E0jpz8YKJNbzkTYotLfmertE3K7RsJ1_hAA",
1);
System.out.println("Message Result: "+result.toString()); //Print message result on console
//Use this code to send notification message to multiple devices
ArrayList<String> devicesList = new ArrayList<String>();
//add your devices RegisterationID, one for each device
devicesList.add("APA91bEbKqwTbvvRuc24vAYljcrhslOw-jXBqozgH8C2OB3H8R7U00NbIf1xp151ptweX9VkZXyHMik022cNrEETm7eM0Z2JnFksWEw1niJ2sQfU3BjQGiGMq8KsaQ7E0jpz8YKJNbzkTYotLfmertE3K7RsJ1_hAA");
devicesList.add("APA91bEVcqKmPnESzgnGpEstHHymcpOwv52THv6u6u2Rl-PaMI4mU3Wkb9bZtuHp4NLs4snBl7aXXVkNn-IPEInGO2jEBnBI_oKEdrEoTo9BpY0i6a0QHeq8LDZd_XRzGRSv_R0rjzzZ1b6jXY60QqAI4P3PL79hMg");
//Use this code for multicast messages
MulticastResult multicastResult = sender.send(message, devicesList, 0);
System.out.println("Message Result: "+multicastResult.toString());//Print multicast message result on console
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}`
The simplest way to implement GCM server side for Java is using restful POST.
URL: "https://android.googleapis.com/gcm/send"
Example code: using scribe framework as consumer
public void pushToAndroidDevice(String deviceToken, String data) {
OAuthRequest request = new OAuthRequest(Verb.POST, "https://android.googleapis.com/gcm/send");
request.addHeader("Authorization", "key=" + apiKey);
request.addHeader("Content-Type", "application/json");
request.addPayload(data);
Response response = request.send();
}
There are 2 ways you can implement server for GCM connections
1) XMPP
2) HTTP
The difference being XMPP allow you to get response back from device to server(Bidirectional) and HTTP is (Unidirectional) for GCM, you can only send push notification to device.
In case you need the full implementation of Java Client and HTTP server, here is the link
GCM Client and Server
Related
I am very new to programming with ESP8266 and can't get this to work.
I am successfully connected to the internet.
With the <ESP8266HTTPClient.h> I am writing the following code:
void loop() {
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
HTTPClient http; //Declare object of class HTTPClient
http.begin("https://api.entur.io/journey-planner/v2/graphql"); //Specify request destination
http.addHeader("Content-Type", "application/json"); //Specify content-type header
http.addHeader("ET-Client-Name", "student-bussAPI"); //Identification requested by the API
int httpCode = http.POST("{\"query\":\"{authorities{id}}\"}"); //Send the request
String payload = http.getString(); //Get the response payload
Serial.println(httpCode); //Print HTTP return code
Serial.println(payload); //Print request response payload
http.end(); //Close connection
} else {
Serial.println("Error in WiFi connection");
}
delay(30000); //Send a request every 30 seconds
}
the code runs with serial output -1
I have tested the query request on postman, and it worked fine there.
The "-1" you are getting is caused by the attempt to establish a connection to a strictly HTTPS service via HTTP.
As the code examples in the ESP8266HttpClient library explain, "httpCode will be negative on error" - what you are seeing is the printing of a http status code of -1.
The easiest way to achieve what you are trying to do here (Query a HTTPS API via the ESP8266httpClient library) would be to connect to it using the current SHA-1 fingerprint of the certificate used by the service as a second parameter of your call to "http.begin".
Example to answer your specific question:
HTTPClient http; //Declare object of class HTTPClient
const char* host = "https://api.entur.io/journey-planner/v2/graphql";
const char* fingerprint ="Current sha-1 fingerprint goes here";
http.begin(host, fingerprint); //Specify request destination and fingerprint for cert to make it do HTTPS
http.addHeader("Content-Type", "application/graphql"); //Content type here is important; Its not JSON
http.addHeader("ET-Client-Name", "Esp8266-BitBrb");
I should also mention that the specific API you are using here has a strict check on content type, so you should change your header to match the data type the API accepts, "application/graphql", or else you'll have trouble :)
Incidentally, i have the full code from a project i did last year with the same service you are using (Hi, fellow Norwegian and EnTur user) available here: https://www.bitbrb.com/electronics/graphql-querying-a-bus
I see they got a new certificate earlier this year, other than that you should be able to cut and paste.
good luck :)
I have a ratchet server, that I try to access via Websocket. It is similar to the tutorial: logging when there is a new client or when it receives a message. The Ratchet server reports having successfully established a connection while the Kotlin client does not (the connection event in Kotlin is never fired). I am using the socket-io-java module v.2.0.1. The client shows a timeout after the specified timeout time, gets detached at the server and attaches again after a short while, just as it seems to think, the connection did not properly connect (because of a missing connection response?).
The successful connection confirmation gets reported to the client, if the client is a Websocket-Client in the JS-console of Chrome, but not to my Kotlin app. Even an Android emulator running on the same computer doesn´t get a response (So I think the problem is not wi-fi related).
The connection works fine with JS, completing the full handshake, but with an Android app it only reaches the server, but never the client again.
That´s my server code:
<?php
namespace agroSMS\Websockets;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
class SocketConnection implements MessageComponentInterface
{
protected \SplObjectStorage $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
error_log("New client attached");
}
function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
error_log("Client detached");
}
function onError(ConnectionInterface $conn, \Exception $e)
{
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
function onMessage(ConnectionInterface $from, $msg)
{
error_log("Received message: $msg");
// TODO: Implement onMessage() method.
}
}
And the script that I run in the terminal:
<?php
use Ratchet\Server\IoServer;
use agroSMS\Websockets\SocketConnection;
use Ratchet\WebSocket\WsServer;
use Ratchet\Http\HttpServer;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new SocketConnection()
)
)
);
$server->run();
What I run in the browser for tests (returns "Connection established" in Chrome, but for some reason not in the Browser "Brave"):
var conn = new WebSocket('ws://<my-ip>:80');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
What my Kotlin-code looks like:
try {
val uri = URI.create("ws://<my-ip>:80")
val options = IO.Options.builder()
.setTimeout(60000)
.setTransports(arrayOf(WebSocket.NAME))
.build()
socket = IO.socket(uri, options)
socket.connect()
.on(Socket.EVENT_CONNECT) {
Log.d(TAG, "[INFO] Connection established")
socket.send(jsonObject)
}
.once(Socket.EVENT_CONNECT_ERROR) {
val itString = gson.toJson(it)
Log.d(TAG, itString)
}
}catch(e : Exception) {
Log.e(TAG, e.toString())
}
After a minute the Kotlin code logs a "timeout"-error, detaches from the server, and attaches again.
When I stop the script on the server, it then gives an error: "connection reset, websocket error" (which makes sense, but why doesn´t he get the connection in the first time?)
I also tried to "just" change the protocol to "wss" in the url, in case it might be the problem, even though my server doesn´t even work with SSL, but this just gave me another error:
[{"cause":{"bytesTransferred":0,"detailMessage":"Read timed out","stackTrace":[],"suppressedExceptions":[]},"detailMessage":"websocket error","stackTrace":[],"suppressedExceptions":[]}]
And the connection isn´t even established at the server. So this try has been more like a down-grade.
I went to the github page of socket.io-java-client to find a solution to my problem there and it turned out, the whole problem was, that I misunderstood a very important concept:
That socket.io uses Websockets doesn´t mean it is compatible with Websockets.
So speaking in clear words:
If you use socket.io at client side, you also need to use it at the server side and vice versa. Since socket.io sends a lot of meta data with its packets, a pure Websocket-server will accept their connection establishment, but his acknowledgement coming back will not be accepted by the socket.io client.
You have to go for either full socket.io or full pure Websockets.
I would like to use a PushNotinfication service via Java application so that I need appGuid and appSecret of the service. (The figure attached to this message shows the window that appSecret is supposed to be shown but it didn't.) enter image description hereSome documents say that appSecret is automatically generated when an application is bound to the service but I cannot understand about the binding process.
So I would like to know the process to issue appSecret of the PushNotification Service as detail as possible. I would appreciate if someone could explain with the screen shot of the window of each process.
#ken We support both AppSecret and Tokens in the swagger(http://imfpush.ng.bluemix.net/imfpush/). For new instances created there would not be any AppSecret as these are IAM based instances. And there is no way other than the Token way of authentication.
Those instances created before June 2018 will work with Appsecret. But the new instances will work only with IAM token. This is introduced for better security. Please refer to our release notes for the same https://console.bluemix.net/docs/services/mobilepush/release-notes.html#release-notes.
To know more on the IAM implementation on the Push Notification service please refer to https://console.bluemix.net/docs/services/mobilepush/push_iam.html#service-access-management
Refer to the question 21 in our FAQ section https://console.bluemix.net/docs/services/mobilepush/push_faq.html#faq to know how to retrieve the token and use.
Regarding the Swagger a new Authorization field is introduced to submit the IAM token. Either the Authorization field or the appSecret is mandatory.
Please refer to the server sdk (https://github.com/ibm-bluemix-mobile-services/bms-pushnotifications-serversdk-java) readme file where customer has to Initialize Push with ApiKey for the new push instance that IAM token is automatically generated by initialization method..
PushNotifications.initWithApiKey("YOUR_APPLICATION_ID", "YOUR-BLUEMIX-PUSH-APIKEY", PushNotifications.US_SOUTH_REGION);
Sample
public static void main(String[] args) {
PushNotifications.initWithApiKey("appId", "APIKey", PushNotifications.US_SOUTH_REGION);
Message message = new Message.Builder().alert("20% Off Offer for you").url("www.ibm.com").build();
String [] deviceIds = {"deviceIds"};
Target target = new Target.Builder().deviceIds(deviceIds).build();
Notification notification = new Notification.Builder().message(message).target(target).build();
PushNotifications.send(notification, new PushNotificationsResponseListener(){
public void onSuccess(int statusCode, String responseBody) {
System.out.println(responseBody);
System.out.println("Successfully sent push notification! Status code: " + statusCode + " Response body: " + responseBody);
}
public void onFailure(Integer statusCode, String responseBody, Throwable t) {
System.out.println("Failed sent push notification. Status code: " + statusCode + " Response body: " + responseBody);
if(t != null){
t.printStackTrace();
}
}
});
}
Hope this helps.
I have created the server side for gcm using the code below:
Message message = new Message.Builder().timeToLive(30)
.delayWhileIdle(true).addData(MESSAGE_KEY, MESSAGE_VALUE).build();
MulticastResult result = null;
try
{
result = sender.send(message, devicesList, 1);
System.out.println(result.toString());
}
catch(Exception e)
{
e.printStackTrace();
}
It is working fine but the problem i am facing is that currently i can't implement the client side,so i don't have the registration id to test my code.
So anyone can please help me that is there any way to test my gcm server side implementation without implementing client side ??? Thanks ..!!!!
guys
I'm trying to send message to server and get response on client side, also I'm trying to publish another message on server using the same endpoint.
I don't get response on client side, but subscribers get published messages with success
Server side code:
if (!someCondition)
{
_bus.Reply(new BookingStatus(message, Status.Occupied));
}
else
{
_bus.Reply(new BookingStatus(message, Status.Ok));
_bus.Publish(new RoomBooked(message, Guid.NewGuid()));
//some logic
}
Code for config bus:
BusConfiguration busConfiguration = new BusConfiguration();
busConfiguration.EndpointName("NServiceBusDemo");
busConfiguration.UseTransport<MsmqTransport>();
busConfiguration.UseSerialization<JsonSerializer>();
busConfiguration.EnableInstallers();
busConfiguration.UsePersistence<InMemoryPersistence>();
busConfiguration.AutoSubscribe();
DefaultFactory defaultFactory = LogManager.Use<DefaultFactory>();
defaultFactory.Directory(#"..\..\..\logs");
defaultFactory.Level(LogLevel.Warn);
var bus = Bus.Create(busConfiguration);
return bus;