Multi-user chat interface: is this feasible?

Started by
7 comments, last by SolidStage 15 years, 9 months ago
I am working out ideas for a dedicated, online chat interface for an RTS game, which would work similar to Blizzard's Battle.net. With Battle.net, players can log in to the server from within the game interface and then chat & organize games with all other players logged into battle.net, setting up private chat channels, hosting/joining games etc. I wonder if anyone would be able to point out whether the following design architecture for such a system would be feasible, or has any obvious flaws: My server-side code would keep a list of everyone who has logged in (with their player-handle and their return IP-address with which to get through NAT/firewall), and when a client logs in (opens a connection to the server), the server sends the client the list of everyone in the main public chat channel. The client thus keeps a duplicate record of everyone in the current chat channel. The user then opens a connection with each of these other clients, forming a sort of peer-to-peer chatting network, so that whenever one client types a message it is sent to every other IP address in the current channel without going through the server at all. Only when the client wants to change channels, does it have to request information from the server in the form of a new list of IP addresses. And, of course, when a new client joins the channel via interaction with the server, the new client's IP address would be forwarded to all the clients in this sort-of private chat network to add to their lists. Is this overly complicated, or is it in fact how typical multi-user chat interfaces work? I'm motivated by the desire to reduce server bandwidth, which I assume would get to be heavy as the number of concurrent users increases, with every message typed potentially having to go out via dozens of duplicate packets to the various clients in a chat channel. I would appreciate any comments from someone more knowledgeable about this sort of system.
Advertisement
Quote:The user then opens a connection with each of these other clients, forming a sort of peer-to-peer chatting network


You'll have spotty success with this at best, if you use TCP. TCP through NAT (using simultaneous open) is nowhere near 100% supported in residential firewalls and operating systems.

Chat traffic is so low bandwidth (how much can you type in a second?) that you might as well bounce all the chat traffic off the server.
enum Bool { True, False, FileNotFound };
I would just write an IRC client interface, and use an IRC server. Writing an IRC client is trivial, and with it would open up alot of additional options using external clients, channels, and more features than just chat if you ever need them.
Hmm... OK, I'll look into IRC chat. I mainly want the interface to allow simple point-and-click hosting/joining of games like Battle.net. I hope something like this would still be possible? I don't have much experience with IRC, I will look into it though. Thanks.
Quote:Original post by hplus0603
TCP through NAT (using simultaneous open) is nowhere near 100% supported in residential firewalls and operating systems.


This worries me. I was planning to use TCP/IP for game-data communication during game sessions. I was hoping to have each of up to 8 players make a TCP connection to each other player, and then one or two times a second send a (small) packet to each of them containing either at maximum one or two orders/commands given by that player to his soldiers/units, and receive similar packets from each other player (the simulation will be 100% deterministic, using a common random seed & regulated calls to rand function, only passing player commands around & not processing a "game turn" until commands are received from every player or "no command" packet is received).

I was of the impression that communication through NAT simply required an "introducer" (my server) to give everyone the proper return address for everyone else, as determined by each player's initial communication with the server. I could fairly easily modify my design to use UDP but I was under the impression that RTS games typically use TCP/IP for game communication.

Is this too bound to fail? I think I either misunderstand your comment or misunderstand how TCP/IP and NAT work.
NAT punch-through with UDP is fairly well supported -- I would guess more than 90% of all residential firewalls support it.

NAT punch-through with TCP is not as well supported, unfortunately, both on the firewall side and the client OS side. The first version of Windows that properly implemented TCP simultaneous open (required for TCP NAT) was Windows XP SP2. Note that you need to bind to a known socket on the client before connecting for this to even be possible.

You have three options:
1) Use NAT punch-through with TCP, and tell people to get better firewalls/routers.
2) Use a version where people can set up port forwarding, and connect that way, and document how to set this up for players.
3) Send your data through the server. If it's a packet a second, that would not be so bad.

