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
Related
I've been through different questions about this topic, however, none of them have cleared my doubts on the best approach notifying the client side of a server-client IM app.
The Problem:
The whole problem is how to notify the client application of updates. I've alread seen the following approaches:
Clients keeps checking for updates: From time to time, client app performs a check in the server to see if there are updates for that specific user;
Problem: it is not performatic at all. Suppose you have one million users and each one of them checks for new updates every second. Serve would have to deal with one million requests per second. Wont work.
Client app opens a socket: The client app opens a socket and sends its address to the server. Server, by its turn, persists this information and connects to the socket whenever it needs to notify the client of some update.
Problem: Often the client will be connected to a NAT, so, the IP it has access to is in a non-visible range. In order to send messages to this client, a port forwarding in the NAT would have to be configured, which can't be done.
Despite of the technology, I think this approach will always be used, however, I have no idea how the problem described above can be solved.
Google Cloud Message (GCM): use the GCM service to notify the client of any update. Problem: It does't seems right to use a third server to handle the IM and it raises concerns about the scalability of the system. When the number of messages and users increases exponentially, it seems that the service will go down. Despite that, it seems that passing the information for two servers before delivering to the targets just adds bottlenecks in the process.
A combination of 2 and 3: uses GCM to reach the client when the last persist addres is no longer available.
Problem: same as described in 2
XMPP: I've seen many answers indicating the use of XMPP for IM applications, however, XMPP is a protocol - as per what I've foun in the web. I don't see how it can solve the problem described in 2 for instance.
Given the options above, can someone indicate me what line should I try to go for? Which one of these approaches has the best chances of success?
Thank y'all in advanced.
Use Google Cloud Messaging. Opposing to what you stated this service is built to scale to billions of users it will generally not introduce performance bottlenecks.
What you basically want to do is to use the messaging service to wake up devices. If you insist you can then still use your client server approach and thus your own protocol to have the client lookup new messages from the backend.
I'm developing an Android app that requires 2 (or more) devices to communicate with each other.
I tried using Google Cloud Messaging but I was disappointed to find out that the GCM max capacity is 100 messages, so it is broken and does not fit my requirements.
I was thinking about java sockets. Every device will open a new socket (or keep its socket open) and communicate with a group of sockets (devices).
In order to communicate this way I need a server-side app that can send messages to the client (android device). So I figured out that HTTP or web-service won't help me. Am I right?
What is the best way for me to implement such a server-side app?
You can refer to this question I previously asked and implemented. It was for implementing my own Notification mechanism but it equally (or even more) applies to chatting applications since message queues perfectly fit that usecase.
Building an Android notification server
I ended up not doing it and using GCM at the end but I did have a fully working solution using ActiveMQ and Paho. You can research them both and understand their inner workings. It's easy in principle and definitely possible but the problem is, you may not be able to do this for iOS or WP as it requires running a service in the background (in case your app is not open and you want to make sure the messages are at least sent in a notification).
The possible solution to that problem would be to use both the notification service (GCM or equivalent) for background notifications and then using your MQ for actual communication but I decided that was too much for my project.
If you look at Paho, it will have a fully working MQTT solution that will work even if the phone is not "online" (sleeping or otherwise) and there are plenty of samples for ActiveMQ and drivers for multiple programming languages.
I think this solution is much better than having open sockets between two apps, at least because they allow you to persist messages and guarantee delivery which is an important aspect for a chatting application.
As it is said by kha, choose one of the message queue protocols is the best solution. 3 reasons in brief,
Delivery guaranteed regardless of temporary offline or long latency.
As simple as subscribe / publish, no worry about transport layer any more.
Broker available online. You save time and money for setting up your own.
For mobile devices like in your case, I'd prioritize MQTT too. It's lightweight and stable. If you are totally new to message queue or MQTT, refer to this documentaion and example code
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
Which is the best way to connect 2 android phones in the internet with a Java Server?
I'm making an game form android. At this moment i have the single player working. But now i have two use an Java server to play online games.
Which is the best way to communicate with 2 phones ?
Most difficult action is send information of client1 to the Server and Server redirect this information to client 2.
Anyone can help me?
Regards
You can use either SOAP or REST, using Jax-RS (rest) or Java-WS (SOAP).
http://www.oracle.com/technetwork/java/index-jsp-137004.html
http://docs.oracle.com/javaee/6/tutorial/doc/giepu.html
Here is one way, assuming your game has some turn based interface, and you want to do is have a create game/join game or a create game with user style interface.
When the game starts, connect to the server using one of
the above techniques (soap/rest) to let the server know you are
there.
Then have one client say create a new game. This will tell the
server to create the game.
The other client will tell the server to list games. Then on
the client, choose a game to join. Then tell the server of the game
choice, so that it knows to add you.
The phone that started the game, should poll the server to see if
another user joined the game. Eventually some will join. (there are
other ways to handle this, but polling is very easy to do)
Have all players in the game poll to find out if the game started, then
go, once they have all joined.
There sure isn't a best way to do that. There are some techniques.
But what I would do is to create a long, unclosed http request from both of the clients to the server and then when something happens the clients get responses from the server. This is called Comet, but I never implemented that by myself. There sure is an Android implementation (or just a Java implementation).
I'm working on a browser game with the play framework, and I definitely need longpolling, but I don't quite understand how to use it. WebSockets would be perfect for this, but it's not supported by that many browsers yet.
Here's what I want to do: When the user logs in, and navigates to the play game controller, I want to start a connection, and keep it open. I want to do this for all users that are online, so I can show a list of them on the site, so they can play with each other. I've looked at the documentation, but I don't understand how I could implement it in my case. Because there simply isn't anything I want to calculate (in the example they're generating a pdf) I just want the connection to stay open.
What I'm also wondering is, how I should keep track of all these open connections? Right now, I just have an online column in my users table in the database, which I update. SO everytime someone connects I have to update the database. Are there better ways to do this, or is this fine?
And lastly, assuming all of the above works. When player A, selects player B to play with: how do I notify player B of this? Do I just send some JSON code, and change the page with javascript, on player B's side, or do I send him to a totally different page? I'm not sure how to communicate when the two connections are established and the game has started.
Firstly, I think you need to appreciate the difference between Websockets and Long Polling.
Websockets creates a connection and keeps it open until the browser terminates the session, via some javascript or the user moving on from the page. This would give you the desired nature of what you are requesting. Looking at the Chat example in the Play download will show you how an entire Chat application is handled using Websockets.
Further to Pere's answer regarding Play's statelessness. The Play creators have suggested that a single Websocket connection, regardless of how long it is open for and how many requests are sent back and forther, is considered to be a single transaction. Therefore, saving to the database in between each Websocket request is not needed (again, you can see that nothing is saved in the Chat example). Using this method, you would be expected to save the details when the Websocket is finally closed, or indeed all Websockets, depending on your use-case.
Long Polling on the other hand opens a connection to the server, and the server simply waits until there is something to send back to the client. If you need to push any data to the server, you would do this as a separate AJAX request, so you would effectively have two requests open at once. You don't necessarily know when a user logs off, unless you send a request just as they leave the page, to let the server know they have gone, but this is not always successful. Long Polling can work, but it is not as neat a solution as Websockets, but as you say, this is not widely supported yet.
My suggestion would be to study the Chat example (as it has a Long Polling and Websockets version). This will be the most effective way to get up and running with your requirements.
As for your final query regarding how to notify the other player. In Long Polling, you would simply respond to the suspended request with some JSON. With websockets, you would send an event back to the client. Again, both approaches can be pretty clearly figured out from the Chat example.
I have also written a Blog post on Websockets, which may help you understand this process a little better.
On the Websocket part, as you can see here (1st answer) the support is not so bad, and you have a Javascript fallback if there is some problem with the browser. This would simplify your scenario, as long polling may be more complicated to manage.
On the issue of keeping track, as Play is stateless you have to store the flag in the database and remove it when they close the connection. Otherwise you are breaking the statelessness.
About the notification, you have to send some message to B, but don't move them to another page as it may be confusing and cause bad user experience. Use Json to pop some message (in a div) alerting them of the game starting or the request to play.
I'm not using the "play" framework.
But I've been lately researching and tinkering with http-based long polling. Websockets, if available, is much more appropriate for realtime messages!
As for long-polling, I found that using a "cargo truck" analogy helped me reason about long-polling quite effectively. Here's a little note I wrote on the subject:
http://dvb.omino.com/blog/2011/http-comet-realtime-messages/
Perhaps you or future greppers may find it useful.
You might also want to take a look at the Juggernaut project which is based on node.js and Redis and gives you a "realtime connection between your servers and your client browsers". When using a Java Redis client like Jedis, you should easily be able to integrate the whole thing with the Play framework!