Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (581)
games submitted by our members
Games in WIP (500)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1]
1  Game Development / Artificial Intelligence / Re: Determing player/objects within a certain radius of "self" on: 2006-02-18 01:25:29
Just read it, and although it have some interesting ideas its not really a complete solution. I have my doupts about the architecture they suggest, but even if that works out the paper doesnt describe the most important properties of the technique, the datastructure and algoritme to support this approch. If I read it correctly it also seems to delegate some responsibility for the interest management to the client. Thats like building in exploits =)

On a side note, I study computer science myself, and this paper have many phases where it feels like the "I dont understand this, lets toss out some fancy word and skip over it" solution  Grin

Edit: As an example, using aura calculations is technically the most precise answer to telling which objects are within LOS, but you need to do an initial reduction of the set of object you will have to perform this operation on. Also, this method alone doesnt work very well in term of determing when an object should be "removed" from the knowledge of another client. The same moment that updates no longer come in, the observer have to know that it can remove the object, so that it doesnt seem to freeze.
2  Game Development / Artificial Intelligence / Re: Determing player/objects within a certain radius of "self" on: 2006-02-18 01:06:47
Seems very interesting, gonna give it a read. Thanks for the reply
3  Game Development / Artificial Intelligence / Determing player/objects within a certain radius of "self" on: 2006-02-17 14:25:20
Hi

Im looking at some advice for a method for determing which players/monsters are within LOS (ie within a certain radius) of another player/monster emitting an event of sort. Im working on the server for a game where we have some pretty large playfields (mmo style) and where transmitting every event to the entire playfield population is not an option. So the problem really boils down to: given an object with an x,y coordinate, find a fast way to determine other objects that are within a certain distance.

Let me start by telling about my current idea for an algorithm/datastructure. I'm thinking about splitting the entire playfield up in non-overlapping squares of side width equal to the wanted LOS in the game, lets say 50x50. Meaning the entire playfield is sort of covered in tiles. When a player moves around he is constantly associated with a single square. Once the player generates an event I can then create a list of "observers" present in the current square, and the 6 squares around it. That ensures that I find all observers within 50 units of the event without getting the entire population. This structure also gives me a simple way of keeping track of which players have been "introduced" to each other, and thereby when to send a "CharEnteredAreaEvent" and such things.

Anyway, im pretty new to all this so I was hoping I could pick up a few suggestions on other ways to do something like this =)

Thanks in advance
4  Game Development / Networking & Multiplayer / Re: Java in consideration for MMORPG on: 2005-05-26 15:43:20
Any chance you can explain what you mean by a copy-free stack? Am I correct in guessing that it means that you dont parse game commands/packets out of the buffers and create object of them, but instead let your logic work directly on the buffer?

Thanks
5  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-27 14:37:05
In my code I have a similar setup. I have my ConnectionListener object that also waits for new connections and then give them to the "client processer"/ConnectionWorker object, through the same queue&wakeup mechanism you have describes. That wakeup doesnt cause any problems.

The problem seems to be when wakeup is called and the thread then returns to .select() without having performed some operations that modify its internal state. Also note that it seems that the behavior is almost impossibel to create (ive done it a few times) with conections comming from same machine as the one hosting the server. I'll be using my sparetime the next days to make an application for a friend but after that Ill get coded some extra test classes so that other can try to reproduce the issue (with the intention of making a bug report)
6  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-27 08:34:53
Quote


I'm saying that I don't see the point in enabling non-blocking mode on a socket when using channel selectors.  Why would you?

-Chris


Without non-blocking your write calls would block until the data had been written. the selector giving a writable key doesnt have to mean there is space in the write buffer to write all your data.

Quote
Unless otherwise specified, a write operation will return only after writing all of the r requested bytes. Some types of channels, depending upon their state, may write only some of the bytes or possibly none at all. A socket channel in non-blocking mode, for example, cannot write any more bytes than are free in the socket's output buffer.


