I've been researching stackoverflow for days now, but can't seem to find a problem like mine.
I have an Raspberry Pi with a python socket server listening for incoming messages. Also I have a Android app which connects to it.
My idea was to create a "simple" music player on the raspberry pi with the use of the pygame module. You can see the Android app as the controller of the music player (Sonos like).
I already have a start, connecting the Android app with Raspberry pi is not the problem.
It's more how the communication between the two need to flow.
A few "solutions" I already thought about:
At the moment the Android app creates a socket object and connection in a new Thread then closes the Thread (so the Thread doesn't receive or sends messages, but the socket persists). When the user clicks a button (let's say to update the music list), it opens a new Thread then uses the already created socket object to send a command, gets a response and updates the UI then terminates the Thread again. And I do this for every action that needs to happen (play, pause, stop, etc.) With this method only the Android app has the right to ask for an action, because it's not constantly listening for server messages
So what if I would create a single thread which is in a constant loop sending a message and then getting a response: how do I interact with the loop from the main UI thread (like clicking a button). I thought about a synchronized List<String> MessageQueue where the main thread pushes a command and in the connection thread's while loops it checks if there are any messages that need to be send.
I made a little schema, how I had this in mind:
Schema (single thread with while loop):
single thread with while loop
Also the reason I chose sockets and not just a simple HTTP request is because later on want to update the UI so you can see real-time music playing (with the seconds updating and stuff like almost every musicplayer has, and who knows what more.
If you guys have any idea's, or know of any topics, example applications on how to create this then please share! If some things are not clear or are a little vague, feel free to ask/comment because I just started with asking on forums.
Example applications that use persistent socket connections with real-time communication are also welcome!
side question: would JSON be a good way to communicate between the 2 applications?
like this:
{
currentsong: "song1.mp3"
position: "1.30" // The current position the music is playing on the server
songlist: ["song1.mp3","song2.mp3","song4.mp3"]
...
}
Related
I was reading about background service limitation in Android 8 and from what I read it seems that you can't run your service in the background for a long time. This seems reasonable but because I use background service to keep connection to server - currently pooling new stuff, sending location and responses I am a bit confused. The responses are OK, I can respond only when interacting with the app, but the pooling new stuff is problematic because it needs to get an stuff from server and if something new come present the user with a notification to respond to it.
If I understand it correctly I can use JobScheduler to schedule some job every several seconds. I can basically schedule the pooling. For the background locations, well there are those restrictions so only foreground service is an option to get updates in requested time.
I will be migrating to websockets and then the pooling is off, the connection to server will be persistent and the app will get updates from server, I was planing to do this in the background service so something would receive stuff from server everytime. However it seems I can't since Android 8. How would you solve this? Should I use foreground service for location and server connection? Or is there a better way to do background networking in an android app on android 8?
Thanks
Here are a few options for performing background work on Android O:
Use JobScheduler. You already seem to have a good grasp on this one- the downside is that it is periodic, not persistent.
Use GCM/FCM or a similar push service to push data to your app when it is relevant instead of constantly holding a connection to your server.
Use a foreground service. This will allow you to continue performing your background work without your app being in the foreground, but will put a notification in the status bar to inform your user that you are doing that work.
Before you select one of these methods, you should take a moment to step back and look at the data that you need from your server and determine why you need a persistent connection and whether the first or second options might be sufficient.
If you absolutely need a persistent connection to your server, the last option is your best option. The idea behind the changes in O is to still allow background work such as what you are describing, but to make it painfully obvious to the user that your app is doing so. That way if they don't think your data is as important as you do, they can take action.
I need to persist a socket connection when my android app goes to background.
Currently, the socket is started, read and written from its own thread. I also store a reference to this thread in a static instance of a class which means i have access to the thread's reference when my app is resumed.
I also don't need this socket to be persisted if the app is destroyed.
Now coming to my question, "Do i need to start a service to maintain this thread or can i just continue with my current design which is to store all such instances that i require when the app resumes in a static container class?"
The only advantage i found so far of using a Service is that the app might be one of the last few to be destroyed during low memory or similar scenarios by the OS (considering the service and the app reside in the same process).
Once your Activity is destroyed, your process becomes a candidate for being shutdown. Most likely, it will linger around a while and not get killed. But on a lower end device, with less memory, all bets are off. Go to Developer Options on your device and check "Don't keep activities ...". Exit the activity and see the outcome.
The workaround is to keep a Service active. Preferably with a notification icon so the user knows it's still running. That's exactly what I did with my music app to allow the audio stream to keep going even when the user switched apps.
On the flip side, a dedicated socket connection is going to use more battery and more of the user's data plan. If your socket is going to be idle most of the time, a better approach might be have the socket connection connect to the server only when notified via a push notification that there is data available.
I'm developing a multiplayer turn based strategy game in Java (both client and server). I don't have much experience in networked games but I have done small things like a multiclient chat and 2 player tic tac toe with sockets. I'm not looking for someone to code this for me but just give me some guidance.
The game goes through multiple stages: first a user connects and logins. After he is given the option to host/join a game. After he joins a game or someone joins his game, the client moves on to the game stage. The game is 1v1 and only needs to send data back and forth every 5 seconds (if that's important?). I just need some guidance on how you could design a client/server to move through these "stages".
This is how I'm currently thinking of implementing it:
When a connection is made the connection will have a corresponding variable that describes state on the server. For example: 0 is before login, 1 is after login, 2 is hosting, etc...
Whenever the client sends data to the server it checks for the state and deals with it accordingly. Like before login if data is sent, the server will assume it's login details and if they're valid it changes the variable to 1 and tells the client to advance.
Is there a better way to do this?
Since is Full Java + Client-Server + Game:
I recommend you to forget using straight sockets.
In my opinion Java RMI is your best bet.
Why?:
Easier than sockets once you have it learned.
You can call remote methods straight from your java client/server.
You can use callbacks. (i.e. Server testing that the clients are still connected)
There are probably even more reasons...
Essentially how you described it is how it is commonly done. Simply have a server listening for client connections, and then deal with client connections in its own thread as they come up. Then send messages back and forth to confirm state (logged in vs. logged out, joining game, etc.) and messages while in game for player moves. Either a TCP or UDP socket will work in the short term, however eventually you will probably switch to a primarily UDP based system as the messages sent between server and client will be fairly small and latency could be key depending on the game type.
Consider sending/recieving messages via JSON (http://wiki.fasterxml.com/JacksonHome is a fairly popular Java parser last I checked).
Additionally, you'll need several data structures on the server side to efficiently manage clients and their states. For example, you could have an integer id for each client and a Map<Integer, Client> that you would use to store all currently connected logged in users, where Client is some object that stores the current state of that user.
Hopefully this gives you some ideas on where to start.
You can use Mina or Netty as Nio socket framework. Using Java both in server and client makes it easier to design message protocol. When one client moves, you send a moving message to the server, and then server pushes back a message to both clients. Both clients move together when receiving the message. Thus two clients move synchronously if avoiding network delay.
You can take a look at the open-source game framework written in java.
java game server engine
I'm programming an Android multi-player game, which basically consist of a server where the clients connect and exchange messages. When the player connects to a server, a player list is return to him/her. A player can then select a user to challenge - of course he must select a player from the player list, which only contains connected users.
When a player1 challenges player2, a message needs to be transmitted from player1 to the server, which in turn must send a message to the player2, notifying him about the challenge. The player2 can then accept/decline the challenge.
I can use the following techniques to make this happen:
Use custom server/client with Java socket programming. The server basically accepts a connection from the client, spawning a new thread for each connected client. The problem with this are:
There needs to be a persistent connection open from client to server wasting battery life of the android phone. This is not really big limitation since the battery isn't consumed that much.
When I'll want to develop another game I'll have to rewrite the client/server code from the scratch - also choosing another port to listen for incoming connections - the whole concept gets rather difficult to maintain.
I'm also worried if this is the way to do it. Spawning another thread for each clients sound quite a lot if thousands clients are connecting at the same time. But I'm guessing the PC games do it like this. Not sure about android.
Use Java REST jersey to build the client-server on top of HTTP. This would be a perfect solution if the server could easily send notifications to clients. There are actually multiple design decisions here:
the client pulls the server for any new data/notifications every few seconds - this is really bad, since we're stuck with non responsiveness, delay, etc.
the client can send a waiting request to server, so the client receives the response only after some data becomes available. This is better, but can still produce a delay when two notifications one after another need to be sent to the user. The first notification is sent instantly, since the client already has a connection open, waiting for data to receive. But we would have to wait for the client to initiate another long http request to receive the second notification. The problem gets bigger as there are multiple notifications that need to be send in a row to a specific client.
the client can initiate a http streaming, where the communication is left open when the request is handled, so the server can also send multiple messages to client whenever it wishes. The problem here is that I don't know how well this works on Android. I've looked at several implementations:
Java jersey + atmosphere: didn't succeed in actually making it work. This seems the most promising, but I don't want to spend too much time on it, since I'm not even sure if it does what I want.
Deacon: seems pretty neat, but after seen the video tutorial on their official web page, I'm not sure that it can do what I need. When a player1 challenges player2, can it send a notification to player2 letting it know about the match request?
I would be glad to know how other multi-player games handle the network communications, if the two players are playing the game over the network.
I'm also open to a totally new suggestion how to achieve what I want. I can pretty much code anything, so don't hesitate to let me know of some more difficult way to achieve the network communication.
Let me also mention that I'll be glad to implement a totally specific method to work in my case, so it can be anything that will do the job done, but I'm also looking at more general way for communication between clients and server. So that I can program an interface/whatever and reuse the code in other android games, android applications.
I hope I presented the problem allright and that I'll receive some valuable answers.
Thank you
You should take a look at XMPP. It's a protocol (originally created for chat programs) that allows sending of xml data between users.
It has a separated client-server relationship, so that you can focus on developing a client application fit for phones, and a different server depending on your needs.
There are loads of information available on the protocol (I should know, I wrote a thesis about using the protocol in game applications), but you can start by looking it up on wikipedia to see if it is what you want.
aSmack is a library for creating android xmpp-clients. It takes some tweaking to set it up and get everything to work, but once you do, it's neat.
EDIT: relating to the answer suggesting using the C2DM:
from the c2dm docs "Sending large numbers of C2DM messages":
Are you sending C2DM messages too frequently? If you need to communicate with your application frequently over a short period of
time, C2DM is probably not the best solution. Instead, consider
implemeting XMPP or your own protocol to exchange messages, and use
C2DM only to send the initial notification.
It sounds like Android Cloud-to-Device-Messaging might be what you need
Push notifications without the app having to keep a connection open
I would vote in favor of some message passing technique - like activeMQ, rabbitMQ, zeroMQ eor something like it. On the server side you may stick with java , or javascript ( like
node.js ) - such solution would provide most performance and minimal latencies.
If latency is not that critical, you may as well use REST calls with JSON
I want to implement an android app which could communicate with a Server via internet. Since everytime the Android app connects to Server, there will be a connection established, and Android app will maintain this connection for the purpose of receiving msgs from Server. However, at the same time the Android app has to deal with User inputs, so these two tasks have to run concurrently that needs to realize by two Threads. I do not have experience about multi-threads programming. any suggestions? Thanks. leon.
The user interface is being handled by the main thread, so really you just have to set up one thread handling the networking (in fact, on 3.0 and on opening a socket connection from the main thread will throw an exception!).
Set up and maintain the connection to the server using an AsyncTask - this is a fairly easy way of doing multi threading. Take a look at this documentation: http://developer.android.com/resources/articles/painless-threading.html
Did you try to put the server interaction into a thread? This should be no problem at all
Thread thread = new Thread(this){
public void run() {
// do your server interaction
}
}
thread.start();
You may want to consider Google's Cloud To Device Messaging (C2DM). They manage to keep a connection open to a device for long periods and will push your server notifications to any android device. I believe its still currently in the 'labs' stage though.