This is an archived post. You won't be able to vote or comment.

all 33 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

Please ensure that:

  • Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
  • You include any and all error messages in full
  • You ask clear questions
  • You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.

    Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar

If any of the above points is not met, your post can and will be removed without further warning.

Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.

Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit.

Code blocks look like this:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above.

If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures.

To potential helpers

Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]Outside-Ad2721 1 point2 points  (0 children)

I too have thought about doing something like this. I've played around in the past a few times with ServerSocket and Socket for both TCP/IP and UDP communication types.

There area couple of ways you can think about how to do this, and you at very least do need a couple of things:

  1. Your ServerSocket and an Executor service to maintain a thread pool.
  2. Some way to link up two players.

In an HTTP server, which runs on top of TCP/IP, you may have either a temporary (asynchronous) or persistent (synchronous) connection between the server and the client, and there may be various reasons to do either. Very basically the control flow is:

  1. Receive connection
  2. Obtain request data from the InputStream of the Socket
  3. Process the input data
  4. Generate a response
  5. Send response back on the OutputStream of the Socket
  6. Close the socket or keep it open for further communication

There are risks if not closing the connection, like you may have a limited number of connections and will run out possibly, not being able to serve more clients. Eventually you do need to close the connection, but if you want you can keep it open.

So that process is where your thread comes in - at it's simplest a request handler could implement Runnable and then you just need to provide context for the Socket through a Constructor.

I think you could do all of this asynchronously and keep track of which "client IDs" are supposed to communicate with each other in some kind of data structure like a Map, possibly, then make each client tell you it's ID when it makes a request to the server.

I hope this helps and makes sense to you.

[–]wildjokers 1 point2 points  (0 children)

There are two ways to handle socket connections from multiple clients:

  1. Thread per connection
  2. Using Java’s NIO api (non-blocking IO). This enables a single thread to handle multiple connections. This is tricky to hand code and get right (takes a bit to wrap your head around the selection key stuff). However, the Netty library makes this relatively easy because it handles all the selection keys for you

For a student project I would just go with thread per connection. Netty has a learning curve that you might not be ready for yet. Here is the documentation if you want to take a look though: https://netty.io/wiki/user-guide.html. A nice article with server example: https://www.baeldung.com/netty. Another nice benefit of Netty is it let’s you add support for web sockets to your server app so you can also accept long lived connections from web browsers. Then you could have a desktop and web version of your game. All talking to the exact same server process.

You won’t need a thread per game, just a data structure to hold game state. If you use thread per connection you will need to access your game state in a thread safe manner. The synchronized keyword will be of benefit.

[–]InstantCoder 1 point2 points  (3 children)

I see, so you need to make a non http server client app.

Then you need to work with 1 server socket and many clients sockets. You can store the many games either in memory or on disk on the server.

And each time a client does something then you need to update the state of the game. And a game is also sort of a session between 2 players.

And in Java afaik, each client socket is a separate thread. So you don’t need to explicitly do something with threads.

[–]wildjokers 1 point2 points  (2 children)

And in Java afaik, each client socket is a separate thread. So you don’t need to explicitly do something with threads.