That really breaks the concept of multiplexing io where you just want to process what can be processed immidiatly. Im not sure on the behavior of socketchannel.read in blocking mode (and the api doc isnt specific on that) but I would assume it block until buffer is filled.
7  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-27 08:25:25
Ill try to put some client code together that can make it easier to reproduce the behavior.

If what you'r saying is correct, then isnt it impossibel to do a workaround to this problem? In theory the addNewConnections method could be called while the selector thread was out in the select loop, and had last returned a 0-set. If the new connection had then been closed before being processed it wouldnt be registered. Without the register() call (which seems to reset internal state) the selector would be in the same situation as in my test code. It of course takes a good portion of bad luck to have the thread scheduler "pause" the selector thread out in the select loop, but thats not something you can guard your code against.
8  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-26 18:11:06
Heres my current test code, got it somewhat down in length.

addSocketChannel(SocketChannel sc).. is called by the ConnectionListener and is the only place any other thread calls any method in this object.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
public class ConnectionWorker implements Runnable{

    private FIFOQueue newConnections = new FIFOQueue(10);
    private Selector selector;
    private Thread internalThread;
    private ByteBuffer readBuffer;

    public ConnectionWorker() throws IOException{
      selector = Selector.open();
      readBuffer = ByteBuffer.allocateDirect(1000);

      internalThread = new Thread(this);
      internalThread.start();
    }


    public void addSocketChannel(SocketChannel sc){
      newConnections.addObject(sc);
      System.out.println("Calling wakeup()!! new socket added to queue");
      selector.wakeup();
    }


    private void closeChannel(SocketChannel sc){
      if (sc == null) return;

      SelectionKey sk = sc.keyFor(selector);
      if (sk != null) sk.cancel();

      try{
          sc.close();
      }catch (Throwable t){
          t.printStackTrace();
      }

    }


    public void run(){
      int nSelKeys = 0;
      System.out.println("[ConnectionWorker] Starting service");

      while (true){
          //Register the new connections in queue
         for (Object o = newConnections.getObjectNow(); o != null; o = newConnections.getObjectNow()){
            SocketChannel sc = (SocketChannel)o;
            if(!sc.isConnected()) continue;
            
            try{
                System.out.println("[ConnectionWorker] Registering new connection");
                sc.configureBlocking(false);
                SelectionKey sk = sc.register(selector, SelectionKey.OP_READ);
                System.out.println("INNER WAKEUP");
                //selector.wakeup();

            }catch (Throwable tr){
                tr.printStackTrace();
                closeChannel(sc);
            }
          }

          try{
            nSelKeys = selector.select();

          }catch (Exception e){
            e.printStackTrace();
            return;
          }

          System.out.println("[ConnectionWorker] Selected " + nSelKeys + " keys");
          if (nSelKeys == 0) continue;
          
          Set keys = selector.selectedKeys();
          Iterator i = keys.iterator();

          while (i.hasNext()){
            try{
                SelectionKey sk = (SelectionKey)i.next();
                i.remove();


                if (sk.isReadable()){
                  //Read so that it wont keep returning key
                 //In case test klient sends data
                 readBuffer.clear();
                  int readBytes = ((SocketChannel)sk.channel()).read(readBuffer);
                  if (readBytes < 0) closeChannel((SocketChannel)sk.channel());
                }

            }catch (Throwable t){
                t.printStackTrace();
                continue; //next key
           }  

          }//end while (i.hasNext())

      }

    }//end run()

}
9  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-26 18:07:47
Okay I've figured out what causes the problem, dunno if you would classify it as a bug.

In my original test code I made a ConnectionTenant object for each connection, which would hold an internal write buffer. The tenant would ready some welcome/ackknowledge data in a bytebuffer, and on setSelectionKey(SelectionKey sk) it would call back to add itself to a "wantToWrite" queue. Effective result of this was that the selectors own thread called back into a method that called selector.wakeup.

