WebSocket with multiple ClientEndpoints and binary messages - java

Overview:
I currently have a fully functioning mobile application that communicates with a Java server running on Windows via WebSockets. The ServerEndpoint is running off of an AWS machine. The Java server is a ClientEndpoint running on a private network, and there can be multiple app users at any given time that are also ClientEndpoints.
I currently have everything working properly when it comes to sending String messages back and forth, as the ServerEndpoint is maintaining the Java server Session along with the mobile application Sessions. Almost all communication is initiated via the mobile applications at which time a JSON String is sent to the Java server session to be able to maintain which mobile application session should receive the return message.
I am now trying to implement functionality to be able to send PDF files via binary messages from the Java server to the mobile applications in the same fashion. The mobile applications are developed using Codename One, and they do not provide the ability to increase the maximum binary message size, so I seem to be limited to 8kb (8,192 bytes) per binary message. This is fine as I am sending multiple binary messages and rebuilding the file within the mobile app.
I currently have this working in the simplest case where there is only one mobile application user at a time requesting a PDF file.
Current Flow:
App A sends JSON message to ServerEndpoint which then forwards message to Java server A. Java server A sends JSON message back to ServerEndpoint which forwards message back to App A. The JSON objects contain the session id to send the messages back to. The ServerEndpoint needs to know which App Session to send messages to that come from the Java server.
When it comes to binary messages, App A sends a String message to the ServerEndpoint which then forwards message to Java server A. Java server A now needs to send multiple binary messages back to the ServerEndpoint which ALL must get forwarded to App A for the file to be rebuilt properly. This is the part that I'm not sure how to handle. It currently works fine if there is only one App session, but if multiple App sessions were to request files at the same time, it would not work properly.
Problem:
When sending String messages, it is easy enough to pass the callback mobile application session id as part of the JSON object back and forth to ensure the correct mobile application session gets the response. When it comes to sending the binary messages, what is the best way to guarantee that if users A and B request a file at the same time, that user A gets the file he/she requested and user B gets the file he/she requested?

You should be able to track the session without having to pass a session ID. For example, see this sample web service endpoint.
Notice how you can pass a Session object as the first parameter with the #OnMessage annotation.
You can use this to know who you're talking to.
One other small point/question. Your statement "The mobile applications are developed using Codename One, and they do not provide the ability to increase the maximum binary message size," seems to suggest that other platforms do allow you to set a maximum binary size on the client. AFAIK this is not part of the WebSocket spec, and isn't implemented by any browser. What other implementations do allow you to set the max size?
EDIT In response to your refinement of the question:
There are multiple ways to skin this cat. One thought is that you only need to chunk the "last mile" (between the middleman and the client). Since the middleman and the end server are JavaEE servers, you have control over the buffer size, and could potentially send the full file in one shot (within reason). Then just do the chunking in the middle server, which will know which client he is dealing with.
Another option is to create your own pseudo protocol. You're returning byte arrays, but you could choose to allocate the first n-bytes of each chunk to contain metadata, which the middleman would parse out. This metadata could be used to tell the middleman which client the chunk is destined for.

Zip the files you want to send and send it via binary, in server unzip it to get the data, i think size is not of a problem(havent tried Codename One though). If it is then you could send chunks of binary data that is structured to a jason object with a type and serial number that you can check to find the type of file you are sending and the number of chunk of the file it is. the flow will be like
get chuncks -> Json Object (Type="PDF", SerialNumber="1", Data="Binary data converted to String") -> zip the json object -> send to server. Do the reverse in server.

Related

Device Not Receiving GCM Messages

Before anything, I am currently unable to post code info/examples because I am not presently at the machine that has the code. If necessary, I will get the appropriate snippits up when I get to that machine tomorrow.
The Setup
I am implementing GCM communication to local server, as according to Google's example code. Both the client and the server are slight modifications of the example. The server is a Java program (again, pulled almost entirely from the demo code).
The Problem
Currently, the App & Server communicate fine back and forth using the dummy 'echo' setup that is the initial setup of Google's GCM communication example code.
If I move over to the custom message content that I intend on using with GCM is where I get the issue. I can send messages find from the GCM-driven app, but for some reason I am not getting the messages from the server back down to the app.
At current I am testing a basic chat element of the app that is talking to an XMPP server through GCM. So, I can connect to the XMPP server w/Pidgin and see messages coming out of the app, and when I send messages back down, they get sent to the GCM service, but never come out # the App.
Confusions/Questions/Clarifications
I am thoroughly confused because the demo behavior works fine
(message is echoed back to the app).
I am sending to the correct registration ID, I can switch back and forth multiple times between demo behavior and my behavior and it will/will not work accordingly.
I do not have collapse_key, or time_to_live in any of my messages back down to the app, and delay_while_idle is explicitly set to false (not omitted). So there should be no super-fast premature timeout or anything like that (unless I am misunderstanding the behavior of these keys)
It was my understanding there are no 'required' keys inside the data field, is that incorrect? If so, I would greatly appreciate links to any appropriate documentation on required keys in the data field.
I can't imagine there are permission errors since it works with demo functionality.
Currently, the message I am sending from my server back to the GCM app has the following fields, and by my understanding only three of these are required (everything except delay_while_idle?):
to (yes the proper key is here)
delay_while_idle (set to false)
data (JSON string of data)
message_id (autogenerated message ID in the pattern of the example code, essentially a random UUID)
Any help is greatly appreciated. If you feel that some code snippit is important, please let me know what you would like to see.
Ok, so this information was not present in my original post, but upon a bit more debugging this morning I discovered the problem.
In the packaging of my custom message to send along the path Server->GCM->Device, I erroneously put in the key/value pair of "data":"{JSON Dictionary}" rather than
"data": {JSON Dictionary}, and was missing the error being sent back by the GCM service indicating the JSON formatting error.
For any confused by that, the value for the "data" key in your GCM message must be a dictionary, not a string-form of the dictionary (an unintentional error on my part, autopilot fingers for the fail).

