How to test GCM server side without implementing client side? - google-cloud-messaging

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 ..!!!!

Related

Ratchet PHP server establishes connection, but Kotlin never receives acknowledgement

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.

How to setup websocket SSL connect using cpprestsdk?

I tried to connect to a websocket server with SSL. But always failed on connection(...).
I am new to cpprestsdk, I can't find doc on how to set SSL information to websocket_client.
websocket_client_config config;
config.set_server_name("wss://host:port/v3/api");
websocket_client client(config);
auto fileStream = std::make_sharedconcurrency::streams::ostream();
pplx::task requestTask = fstream::open_ostream(U("results2.html"))
.then([&](ostream outFile)
{
*fileStream = outFile;
// Create http_client to send the request.
uri wsuri(U("wss://host:port/v3/api"));
client.connect(wsuri).wait();
websocket_outgoing_message msg;
msg.set_utf8_message(obj.serialize());
client.send(msg).wait();
printf("send success: %s\n", obj.serialize().c_str());
return client.receive().get();
})
it throws "Error exception:set_fail_handler: 8: TLS handshake failed".
Documentation for cpprestsdk can be found here
C++ REST SDK WebSocket client. Although this doesn't show all the necessary information related to cpprestsdk it will help you.
And also you can get an SSL test example here. I show a simple websocket client implemented using SSL or wss:// scheme
websocket_client client;
std::string body_str("hello");
try
{
client.connect(U("wss://echo.websocket.org/")).wait();
auto receive_task = client.receive().then([body_str](websocket_incoming_message ret_msg) {
VERIFY_ARE_EQUAL(ret_msg.length(), body_str.length());
auto ret_str = ret_msg.extract_string().get();
VERIFY_ARE_EQUAL(body_str.compare(ret_str), 0);
VERIFY_ARE_EQUAL(ret_msg.message_type(), websocket_message_type::text_message);
});
websocket_outgoing_message msg;
msg.set_utf8_message(body_str);
client.send(msg).wait();
receive_task.wait();
client.close().wait();
}
catch (const websocket_exception& e)
{
if (is_timeout(e.what()))
{
// Since this test depends on an outside server sometimes it sporadically can fail due to timeouts
// especially on our build machines.
return;
}
throw;
}
And further examples here to guide you get it successfully is found here
https://github.com/microsoft/cpprestsdk/wiki/Web-Socket

WebSockets not working when application is built

I have got to ASP.NET-Core 2.0 apps communicating via WebSockets.
App A is Server.
Application A is running on a remote server with Ubuntu.
App B is Client
Application B is running on a PC setup in my office.
When I test my applications locally in Debug everything works fine. Client connects to the server and they can exchange information.
However, when I build my Server app, Client can connect to it but when server tries to send a message to the client the message is not received by the client.
public async Task<RecievedResult> RecieveAsync(CancellationToken cancellationToken)
{
RecievedResult endResult;
var buffer = new byte[Connection.ReceiveChunkSize];
WebSocketReceiveResult result;
MemoryStream memoryStream = new MemoryStream();
do
{
if (cancellationToken.IsCancellationRequested)
{
throw new TaskCanceledException();
}
Console.WriteLine("Server Invoke");
// result never finishes when application is build. On debug it finishes and method returns the correct result
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
if (result.MessageType == WebSocketMessageType.Close)
{
await CloseAsync(cancellationToken);
endResult = new RecievedResult(null, true);
return endResult;
}
memoryStream.Write(buffer, 0, result.Count);
} while (!result.EndOfMessage);
endResult = new RecievedResult(memoryStream, false);
return endResult;
}
This is the part of code where everything hangs.
What I tried was:
Build Server - Build Client => not working
Build Server - Debug Client => not working
Debug Server - Debug Client => working
I need any advice what might be wrong here and where I should look for issues.
Console if free of errors. Everything hangs on:
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);

FCM/GCM App Server cannot connect to FCM/GCM CCS using SSLSocket and SMACK library

I'm writing a Firebase Cloud Messaing (FCM) App server program, and encountered a connection problem when I try to connect to FCM server via XMPP connection, using SMACK library. The program fails to be connected to the FCM server (fcm-xmpp.googleapis.com:5236).
Following an example,
https://github.com/carlosCharz/fcmxmppserverv2/blob/master/src/main/java/com/wedevol/xmpp/server/CcsClient.java,
I try to connect to the FCM server using SSL socket. The source codes are as follows.
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder ();
configBuilder.setUsernameAndPassword (senderId, serverKey);
configBuilder.setServiceName (CCMServiceName);
configBuilder.setHost (CCMServer);
configBuilder.setPort (CCMServerPort);
configBuilder.setSocketFactory (SSLSocketFactory.getDefault ());
configBuilder.setSecurityMode (SecurityMode.ifpossible);
configBuilder.setSendPresence (true);
configBuilder.setDebuggerEnabled(true);
SASLAuthentication.unBlacklistSASLMechanism("PLAIN");
//Step 2. Generate a connection resource with CCM Server
connection = new XMPPTCPConnection (configBuilder.build ());
//Step 3. Connect
try {
systemLogStream.println ("Try to connect XMPP end-point: " + CCMServer );
connection.connect();
} catch (SmackException smackEx) {
systemLogStream.println ("SMACK Exception: " + smackEx.getMessage());
System.exit(999);
} catch (XMPPException xmppEx) {
systemLogStream.println ("XMPP Exception: ");
} catch (IOException ioEx) {
systemLogStream.println ("IO Exception: ");
}
However, it always fails to connect to FCM server generating following exception.
SMACK Exception: No response received within reply timeout. Timeout was 5000ms (~5s). Used filter: No filter used or filter was 'null'.
To figure out the reason, I captured tcpdumps and it looks like SSLSocket does not send Clienthello message which is the first step to TLS handshake. Following is the result from Wireshark.
Wireshark capture result
I hope that someone nice gives a comment or an advise how to resolve this problem.
Thank you.

GCM server side implementation for java

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