In the current version of my code I dont even write (and dont have to read either, just got the code for it to handle disconnects):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
          //Register the new connections in queue
         for (Object o = newConnections.getObjectNow(); o != null; o = newConnections.getObjectNow()){
            SocketChannel sc = (SocketChannel)o;
            if(!sc.isConnected()) return;
            
            try{
                System.out.println("[ConnectionWorker] Registering new connection");
                sc.configureBlocking(false);
                SelectionKey sk = sc.register(selector, SelectionKey.OP_READ);
                System.out.println("INNER WAKEUP");
                //selector.wakeup();

            }catch (Throwable tr){
                tr.printStackTrace();
                closeChannel(sc);
            }
          }


The code is placed before selector.select() in the select loop. If I comment out selector.wakeup() everything runs as normal, but if its not the selector will start to return immidiatly on select. The wakeup placed in the code snippet will only be called for every new connection, so its not like it queue a new "wakeup request" up each loop. Ive made test where wakeup() in the select loop is called one time, but the selector keep non-blocking select until a new connection is made.

An imporant note is that if I connect to the server with telnet from my workstation (where I also run the server) I cant create the bug. The first time (most of the time, sometimes take 2-3 connections) I connect with telnet from my "test machine" (stands right next to workstation, both connected to same switch) it will start its non-blocking select. I dont know enough about low lvl io to say anything based on this, but it obviously has an effect that its a "real" network connection.
10  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-26 17:22:22
If I leave them in blocking mode (default for new connections) then Ill end up with blocking read and write calls and that pretty much kills the idea.
11  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-26 17:16:39
I've tried inlining as much as possibel, and made a lil discovery. If I register the connection for OP_WRITE right from the beginning then I cant create the problemo, so seems it could be related to the sk.interestOps(sk.interestOps() | SelectionKey.OP_WRITE) call. Ill get some more tests done on this before posting more code, cant really get it down to 60loc so far.

Another little note is that it seems much easier to create this condition when run the flash client on another computer, so might be a time factor involved.
12  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-26 12:36:19
Ive tried a System.out.println("...") before both wakeups, and its never called. The selector just returns immidiatly on .select(); until a new connections is added.

It keep returning on select (produce 4mb logfile in 10-15 seconds) so is not because wakeups is queued.
13  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-26 12:03:35
The basic princip is that only the selector thread does selector related operations. New connections are added to a queue and the selector thread then registers them as part of the select loop:

1  
2  
3  
4  
5  
6  
7  
8  
  
//Executed for all new connections
//ConnectionTenant is a buffer holding object
sc.configureBlocking(false);
ConnectionTenant ct = new ConnectionTenant(this);
SelectionKey sk = sc.register(selector, SelectionKey.OP_READ, ct);
ct.setSelectionKey(sk);
 


Similar, if the connection tenant wants to write, it adds a request to a queue, as part of the select loop the thread then modifies interestOps with this:

1  
2  
 //Executed for each connection that wants to write
sk.interestOps(sk.interestOps() | SelectionKey.OP_WRITE);


The SelectionKeys returned by selector.select(); is checked for valid operations by this code:


1  
2  
3  
4  
5  
6  
7  
 if (sk.isReadable()){ 
     if (!processRead(sk)) return;
 }
 
 if (sk.isWritable()){
     processWrite(sk);
 }


If its readable the reading is done with this:

1  
2  
3  
4  
//Using a shared direct bytebuffer for reading in the available data. In this example the data is never passed on/used
readBuffer.clear();
 ReadableByteChannel rbc = (ReadableByteChannel)sk.channel();
 int numBytesRead = 0;


