Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

How to Make Multiplayer TCP Flash Game?

Explorer ,
Apr 11, 2015 Apr 11, 2015

I have a game in the works, and though I got the UDP to work perfectly, I sadly later found out that that is simply just a lossy protocol. There's apparently (as far as my knowledge goes) nothing you can do to make it resend data if the data was not received successfully by the recipient.

So, I was wondering how to use TCP? I've heard it's possible, but I can't seem to find a single tutorial or any information anywhere on how to do it. I found on Adobe's site socket connections, and though I got the server to connect (I think), I have no clue how to send data to it, how to get other clients to connect to it, etc. Any help?

This is the script I've been using, and though it does connect... that's basically all it does, I don't know where to go from here...

package

{

    import flash.display.Sprite;

    import flash.events.EventDispatcher;

    import flash.events.Event;

    import flash.events.*;

    import flash.events.IOErrorEvent;

    import flash.events.ProgressEvent;

    import flash.events.ServerSocketConnectEvent;

    import flash.net.ServerSocket;

    import flash.net.Socket;

    

    public class TCP extends Sprite

    {

        private var serverSocket:ServerSocket;

        private var clientSockets:Array = new Array();

        public function TCP()

        {

            try

            {

                // Create the server socket

                serverSocket = new ServerSocket();

                

                // Add the event listener

                serverSocket.addEventListener( Event.CONNECT, connectHandler );

                serverSocket.addEventListener( Event.CLOSE, onClose );

                

                // Bind to local port 8087

                serverSocket.bind( 8087, "127.0.0.1" );

                

                // Listen for connections

                serverSocket.listen();

                trace( "Listening on " + serverSocket.localPort );

            }

            catch(e:SecurityError)

            {

                trace(e);

            }

        }

        public function connectHandler(event:ServerSocketConnectEvent):void

        {

            //Thesocket is provided by the event object

            var socket:Socket = event.socket as Socket;

            clientSockets.push( socket );

            

            socket.addEventListener( ProgressEvent.SOCKET_DATA, socketDataHandler);

            socket.addEventListener( Event.CLOSE, onClientClose );

            socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError );

            

            //Send a connect message

            socket.writeUTFBytes("Connected");

            socket.flush();

            

            trace( "Sending connect message" );

        }  

        public function socketDataHandler(event:ProgressEvent):void

        {

            var socket:Socket = event.target as Socket

            //Read the message from the socket

            var message:String = socket.readUTFBytes( socket.bytesAvailable );

            trace( "Received: " + message);

            // Echo the received message back to the sender

            message = "Echo -- " + message;

            socket.writeUTFBytes( message );

            socket.flush();

            trace( "Sending: " + message );

        }     

        private function onClientClose( event:Event ):void

        {

            trace( "Connection to client closed." );

            //Should also remove from clientSockets array...

        }

        private function onIOError( errorEvent:IOErrorEvent ):void

        {

            trace( "IOError: " + errorEvent.text );

        }

        private function onClose( event:Event ):void

        {

            trace( "Server socket closed by OS." );

        }

}}

TOPICS
ActionScript
5.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Apr 12, 2015 Apr 12, 2015

unless you're using a server that all players connect to, you should be using adobe's peer-to-peer networking (rtmfp).

Translate
Community Expert ,
Apr 12, 2015 Apr 12, 2015

unless you're using a server that all players connect to, you should be using adobe's peer-to-peer networking (rtmfp).

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 12, 2015 Apr 12, 2015

Thank you, I actually just found some documents online (one a server, one a client) and got the client to connect, as long as the server is on the same computer. I tried putting the server on one computer and a client on the other but the connection failed... is there something I'm missing here?

Here's an example of the client's script:

sock.connect('127.0.0.1',8910);

// receive data from socket

function onSocketData(e:ProgressEvent):void

{

    trace(sock.bytesAvailable + ' byte(s) available');

    // read the socket data

    if (sock.bytesAvailable > 0)

    {

        // (I know it's a string for this example)

        var msg:String = sock.readUTFBytes(sock.bytesAvailable);

       

        trace(msg);

       

        if (msg == 'Connected.')

        {

            // send a message back to the server (which it will return to me to confirm it worked)

            sock.writeUTFBytes('Thanks for connecting!');

            gotoAndStop(2);

        }

        // flush!

        sock.flush();

    }

}

Thank you.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 12, 2015 Apr 12, 2015

you'll need to use the correct ip for the non-local client.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 12, 2015 Apr 12, 2015

Alright, I looked up that the IP to connect to the LAN for the server is supposed to be like this:

serverSocket.bind( 8080, "192.168.1.4" );

But I get this error:

Error #2002: Operation attempted on invalid socket.

It seems to only work when I set it to:

(8910, '127.0.0.1');

What's going on here?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 12, 2015 Apr 12, 2015

test from a non-local computer.  ie, a file server.

otherwise you're probably encountering a cross-domain security issue.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 12, 2015 Apr 12, 2015

