I am working on SMS application for a company, that sends SMS messages (SUBMIT_SM command) and receives the response from the SMSC (SUBMIT_SM_RESP command) to indicates if it is delivered to the customer. I am using JSMPP API.
What is the best practice to connect to the SMSC server? Should I open one connection (one session) and use it through the whole application to send SMS messages (any memory leakage here)? Or should I connect/disconnect to/from the SMSC server every time I send SMS message (any delays here)?
Note that, we are sending about 1000-2000 SMS messages per hour. Also I noticed that JSMPP API receives the response message (SUBMIT_SM_RESP) only when the connection is open.
That depends on the connection implementation. If your connection won't "die" during a long break than use one connection as it will save you time openeing/closing per request.
If your application is multi-threaded (where more than one thread can send a message) I advice you to implement a connection pool mechanism (or use an available one which supports SMSC sessions).
Related
I'm trying to make a communication between my App and the server side. The app needs to receive messages from the server because it's remotely controlled. It works as a Background Service.
I'm currently getting the messages from the external MySQL by using HTTPPost, doing requisitions every 20 seconds, but it spends much battery.
I tried doing a Socket connection to a server (build in java): device connects to the server every 20 seconds and close the conn when it just receive the data, but it also spends much battery.
Is there a way of receiving these messages instantly as Whatsapp does?
If the app is open it's most likely a socket connection. This is usually how messengers work.
In the background though it's most probably using push notifications (Check FCM - Firebase Cloud Messaging). This source of info can be unreliable so making a service with requests once a minute or two could be cool
In our messenger, we use long-live HttpsURLConnection as the main channel. The connection is hosted in Service and it is run in separate thread. In case of disconnect, we try to establish a new one. And we stop the service after our application is inactive for 2 minutes.
As the second channel, we use FCM.
This is what concerns messages. We also use WebRTC for multimedia data transfer. And we are going to use SIP calls to init voice- and video- call.
I'm building a service with Tyrus in Standalone Mode (Grizzly Server) where I send huge amounts of binary data via WS to a client. In my setup, the service is located behind a proxy server, so all data that is send, is first buffered at the proxy and after the proxy in the unix send buffer.
At a certain point in this transfer, I want to serverside close the connection. When i do so, the client gets the onClose event as soon as all the data waiting in the buffer and proxy is sent.
This behavior, where all messages are handled sequentiell and therefore the close message is the last one recieved by the client, is understandable.
But what I need is a way to close the WebSocket connection in realtime. Like the underlying TCP connection would close and therefor the client won't ever get the remaining data stored in the send buffer and proxy.
Does anyone got an idea how to create such an behavior with the Tyrus API?
I have a complete implementation of a protocol where four messages are exchanged between the client (a native Android application) and the server (a standalone Java server) in the following way using a persistent connection through Java sockets:
(client->server): message1
(server->client); message2
(client->server): message3
(server->client): message4
Between sending each message, both client and server have to do heavy mathematical (cryptographic) operations (pairing-based computations over elliptic curves).
This project works properly in my local development machine using sockets and mantaining opened this socket from message1 to the message4 between the Android app and the Java server. Now, I need to do the same with Google AppEngine, but since it does not allow opening sockets, I do not know how can I do it. I already checked the Channel and XMPP APIs, but I do not know whether my use-case applies to that APIs. Is it the right method using Channel and XMPP APIs from AppEngine? Is it possible to emulate the functionality implemented in my local machine through sockets on AppEngine?
Thank you for your response.
Google App Engine doesn't support persistent connections.
You will need to significantly re-design your protocol to run over HTTP.
As an example, message1 can be sent over an HTTP request, message2 can be returned with the matching HTTP response. At that point, your socket connection ends.
You'll have to issue a second HTTP request to open a new socket with message3, and you can return message4 with the second HTTP response.
You can "connect" the first and second HTTP request by using an HTTP session. A session is basically an id with extra data stored on the server side. You'd create the session in the first HTTP request, and pass it as a parameter to the second HTTP request. The server can look up the session id and the associated data when processing the second request.
You can find more info about sessions on SO: How to use session on Google app engine
The XMPP API will not help you, it's for communicating between the GAE server-side code and other XMPP clients that use HTTP as a communcation protocol.
The Channel API can be used to send data from the server->client, but it's actually implemented as an HTTP long poll. Multiple long HTTP requests are used, and you are not guaranteed to have a single socket that stays open; multiple sockets are opened and closed in the process. It will be more complicated that what I described above, and more expensive.
I'm working on a multi-client application that will connect with a server in the LAN.
Every client can send a command that changes the status of the server.
This 'ServerStatus', as I will call it, is an object with some values.
Now if the ServerStatus changes, all clients should know about it immediatly.
My idea was to work like this:
Server sends a multicast to all listening clients with a versionNumber of the ServerStatus every second. So if a new client joins the multicast group, he will see if his versionNumber is the same.
If not, the client will ask the current version of ServerStatus via UDP.
When a client sends a command that changes the ServerStatus,
the server will send his current (and new) ServerStatus to the same multicast group,
while in another thread, the versionnumber of ServerStatus is still shared every second.
Do you guys think this is a good way to deal with this?
Or will this cause too much problems,... etc
What happens if the new ServerStatus fails to reach the clients? In my opinion you should not use UDP when sending the new status to the clients, but a reliable protocol. So if you intend to use multicast on this you will have to get a reliable multicast protocol.
On the other hand, you may prefer client synchronization with the server:
Every time a client enters the network it asks the server its statusid (if not the same, the server sends him ServerStatus) and the client also registers for new status change events. (TCP)
When leaving, the client could send a UNREGISTER message (UDP).
Each time ServerStatus changes, the server sends the new ServerStatus to each registered client. On receiving the new Serverstatus the client would send an ack-like to the server.(TCP)
If the ack was not received by the server, the client in question would be unregistered (because it would mean the client had left the network without unregistering - by error).
hope this helps..
Basically, your idea sounds good to me
I would suggest you dig more into principals of "group communication", and look at frameworks such as jGroups, I know that JBoss Cache uses it to distrubte data among its nodes.
Maybe for reliability clients should also query the server once in X seconds, to see they they ave the correct version number,
or at least perform this when they are started / recover from crash.
Can a J2ME app be triggered by a message from a remote web server. I want to perform a task at the client mobile phone as soon as the J2ME app running on it receives this message.
I have read of HTTP connection, however what I understand about it is a client based protocol and the server will only reply to client requests.
Any idea if there is any protocol where the server can send a command to the client without client initiating any request?. How about Socket/Stream based(TCP) or UDP interfaces?.
If the mobile device doesnt allow you to make TCP connections, and you are limited to HTTP requests, then you're looking at implementing "long polling".
One POST a http request and the web-server will wait as long time as possible (before things time out) to answer. If something arrives while the connection is idling it can receive it directly, if something arrives between long-polling requests it is queued until a request comes in.
If you can make TCP connections, then just set up a connection and let it stay idle. I have icq and irc applications that essentially just sit there waiting for the server to send it something.
You should see PushRegistry feature where you can send out an SMS to a specific number have the application started when the phone receives that SMS and then make the required HTTP connection or whatever. However, the downside of it is that you might have to sign the application to have it working on devices and you also need an SMS aggregator like SMSLib or Kannel
You can open socket connection and implement "Hide" (or "Minimize") functionality in your app. Call this to hide:
Display.getDisplay(MyMIDlet.instance).setCurrent(null);
Listen to the server in a loop, and if you receive some message, popup the applicaion by calling this from canvas:
Display.getDisplay(MyMIDlet.instance).setCurrent(this);
But it dosen't work on all devices.
Socket push are supported by j2me. But it could work only if your server could deliver data to your mobile phone. Most likely that operator gateway don't allow to do this.
Maybe it would be possible if your mobile has static external IP address - some operators could provide this for $$.