And if its writeable:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
//ConnectionTenant holds a writebuffer for the connection. Get the buffer and write from it. ConnectionTenant takes care of preparing buffer to be written before returning it.
ConnectionTenant ct = (ConnectionTenant)sk.attachment();
 
 if(ct.hasData()){
     WritableByteChannel wbc = (WritableByteChannel)sk.channel();
     

  ByteBuffer writeBuffer = ct.getOutputBuffer();
  wbc.write(writeBuffer);
   
  ct.onWritePerformed();



The initial handling of the Set returned by the select operation is handeled by this code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
//If the selector returned any keys iterate through the key set and toss each of them off to processing
    if (nSelKeys == 0) continue;
     
     Set keys = selector.selectedKeys();
     Iterator i = keys.iterator();
 
     while (i.hasNext()){
  SelectionKey sk = (SelectionKey)i.next();
  i.remove();
 
  processKey(sk);
     }


Hope it made it a bit more clear
14  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-26 11:43:18
Im using 1.4.2 and have tried it on both windows 2000 and windows xp. Ill just get the important stuff typed out for the selector loop.
15  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-25 20:25:43
Should be irrelevant, but heres the ConnectionListner:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
import java.util.*;
import java.net.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;


public class ConnectionListener implements Runnable{


    private Selector selector;
    private Thread internalThread;
    private ConnectionWorker cw;
    private String host;
    private int port;

    public ConnectionListener(String host, int port) throws IOException{
      this.host = host;
      this.port = port;

      selector = Selector.open();
     
      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking(false);
      ssc.socket().bind(new InetSocketAddress(host, port));
      ssc.register(selector, SelectionKey.OP_ACCEPT);
     
      cw = new ConnectionWorker();

      internalThread = new Thread(this);
      internalThread.start();

    }



    public void run(){
      int nSelKeys = 0;
      System.out.println("[ConnectionListener] Starting service");

      while (true){
         
          try{
            nSelKeys = selector.select();

          }catch (Exception e){
            e.printStackTrace();
            return;
          }
         
          if (nSelKeys == 0) continue;
         
          Set keys = selector.selectedKeys();
          Iterator i = keys.iterator();

          while(i.hasNext()){
            SelectionKey sk = (SelectionKey)i.next();
            i.remove();

            processKey(sk);
          }

      }

    }//end run()



    private void processKey(SelectionKey sk){
      if(!sk.isValid()){
          System.out.println("[ConnectionListner] Invalid key");
          return;
      }

      try{
          ServerSocketChannel ssc = (ServerSocketChannel)sk.channel();
          SocketChannel sc = ssc.accept();

          cw.addSocketChannel(sc);

      }catch (Exception e){
          e.printStackTrace();
          return;
      }

    }//end processKey()



    public static void main(String[] args) throws Exception{
      if(args.length < 2){
          System.out.println("Syntax: ConnectionListner <host> <port>");
          System.exit(0);
      }

      int port = 5000;
      String host = args[0];
     
      try{
          port = Integer.parseInt(args[1]);
      }catch (NumberFormatException nfe){}

      System.out.println("host: " + host);
      System.out.println("port: " + port);

      ConnectionListener cl = new ConnectionListener(host, port);
    }





}
16  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-25 20:24:18
ConnectionWorker: The selector object

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
import java.nio.*;
import java.nio.channels.*;
import java.io.*;
import java.util.*;

public class ConnectionWorker implements Runnable{

    private FIFOQueue newConnections = new FIFOQueue(10);
    private FIFOQueue writeRequests = new FIFOQueue(10);
    private Selector selector;
    private ByteBuffer readBuffer;
    private Thread internalThread;
   
    public ConnectionWorker() throws IOException{
      selector = Selector.open();
      readBuffer = ByteBuffer.allocateDirect(1000);

      internalThread = new Thread(this);
      internalThread.start();
    }


    public synchronized void addSocketChannel(SocketChannel sc){
      newConnections.addObject(sc);
      selector.wakeup();
    }

    public synchronized void addWriteInterest(SelectionKey sk){
      writeRequests.addObject(sk);
      selector.wakeup();
    }

    private void closeChannel(SocketChannel sc){
      if (sc == null) return;

      SelectionKey sk = sc.keyFor(selector);
      if (sk != null){
          if (sk.attachment() != null){
            ((ConnectionTenant)sk.attachment()).onShutdown();
          }
          sk.cancel();
      }

      try{
          sc.socket().close();
      }catch (IOException e){
          e.printStackTrace();
      }

      try{
          sc.close();
      }catch (Throwable t){
          t.printStackTrace();
      }

    }

    private void processNewConnections(){
      for (Object o = newConnections.getObjectNow(); o != null; o = newConnections.getObjectNow()){
          SocketChannel sc = (SocketChannel)o;

          if(!sc.isConnected()){
            return;
          }
         

          try{
            System.out.println("[ConnectionWorker] Registering new connection");

            sc.configureBlocking(false);
            ConnectionTenant ct = new ConnectionTenant(this);
            SelectionKey sk = sc.register(selector, SelectionKey.OP_READ, ct);
            ct.setSelectionKey(sk);

          }catch (Exception e){
            System.out.println("Error caught in processNewConnections(). Printing stack trace: ");
            e.printStackTrace();
           
            closeChannel(sc);
          }
      }

    }//end processNewConnections()


    private void processWriteInterests(){
      for (Object o = writeRequests.getObjectNow(); o != null; o = writeRequests.getObjectNow()){
          SelectionKey sk = (SelectionKey)o;
          sk.interestOps(sk.interestOps() | SelectionKey.OP_WRITE);
      }

    }//end processWriteInterests()
   


   

    public void run(){
      int nSelKeys = 0;
      System.out.println("[ConnectionWorker] Starting service");

      while (true){
          processNewConnections();
          processWriteInterests();
         
          try{
            nSelKeys = selector.select();

          }catch (Exception e){
            e.printStackTrace();
            return;
          }

          System.out.println("[ConnectionWorker] Selected " + nSelKeys + " keys");
          if (nSelKeys == 0) continue;
         
          Set keys = selector.selectedKeys();
          Iterator i = keys.iterator();

          while (i.hasNext()){
            SelectionKey sk = (SelectionKey)i.next();
            i.remove();

            processKey(sk);
          }
      }

    }//end run()


    private void processKey(SelectionKey sk){
      if (!sk.isValid()){
          System.out.println("[DEBUG] Invalid key");
          return;
      }
     
      if (sk.isReadable()){
          if (!processRead(sk)) return;
      }

      if (sk.isWritable()){
          processWrite(sk);
      }
     
    }//end processKey()


    private boolean processRead(SelectionKey sk){
      readBuffer.clear();
      ReadableByteChannel rbc = (ReadableByteChannel)sk.channel();
      int numBytesRead = 0;
     
      try{
          numBytesRead = rbc.read(readBuffer);

      }catch (Exception e){
          e.printStackTrace();
          closeChannel((SocketChannel)sk.channel());
          return false;
      }
     

      if (numBytesRead < 0){
          closeChannel((SocketChannel)sk.channel());
          return false;
      }

      readBuffer.flip();
      //Discard data in demo


      return true;
    }//end processRead()



    private void processWrite(SelectionKey sk){
      ConnectionTenant ct = (ConnectionTenant)sk.attachment();
     
      if(ct.hasData()){
          WritableByteChannel wbc = (WritableByteChannel)sk.channel();
         
          try{
            ByteBuffer writeBuffer = ct.getOutputBuffer();
            wbc.write(writeBuffer);
           
            ct.onWritePerformed();

          }catch (Exception e){
            e.printStackTrace();
           
            closeChannel((SocketChannel)sk.channel());
          }


      }else{
          sk.interestOps(sk.interestOps() & (~SelectionKey.OP_WRITE));

          if (ct.isRequestingShutdown()){
            closeChannel((SocketChannel)sk.channel());
          }
      }

    }//end processWrite()

}
17  Game Development / Networking & Multiplayer / Re: Selector not blocking on select on: 2004-02-25 20:23:33
ConnectionTenant: A "controller" for each connection, just a seperate outputbuffer in this example:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
import java.nio.*;
import java.nio.channels.*;

public class ConnectionTenant{

    private SelectionKey sk;
    private ByteBuffer outBuffer;
    private ConnectionWorker cw;

    public ConnectionTenant(ConnectionWorker cw){
      this.cw = cw;

      String welcome = "Hej med dig";
      outBuffer = ByteBuffer.allocate(500);

      byte[] outArr = welcome.getBytes();
      outBuffer.put(outArr);
    }


    public void setSelectionKey(SelectionKey sk){
      this.sk = sk;
      cw.addWriteInterest(sk);
    }
   
   
    public boolean hasData(){
      return (outBuffer.position() > 0);
    }

    public ByteBuffer getOutputBuffer(){
      outBuffer.flip();
      return outBuffer;
    }

    public void onWritePerformed(){
      outBuffer.compact();
    }

    public boolean isRequestingShutdown(){
      return false;
    }

    public void onShutdown(){
      System.out.println("[ConnectionTenant:onShutdown()]");
    }
   

}
18  Game Development / Networking & Multiplayer / Selector not blocking on select on: 2004-02-25 20:22:15
Hi, I finally got around to play with some nio code again, but of course things had to stop working before I could get anywhere  :-/  To make it easier to overlook i've put together some code containing of only the basic stuff, but where the problem also exists.

If I connect to my code using fx telnet everything works fine. If I then try to make a connection from macromedia flash and continue to start up the flash script (which means closing the connection and opening a new one fast) my selector suddenly starts to return immidiatly on select, returning 0 selectionkeys. Sometime this condition is even created the first time I connect from flash. My orriginal code connected to another server (and went bananas when the connections were dropped quick), but the behavior has been similar with this test code.

Once the selector has started returning immidiatly it will continue until a new connection is made, after when it will enter into normal blocking operation.  Another thing worth noting is that if I dont write out anything to the socket then its not possibel to create this behavior.

Hope someone here can help me figure it out, cause Im pretty empty for ideas atm =) Ill post the code in seperate posts to make it easier to overlook.
19  Game Development / Networking & Multiplayer / Re: Structure of a networking framework based on n on: 2004-01-28 11:44:01
Just a quick answer as Im on my way out the door. The multiple second query is already optimized (not by me =) but is simply dealing with a lot of data and table relations. The majority of the sql calls has very reasonable execution time, but what I tried to say was simply that since the application code will perform actions involving io then there would need to be a decopling in the application layer if the netcode just ran with one thread. My feeling right now is that its easier to simply place that decoupling at the selectionkey processing.