Alright thank you for all the info, was very helpful. I have one more question though, it seems that the method I've been told to use: sock.writeUTFBytes('message'); seems to only send back to the socket the message was originally from, rather than sending the message to multiple clients from the server... I was wondering if there was a simple way to tweak the code to do this, or do I need a new method entirely? Again, thanks!!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2015 Apr 13, 2015

again:  unless you're using a server that all players connect to, you should be using adobe's peer-to-peer networking (rtmfp).

ie, with multiplayer each player can communicate with a server and the server communicates with each player, or you use peer-to-peer communication.  below is an excerpt from a book i wrote (Flash Game Development: In a Social, Mobile and 3D World).

Social Gaming - Multiplayer Games

With multiplayer games, data needs to be communicated among the players.  When a player makes a move (changing the game state) the updated game state needs to be communicated to all the other players. In addition, that communication needs to occur in a timely manner. 

With turn-based games (like card games) that communication among players can take as long as few seconds without degrading the game experience. With real time games (like shooter games), even a 250 millisecond delay in communicating game state leads to a significantly degraded player experience. Consequently, real time multiplayer games require substantial expertise to successfully develop and deploy.

There are two fundamentally different ways that communication among players can be accomplished. Players can communicate via a server (server-based games) or they can communicate directly from player to player (peer-to-peer) games.

Server Based Multiplayer Games

Generally, the code in each player’s Flash game handles the player’s input, transmits player data to the server, receives other players' data and displays the game state. The server receives player data, validates the data, updates and maintains game state and transmits each player’s data to the other players.

The code used on the server cannot be ActionScript so you will need to learn a server-side coding language like php or c#.  Server-side coding is beyond the scope of this book so I will not cover server-based multiplayer games except to say you need to have advanced coding skills in, at least, two languages (ActionScript and a server-side language) to create these game types.

Peer-to-peer games

Since Flash Player 10, you can create multiplayer games without the need of an intermediary server to facilitate player communication.  The Flash Player can use a protocol (Adobe's Real-Time Media Flow Protocol) that allows direct peer-to-peer communication.

Instead of using server-side code to handle the game logic and coordinate game state among players, each peer in the network handles their own game logic and game state and communicates that directly to their peers and each peer updates their game state based on the data received from others.

To use peer-to-peer networking each peer must connect with an Adobe server.  Peer-to-peer communication does not go through that server (or it that would not be peer-to-peer) but peers must stay connected with the Adobe server in order to communicate with each other.

To communicate with the Adobe server you should use your own server URL and developer key. That URL and key can be obtained at http://www.adobe.com/cfusion/entitlement/index.cfm?e=cirrus.

Below is a simple tic-tac-toe game that uses Adobe's peer-to-peer networking to pair-up players.  The NetConnection class is used to establish a connection to the Adobe server while the NetGroup class is used for peer-to-peer communication.

I used only a small part of the NetGroup methods for the tic-tac-toe game but there are more available if you are sharing data among many users and/or sharing large amounts of data.

The tic-tac-toe game is in support files/Chapter 11/multiplayer and is extensively commented

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2015 Apr 13, 2015

Right, I got an AIR socket server that they're supposed to connect to, and so far it works with the client on the same machine the server is. I have used RTMFP but it was way too lossy, unless there's a way to fix that I want to use the server.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2015 Apr 13, 2015

is your server your local computer?

is the problem client on your local computer?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2015 Apr 13, 2015

Yes, the server is a simple AIR application on my local computer.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2015 Apr 13, 2015
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2015 Apr 13, 2015

Alright, I'll try that, but I do have one more question, it seems when I try to send a signal to the other client, it simply sends the signal BACK to the client that sent the message... I understand this isn't an error in the programming, because the method I'm using is apparently SUPPOSED to do that, I just have to find out how I'm supposed to make sure the signal sends to ALL the clients instead of just back to the sender, do you have any ideas?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2015 Apr 13, 2015

the message will be sent to the server.  then it's up to the server to send that message to everyone else.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 14, 2015 Apr 14, 2015

Right, but what code is used for the server to send the message to everyone else? When I use

socket.writeUTFBytes('whatever');

socket.flush();

It just sends it back to the sender rather than everyone connected to the server. I don't know how to get it to send to everyone. Is there a simple way to do this or do I have to manually set something up for the server to keep track of multiple clients?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2015 Apr 14, 2015

what's 'whatever'???

you need to an array of users.  google a tutorial on whatever server you're using.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 14, 2015 Apr 14, 2015

'whatever' is just whatever the message is, a string, for example.

And I will try, I have been Googling allover the place for tutorials but they're hard to find, however, thank you, you have been very helpful.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2015 Apr 14, 2015

you're welcome.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 14, 2015 Apr 14, 2015
LATEST

I got it figured out!!

To get it to send to all the clients (sockets), I just had to put this into the server at the line where it sends over the UTFBytes:

for each (var socket:Socket in clientSockets)

{

socket.writeUTFBytes(message);

socket.flush();

}

Of course, I also had an array set up: var clientSockets:Array = new Array();

Also, to get it to connect to my LAN, I actually had to REMOVE the IP address in the server, so it connects with: serverSocket.bind(8080);

Then, with the client, I connect it to the server using: sock.connect('localhost',8080);

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines