I have a concept of a game system that includes (preferably) Java server and multi-platform clients (Web, Android, iOS).
This is a 1vs1 player-vs-player realtime game. Servers performs a matchup of 2 players. So basically server needs to handle many matches containing 2 players. Both players alter same data, and each player should be updated in realtime with actions of other player.
Can you suggest me:
1) Server-side framework/library that would ease the implementation, as I would rather not start learning node.js from the scratch. :) Vert.x comes to mind.
2) Should clients hold the replica of the data, and alter it locally (meaning only data that is transfered are only commands, here I see JMS as good solution), or should only server alter the data and then send the complete data set every time change occurs?
3) How should the data be transfered? Considering the multi-platform requirement only thing I see viable are WebSockets.
4) An example/tutorial of server handling pairing of WebSocket connections? All I ever found are 1-to-1 connections.
5) Considering scalability, can you explain how could all this work in a distributed environment?
1) I don't think node.js is such big deal to learn. I would personally prefer a well known - broadly used framework.
2) If you are considering mobile, probably the first option seems more sound. You should consider send/push deltas during the game, and still provide functionality to retrieve the full state of the game in case the client disconnect and connect with same ID.
3) WebSocket would be the best option. Push approach, TLS option and well supported. Another option is the WebRTC data connection, that is peer-2-peer most of the times. I say most of the times because if one of the users is behind a dynamic NAT router or restrictive firewall, it won't be possible, and you will need a TURN (relay) server. Anyway, it is less supported than WS.
4) You should not "pair websockets". The WS connections just input commands to your logic, and your logic broadcast events to whoever it wants. Despite of being a 1vs1 game, probably you want to inspect the flow of events for further debugging or analysis. So consider WS as a transport, not as an entity.
5) Very, very, very broad question. But assuming that you are going to use WS, and that your application will be so successful that you will need multiple servers... assume that it is impossible to predict that two users will connect to the same server, so you should consider a message bus that allow to play users from one server with the users in other server. An EDA (Event Driven Architecture) would make sense.
Related
I'm looking to have a network of bukkit servers that all operate under a single game mod that allows for inter-server communication. The conventional way to do this is to utilize a MySQL database and have all the servers pull from the database periodically (5 seconds or so) to keep all the servers up to date. I'm wondering if there is a better way to accomplish this.
I have an idea, but I don't know enough about networking to know if it is feasible. I'm considering having the game mod run under it's own java server (here-on referred to as the mod server and not related to bukkit). The mod server will have all the data associated with the mod and it will be responsible for executing all the computation regarding the mod (handling money transactions, adding and removing claimed land, and dealing with the tax cycle). All the bukkit servers interface with the mod server whenever it needs to determine if, for instance, a player can break a block, or hurt another player. All changes to the data of the mod is done on the mod server. The bukkit servers are essentially just portals to interact with the mod server. As long as the mod server is single threaded, then there shouldn't be any concurrency issues, race conditions, or conflicts.
I've been reading into Remote Method Invocation and I was thinking that maybe it was the avenue to accomplish this. The mod server would be considered the RMI server, and the clients would be the Bukkit servers. I read through the documentation for the Java Sockets, but I'm not sure that it's what I'm looking for. I'm having a difficult time googling it because it's only a concept for which I don't know all the technical terms. Any ideas or suggestions? Thanks.
Each bukkit server should be in charge of managing the players on it and only those on it. Thus you don't need this mod server to handle SQL when you can simply load player data when a player joins that specific server. Any updates to the player can be done on the local data and then committed to the database when the player leaves or when it happens. As an example, or server uses zPermissions for cross server permissions. It updates on change and players who change to another server have all their permissions from the original. The only problem here is when the group permissions change which simply needs a permissions reload to update, but those will not change often once your server gets organized.
Are you using BungeeCord? If you are, you can create your own plugin channel.
You can send and recieve data from every subserver (bukkit server) to the master server (bungeecord proxy) via your own channel. Here is an explanation:
http://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/#the-bungeecord-plugin-channel
Let's consider application using WebSockets which can be divided into several, independent modules. A simplest example would be chat application where client app can join/connect to several chat rooms at once (each chat room is independent from each other). What is the preferred aproach of organizing the connections while developing such application
Open new websocket connection in client for each chat room. This way you'll have multiple instances of javax.websocket.server.ServerEndpoint on the server side, each with different url. Both the server and client apps will thus be a little bit less complex and can be separated into functional (reusable) blocks. The drawback is that the client will have to keep multiple opened connnections at once. In my case we're talking about up to ten max at a time.
Open one websocket connection and multiplex the messages to chat room underneath, i.e by field with chat room id in the messages. Not a big deal to implement, will make the app a little bit more complex, but is it worth it?
What is the preferred approach?
This is not easy to answer generally, for it depends on your specific setup. However, here are my thoughts on this:
I think option 2 is the better approach, because open connections are really a limited resource for many webservers. Remember, that a websocket connection is different from a regular http request and stays open over a long time. The additional complexity of the multiplexing protocol is really not an issue I think. All implementations I know of websocket communication protocols use the latter approach, although I must admit to not know really many examples.
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
Scenario: User logs in on the client software which forms a persistent bidirectional connection with the serverside entity (server) which would process user specified tasks. When the serverside entity, while processing user's task, encounters an error or requires further user input, it will notify the client software, and wait until the client decides what to do. The client software will take the new user specifiefd inputs and send this to the serverside. The serverside continue where it last stopped with the new user specified inputs. This feedback cycle will continue until it's finished processing. The progressively updated user inputs will all be stored on the serverside and accessible and modifiable from the client software. So if a client deletes a specific input, that change will be immediately reflected on the serverside. On the serverside, an extra interface is probably required to route different user's clients to available hardware nodes (cloud) to support concurrent multi-user tasks running on the serverside.
On the client side, I suspect using sockets to connect to the server...
Now for the server, I am a little lost because there seems to be many different Java servers like Jetty & Netty. I am also practicing caution in order to not try and reinvent any wheels here.
Is building a server the right approach? or Build a webservice that will complete a specific task on demand?
I am also not just looking for a one size fits all solution (wishful thinking probably) but open to any insights on my current situation.
Netty will provide a lot of what it sounds like you need for this, without making you reinvent a socket server. That said, I would make certain that you actually need bidirectional, real-time communication between the client and server. If you can rework the problem such that the client-server communications do not need to be real-time, then things like RESTful webservices become a possibility, and (in my experience) are much less complicated and error prone.
I am developing a chat website using jsp/servlet.I will be hosting my website on gooogle appengine .Now i have some doubts regarding whether to use server push or client pull technology
1)If i use server push and if i dont close the response of servlet will it cause the server to go slow?How many simultanious connection can a tyicall tomcat server can handle if i keep the socket open for the entire chat session between 2 clinets??
2)Will server push or clinet push be better??
If you are using a servlet (prior to 3.0), then I guess you'll have to go with pull because of the programming model of servlet. However, there ARE advantages in using a push model. Primarily, wasted load on server and the limitation in latency. That's why there are technologies such as comet. Servlet 3.0 also supports push model. These are commonly used in ajax based apps.
In fact I believe a push model is more suited for a chatting app. because of the fast response time (=better user experience) it can provide.
If you use a nio based implementation for push-model, you can support thousands or even more than 10k concurrent connections (obviously, your millage varies).
If you use a conventional IO based implementation, it will be likely in the range of hundreds of concurrent connections (don't take this estimation too seriously though. I'm just giving these numbers to give a very, very rough feeling).
As for tomcat, last time I checked, people were saying that it won't have a good push-model support until version 7.0. But I'm not following the current status so I'm not sure (Sorry, perhaps somebody else can help you on this). If that is the case, you might want to check out comet support of jetty.
grizzly and netty are also good NIO based network frameworks, but if you want to use JSP, and find that tomcat is not sufficient, I guess jetty would be the best bet.
edit: (some additional info)
In this "push models", it's not like the server opens a connection to the client. The connection will be kept alive, and the server will push messages as it sees fit.
Also, it's not like there are only "push" and "pull" models. You can have a hybrid, like long polling.
I don't know how are you thinking of achieving server push here. As far as I can see, server needs a request to respond over HTTP. So, when there is a request, server will respond to that.
If i use server push and if i dont close the response of servlet will it cause the server to go slow?
App Engine will not let you do that. You have to finish your response within thirty seconds, or it will be killed. The thirty seconds is also an edge case, most calculations they do (for quota and such) are based on a 75 millisecond response time.
How many simultanious connection can a tyicall tomcat server
Tomcat? I thought you are planning to use App Engine?
Pull. Always pull.
I know it's a manufacturing-oriented book but the advice from Lean Thinking (Womack & Jones) is invaluable in any context (roughly, from memory):
Start by defining value,
line up the activities that create value in the value-stream,
create flow across the value-stream,
let customers pull value from the value-stream,
compete against perfection rather than other organizations
If I misquoted them, I apologize. Anyway, all of those principles can easily be applied in the development of any software product just as they could in the production of any physical product but the one that matters for you is pull.
Letting consumers of a service pull rather than pushing to them not only makes your programming model easier, it aligns activity with demand. You can still use queuing to load-level over time, if you have to, just the way you could with push but, this way, you have complete visibility into what, exactly happens in any given transaction.
I don't quite get your first question but the answer is still pull.
The answer to your query depends on what underlying protocol you wish to use.
Since you have mentioned JSP/servlets, your app will be implemented over the HTTP protocol.
HTTP is a protocol over TCP. TCP is connection oriented and remains alive, until the connection is ended. However, HTTP connections are persistent, only for the duration of a single request-response cycle. The TCP connection is broken after every request-response cycle. So that should answer your doubt with regards to how many socket connections a typical TOMCAT server will be able to handle. The connections will not be persistent, at all. They will only last the duration of a HTTP request-response cycle.
Given this basic idea, I would suggest , you use a client pull strategy, to implement your app.
Even with server push, over HTTP, even though the name says "server push", it is always the web client that polls the server at regular intervals, which just gives an illusion of "server-push". HTTP specification mandates that the client makes a request to which the server responds.
I have considerable experience in developing chat applications (both mobile and web).
Let me know , if you need any assistance. I will be more that willing to help.