Anyway I didnt start this thread to discuss specific performance issues, I was just interested in hearing if there was some well known, good and elegant ways to structure nio code and work around the different bugs which I find is a bit of a problem keeping track of. Ie how other people have handeled the different mechanisms needed in a framework.
20  Game Development / Networking & Multiplayer / Re: Structure of a networking framework based on n on: 2004-01-28 10:44:30
Hi again. Sorry for the lack of replies, but ive been so busy with work that I havnt had time to play with java =)

Quote
Is there anything wrong with queuing events? What did you have in mind for this (i.e. you seem to dislike it, but I can't think what's wrong with that, so I'm wondering what you're thinking of that is different to what I'm thinking of


The reason Ive been a bit worried about queuing events/objects is that I was affraid it would introduce to much object creation in the basic operation of the netcode. After Ive had the chance to create a nio server it seems it was an unneeded concern, since nio does do a lot of the work as you said.

Another thing Im a bit concerned about is what the performance cost is for constantly changing the events you are registered for (and perform a wakeup to make the selector update it) plus the good description in SelectionKey.interestOps(int:ops)

Quote
This method may be invoked at any time. Whether or not it blocks, and for how long, is implementation-dependent.


Say we have a setup where one object contains the selector and has its own thread who perform select operations. The selected keys are then handed over to a pool from where 1-n workers pick them up to process.

Correct me if im wrong here, but when the selectionkey is put in the pool I would have to cancel the registered OP_READ and then reregister it after processing has been completed, to prevent that multiple threads get a reference to the selectionkey (by cancling i mean changing interestOps not canceling selectionKey).

Its not a problem to implement Im just a little annoyed with working with may/may not work documented features =)