Is it possible to read incoming data stream, using java, from Server to .exe client (Coded using C++)?

Is it possible to read datastream sent from C++ server program to C++ client over socket connection in java? I have details like port number and server IP.
Or do I need decompile the whole C++ client into Assembly and then somehow translate it into java to do that?
I'm really not sure what kind of data it's transforming, though.. Somebody told me to code HTTP server and run it on my Router but I'm not really sure if that would work?
Here’s the diagrammatic way to look at it.
Server generates data.
it puts it in a packet.
it encrypts the packet.
and sends it over the wire.
It gets to a user’s Computer (= client). (I should be in the control now on..)
(If I could somehow read data at this part?)
The client reads the encrypted packet.
(If I could somehow read data at this part?) (The later, the better :D)
The client decrypts the packet.
(If I could somehow read data at this part?) (The later, the better :D)
The client does something.
As said, the client is .exe file and it's coded using C++. And I don't have source code of it.
All you have to do is define well your application protocol. This is, the format of your data stream. As long as you are using the same format in both ends, it doesn't really matter what language or program you are using. Imagine your browser and the web server. They are both using the same application protocol (HTTP) but they are completely different programs. Even more, there exists different web servers and different browsers.
Then, all you need to do is use the java sockets to listen to some specific port, and use your c++ sockets to write to the specific port. Just make sure you know how the information is "organized".

How does the server send feeds when they are unique to each application?

As the diagram suggests, there is one main server and more than one user application. Server in its database, has maintained a set of feeds for each application.In other words, each application will have a set of unique feeds.
How does the client application receive the feeds from the server ? The only problem that has kept me away from implementing this is, how client will ask the server to send its feeds. Even if the client pokes the server about the feed, how will the server send them or how will the client receive it. One way out could be, the server writes all the feeds to a file and then the client knowing the address of the file parse it extracting the relevant data. But it could be a very long process if the there are many clients connected to the server.
Note: The client application is a desktop application
You probably want to identify the client by a unique user string or by authenticating the user. The most common way for implementing this is probably basic authentication (username/password) or a security string.
Basic Auth:
User enters username/password in the client software which is bundled with the feed request using either POST or HTTP-BA.
Security/Identifier string:
User enters a unique string such as hashed user ID or alike, which the client bundles with the feed request. E.g https://feed.domain.com?identity=fed54bd54ae...
There's plenty of ways to differentiate clients. Imagine what you will do when you go to a store. Do you just stand there, waiting for the cashier to give you something? No, you ask for something. How you implement that is up to you. You can use different ports, different URLs, define the protocol so that the client passes the name or id of the wanted resource when it connects.... Nothing really special here.

Check File in the server is change or not

I am trying to make an app that connect to the server.
The app is used by some devices.
If one of the devices upload something to the server, I would like other devices receive the notification about the server has something new.
My question is, how to check the server is change or not? How often we must check the server?
I wonder how the Online Messaging work, because someone send something, we receive the message ASAP
Is the concept can be use with my app?
Sounds like you want to take advantage of Google Could Messaging or GCM for short.
http://developer.android.com/guide/google/gcm/index.html
This could be a lightweight message telling the Android application that there is new data to be fetched from the server (for instance, a movie uploaded by a friend), or it could be a message containing up to 4kb of payload data (so apps like instant messaging can consume the message directly).
GCM is the standard for how your apps "talk" to your servers. Either for a message in it's entirety or just a message to go check the server because it's been updated.

Easiest/most efficient way to constantly check & read PHP file for database changes in Java?

I have a simple Friend System in PHP using a MySQL Database. I also have a Java application where a user can send a friend request to someone via the PHP system, and the recipient can accept it. When the user sends a friend request, the PHP writes the sender and the recipient's username into a table on the database, and right now in order to check for the friend request, the recipient has to manually refresh a PHP file (which outputs the sender's username).
I'm using HttpConnection to manually check the PHP file and load the output, but I am wondering if there is a way to constantly poll or keep an active connection that reads updated information from the PHP file so that the recipient can automatically be notified as soon as the sender sends a friend request instead of reloading the file every second (that doesn't use a whole lot of bandwidth).
Thanks.
You could use AJAX to keep checking instead of the user performing a hard refresh.
Other option would be using a webworker:
https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers?redirectlocale=en-US&redirectslug=Using_web_workers
tkx

Categories

Resources