Ideally, you do all three, and automatically select the best version :-)
enum Bool { True, False, FileNotFound };
Quote:Original post by DrEvil
I would just write an IRC client interface, and use an IRC server. Writing an IRC client is trivial, and with it would open up alot of additional options using external clients, channels, and more features than just chat if you ever need them.


Ok, having read a little bit about IRC, I realize that I'm dumb. Battle.net *IS* an IRC server. Thats exactly what I want to implement, single-line message forwarding with slash-commands like /whisper for one-on-one communication and /join for joining channels or chatrooms, in addition to the dynamically updated list of games. I suppose my idea about creating private peer-to-peer networks is unnecessary.

All I want is to have users connect to the server via an in-game interface, and be able to type messages which I suppose can just be echoed by the server to all other users connected to the server in the same channel, via the return IP address they used to first connect to the server.

My impression is that TCP/IP would still be best for this, since I don't want to tolerate lost or out of order chat messages. If anyone with more experience implementing these types of systems could comment or correct me where I'm wrong I'd appreciate it. Thanks.
Quote:Original post by hplus0603
NAT punch-through with UDP is fairly well supported -- I would guess more than 90% of all residential firewalls support it.

NAT punch-through with TCP is not as well supported, unfortunately...


This sort of thing is very useful to know.

I can certainly modify my design slightly to work with UDP for actual game-communication, I already intend to divide game processing into "communication turns" anyhow and sending out packets containing player commands (or a definite 'no commands' message) for every comm turn, with a fixed delay between communication & processing, making it easy to notice when I am missing the packet for a particular turn and request it to be sent again before it becomes necessary to process it.

I am toying with the idea of buying or renting a dedicated server, & bandwidth usage is a key concern... if I can avoid sending all game data communication through the server (it may be only a few packets per second, but each has to be sent to each of at most 8 players, and received from said players) through a relatively easy method such as the above I would take it.

Thanks for your advice.

Do some quick numbers.

How much bandwidth is one user going to cost you? I think a reasonable upper bound for chatting would be about 1 kbps (kilobit per second--units are important). This means that each player's total in & out traffic is about 128 characters per second, which might be several short chat lines.

If a player stays connected at 1 kbps for an entire month (24/7) he uses about 321 MB of bandwidth. If you have a typical plan that offers you, say, 1 TB of bandwidth per month, that means that you can support 3,266 players simultaneously (assuming load is completely even).

A more sophisticated model, like you might see in a planning document for an MMO or some similar online service, would account for daily peak times and weekly peak times (e.g., when everyone gets home and can play at night, when everyone is free on the weekends, etc.).

It's completely reasonable to have players play the actual game among themselves if you're just trying to create a matchmaking service, but you're going to be doing a lot of work and opening yourself up to the problems that accompany additional complexity (and for not much gain!).

Even if you're planning to pass all game traffic through your system, I don't think you'll have much trouble. If your game uses an order of magnitude more traffic (say, 10 kbit/sec) then you can still support 326 players continuously, or say a baseline of 200-250 and a peak of 500ish. That's a lot of players!

I would suggest starting with the simple solution (having your gateway forward traffic). If you are very worried about the bandwidth (or better, when it actually becomes a problem), have your gateway check if each client is connectable. Whenever two clients need to communicate, if at least one is connectable, your gateway can instruct the two clients to perform a NAT breakthrough and directly communicate, which saves your gateway the traffic. You'll still have the gateway-forwarding method for pairs where you can't pull that off.

Hope some of that helps! Any details on your RTS project?

[Edit:] Yes, UDP is really where you should look, for the reasons mentioned above... but if you don't want to deal with it, there are many good networking libraries that provide reliable, ordered semantics on top of a UDP connection. See RakNet, ENet, TNL, etc.

Kevin
Solid Stage, LLC

This topic is closed to new replies.

Advertisement