Quote
Out of interest, what do you find "messy" about it? Also, what problems have you had with shutdown?


My problem with having seperate read/write selectors is mostly that I then spread out the code that can "trigger" the need to disconnect a client, so it takes extra code to handle those different scenarios. I cant really see advantages of splitting it up (which is probabbly because im new to this area =) so Im just going for the most simple design.

Quote
You shouldn't need to use wait/notify with NIO unless you really want to; I'm guessing you're thinking of using this to implement a multi-threaded queue (given your later comments), but you can do it without if you don't like them (which I don't )


Thats what Im going for in my rewrite yes, with multiple worker threads picking the up the SelectionKey's from a queue. Im not sure how you'll do without wait/notify to handle that transfer though  Huh

Quote
Are you sure you want worker threads? Since dumping the pooling, I've usually found performance more than adequate for hundreds of clients with just a single thread per selector


Nope Im not sure if its needed, but as I said there can be a fair load of users at the chatsite where this code if first intended to be put in use (where some user commands result in multiple-second sql queries so decoupling from any bottleneck in the system is needed, and it seems a better and better idea to do it in the networkcode =) My current plan is to try a rewrite with the structure describe in this reply, and then try out how it works.
21  Game Development / Networking & Multiplayer / Re: Structure of a networking framework based on n on: 2004-01-12 12:12:55
Ill try to explain my needs and goals a bit better. I intend to use the code/framework to replace my old-io network code in a bunch of existing projects (including some chat server applications that runs with loads of 1000-1500 users). Its defintly not high load applications but still enough that I have to think at bit about the performance.

The main reason that I have considered this approch is that I find the structure with a read and write selector somewhat messy and that it introduces some trouble with doing a gracefull shutdown of a client.

A single selector and a bunch of worker threads on a wait/notify is perhaps a better and simpler solution but it just involves a lot of queuing events to and from the selector thread.

Im defintly a noob on this area, so Im really just trying to find some best practice patterns for a semi-scaleable framework.
22  Game Development / Networking & Multiplayer / Structure of a networking framework based on nio on: 2004-01-12 10:55:51
Hi

As the subject suggest Im  looking at designing some reusable network code based on nio, and thought I would seek some input here on how to structure it.

My current plan is to have:

- A selector thread listening for new connections
- A simple load balancing system delegating the new connections to worker threads and adjusting the number of those threads.

- 1-n number of worker threads each having their own selector which they register the connections on

The plan is to always have the socketchannels registered for OP_READ and then register them for OP_WRITE whenever there is data or some other event that the worker threads will then query the ChannelSockets "manager object" for.

On of the big problems with this structure is of course if the data processing and handling of the incomming data takes a lot of time, but I plan on making decoupling heavy / time consuming tasks the responsibility of the application code.

So, is this structure totally messed up? Smiley Suggestions and comments on this and other possibel structures are very welcome.
Pages: [1]
 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (64 views)
2014-04-15 18:08:23

BurntPizza (62 views)
2014-04-15 03:46:01

UprightPath (75 views)
2014-04-14 17:39:50

UprightPath (58 views)
2014-04-14 17:35:47

Porlus (76 views)
2014-04-14 15:48:38

tom_mai78101 (101 views)
2014-04-10 04:04:31

BurntPizza (161 views)
2014-04-08 23:06:04

tom_mai78101 (256 views)
2014-04-05 13:34:39

trollwarrior1 (209 views)
2014-04-04 12:06:45

CJLetsGame (216 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!