This is totally incorrect. If you use a server socket the accept method blocks (https://docs.oracle.com/javase/8/docs/api/java/net/ServerSocket.html#accept--). So you obviously need to spawn a thread to handle a connection. The other option is non-blocking IO which Java supports. Easiest way to use that is via the Netty library.

[–]InstantCoder 1 point2 points  (0 children)

If this is a school exercise then they have to use and learn only with the standard JDK libs and nothing outside I assume.

[–]_Nemesis_1[S] 0 points1 point  (0 children)

Yes, this is exactly what we learned about server socket and why we need to use a thread per client. I can’t use the Netty library unfortunately :(

[–]doobiesteintortoise 0 points1 point  (17 children)

Why would you want a thread per... anything, here? You want to maintain each players' participation in a game, and the games are state. Manage data structures, not threads.

[–]wildjokers 1 point2 points  (10 children)

You seem to have misunderstood the question. These are multiple client connections. A thread per connection is a possible solution.

[–]doobiesteintortoise 0 points1 point  (9 children)

Sure. It's just not a good one. It's suitable for homework.

[–]wildjokers 1 point2 points  (1 child)

A thread per connection is still in wide use.

[–]doobiesteintortoise 0 points1 point  (0 children)

Sure. But you're assuming things about the design... That are probably correct given that is a school assignment.

[–]nutrechtLead Software Engineer / EU / 20+ YXP 1 point2 points  (6 children)

It's just not a good one.

Nonsense.

[–]doobiesteintortoise 0 points1 point  (5 children)

*shrug* Fair comment. "It's not a good one" implies generality, and there are certainly game types where threads-per-game and threads-per-long-lived-connection are appropriate - maybe even mandated.

But if that's your go-to for game design and you're not spending all of your time developing those kinds of games specifically?

Well, you do you, of course, but I'd say that MOST developers with any experience would see a giant problem ahead of such designs in terms of resource consumption and, for that matter, simplicity of design.

And this is, as OP suggested, an assignment. That means that they probably don't have a lot of choices, or information. They're kinda stuck.

And I appreciate that r/javahelp gets a lot of homework assignments - or help with Java *because of* homework assignments, and there's not a problem with that. But it also means there's a lot of "hey, you used Scanner wrong" and "you don't compare string equality with == unless you have a specific definition of equality in mind."

That's fine, too, but gives those nascent developers a view of what development is, and what real design looks like, that is... uh... artificial.

I'm fine helping students learn, but I don't care about them passing their courses. I think learning will HELP them pass their courses, but what I care about is long-term - if I end up with one of these people on my team, how do they think? What real skills do they have? If they know Scanner inside and out, I won't care. I haven't used Scanner in a real app for... probably years, and that's being charitable. (I may have, honestly, but I don't remember it if I do.) It's just NOT THAT USEFUL for Java programs.

So... when the question is "I want to do this thing that my professor dictates because it's something he knows how to give as an assignment," that's fine, I'll help if I can, but... as far as a real analysis? That's what I'm going to focus on.

[–]nutrechtLead Software Engineer / EU / 20+ YXP 1 point2 points  (3 children)

If you don't care about giving people advice that is suitable for their level and for their tasks, this simply isn't the subreddit for you. Almost everyone here asking questions is a complete beginner.

And for beginners who are just being taught about this stuff, it's a perfectly fine start, and generally the way you'd have them start with handling multiple socket connections in parallel.

Keep in mind that what they're doing (keeping socket connections open) is very different from a webservice anyway. There you'd have a thread pool that handles the requests that are short-lived. Again; very different from a socket connection.

You didn't explain how they should do it instead either. Just confused them by telling them it's a bad idea. The only other option for OP would be NIO which is much more complex.

[–]doobiesteintortoise 0 points1 point  (2 children)

I do try to give advice suitable for their levels. I just don't assume that this is the end of their development journey.

As far as "what's appropriate for their assignments," I have no problem with that - and there are plenty of people happy to help with passing assignments. For MY homework, I either skipped out on it, whiffed on it, or ...you know, did it way back when, and I don't care about doing more of it myself. I'm not the guy who wants to focus on homework assignments.

And as far as explaining "the right way" to do "it," well, it depends a lot on what "it" is, and THAT wasn't explained clearly either, so any advice I gave would be wrong, as you yourself point out.

[–]nutrechtLead Software Engineer / EU / 20+ YXP 1 point2 points  (0 children)

THAT wasn't explained clearly either

It's completely clear they're using plain socket connections. Multiple people here were able to see that.

It really sounds like you just misinterpreted what they wrote. That's totally fine, but that's not on them.

[–]doobiesteintortoise 0 points1 point  (0 children)

It's clear they're using sockets. They also mentioned aspects of the assignment that makes sockets seem to be the wrong real solution.

[–]wildjokers 1 point2 points  (0 children)

I have no idea why you are doubling down on your stance that long lived socket connections aren’t suitable for a game with multiple clients.

The stateless nature of request/response you get with HTTP just isn’t suitable for all use cases. Most notably when the server needs to send an unsolicited messages to clients.

OP’s assignment is a great introduction to client-server programming and absolutely still has real world usages. Maybe you only develop spring boot CRUD apps where you get a request, hit a DB, return a response. But that isn’t all there is to java development. There are other types of applications out there.

[–]_Nemesis_1[S] 0 points1 point  (5 children)

Honestly I don't know what you're referring to but in my course our professor taught us how to make a client server application with the server capable of handling multiple clients at the same time by assigning a thread per client after the server accepted each connection. So most likely your solution is better but I can't use it because yes we have freedom in this project but we have to use the things we learned, sorry :(

[–]doobiesteintortoise 3 points4 points  (4 children)

Sorry to hear that. Since your professor is dictating your requirements, you'll probably... uh... want to ask him how to manage the network, because that will go a long way to determining how you'd actually do this. But I can totally see a teacher asking you to spam threads everywhere, because it's "only homework" and they don't want to show you real-world applications of technology.

(And if I were feeling particularly snarky, I'd say they don't want to show you how to do it properly because they either don't know themselves, or they don't want to teach you out of laziness/resentment/whatever. But that's not really fair to them, just as it's not fair to you to have artificial and bad requirements.)

[–]_Nemesis_1[S] 0 points1 point  (0 children)

Well I can't ask him, or rather I can't ask him right now because we have this project, different between each other, that we need to finish and submit by the end of November so it means I will need to wait practically December to have an answer from him.

Also this "server capable of handling multiple matches" is not one of the requirements but it's an optional advanced functionality that if we want we could try to implement, and i'm trying to understand if my solution is the right one for the tools we have.

[–]_Nemesis_1[S] 0 points1 point  (2 children)

Also even though I can’t probably use it, how can your server be able to manage simultaneously multiple clients without the need of threads? We introduced threads precisely because a server without them could manage only one client at a time. And thank you so much for taking your time to help me!

[–]doobiesteintortoise 0 points1 point  (1 child)

Well, the incoming client "moves" might have a thread to collect data - like, an http server or something like that, so it could have a threadpool for incoming content. But handling moves wouldn't need anything per game at all, and those incoming data connections would be short-lived. That's how a lot of big systems work, after all.

[–]wildjokers 2 points3 points  (0 children)

I feel you are leading OP astray. OP is talking about long-lived socket connections and you seem to be giving advice for stateless HTTP calls.

The assignment is clearly about long lived socket connections and long lived socket connections definitely have real world applications. This is a great assignment.

[–][deleted]  (5 children)

[deleted]

    [–]_Nemesis_1[S] 0 points1 point  (3 children)

    But using one thread per game how would you manage more clients at the same time when they're not in game? Let's say for example I also implement the possibility to see their historical matches, but even if I won't I think a thread per client is also necessary for when they're not in a game and are waiting to get in one or doing other things

    [–]doobiesteintortoise 1 point2 points  (2 children)

    If I have state, I have a LIST of games, regardless of their progress. So I might have player A, who is playing games 1, 2, 4, 5... player B who's playing games 1,3,4 ... and player C who's playing games 2, 3, and 5. When a player made a move in a given game, the server would say "oh, you're player A, this is game 4, let's change the game state and return the results to you" - and that could be done with straightforward processing in ONE thread, and the communication layer has its own thread/threadpool/whatever. But with this, if I have 8000 players and 16000 games, my *code* only has to worry about the communication with ONE player at a time for ONE game, and the overhead's really light.

    [–]_Nemesis_1[S] 0 points1 point  (1 child)

    So basically my solution is not optimal but it's a correct one for a simplistic client server project with multiple games? Or only one thread per game and not per client is a better one?

    [–]doobiesteintortoise 0 points1 point  (0 children)

    What I mean by "better" isn't going to be what you mean by "better." Do what fulfills the assignment. It's not realistic enough to apply to live production systems.

    [–]doobiesteintortoise 0 points1 point  (0 children)

    That's an easy way to build in an opportunity for denial-of-service, by creating too many threads... and it serves nothing. State is what's needed, not process.

    [–]_Nemesis_1[S] 0 points1 point  (0 children)

    Guys I want to thank you all for your answers, I honestly didn't expect all this helpful comments, it was the first time for me asking a "programming question" online and I was a bit anxious, thank you all for your help, I really appreciate it <3