在套接字客户端服务器上实现观察者模式

时间:2014-05-25 13:07:27

标签: java sockets client-server observer-pattern

每个客户端连接到服务器后都会注册为观察者。 当任何客户端进行更改时,将通知另一个客户端。

我的问题是如何连接套接字?

我可以存储Socket[]等所有连接,并每秒检查一次InputStream吗?

1 个答案:

答案 0 :(得分:0)

我不知道我的问题是否正确......但我会试一试。

问题是,您有1个ServerSocket和多个套接字(每个客户端一个),现在您希望得到有关这些套接字的活动的通知/通知。所以你计划迭代插座列表?

关键字是非阻塞I / O.搜索关键字"选择器"或"多路复用"。 我试着举一个简单的例子。

我构建了一个非常小的例子。但这是一个开始。这是整个

package server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Set;

public class Server {

public Server() throws IOException{
    Selector selector = SelectorProvider.provider().openSelector();
    ServerSocketChannel ssc = ServerSocketChannel.open().bind(new InetSocketAddress(9000));
    ssc.configureBlocking(false);       
    ssc.register(selector, 
              SelectionKey.OP_ACCEPT);  


    while(true) {

      int readyChannels = selector.select();

      if(readyChannels == 0) continue;


      Set<SelectionKey> selectedKeys = selector.selectedKeys();

      Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

      while(keyIterator.hasNext()) {

        SelectionKey key = keyIterator.next();

        if(key.isAcceptable()) {
           System.out.println("acceptable");
           SocketChannel socketChan =  ((ServerSocketChannel)key.channel()).accept();
           socketChan.configureBlocking(false);
            socketChan.register(selector, SelectionKey.OP_READ);

        } else if (key.isConnectable()) {
            // a connection was established with a remote server.

        } else if (key.isReadable()) {
            System.out.println("Processing reading...");

            ByteBuffer buf = ByteBuffer.allocate(1024);
            int readedBytes = ((SocketChannel)key.channel()).read(buf);
            System.out.println("Readed: " + readedBytes);
            buf.flip();

            for(byte b : buf.array()) {
                System.out.print((char) b);
            }

        } else if (key.isWritable()) {
            // a channel is ready for writing
        }

        keyIterator.remove();
      }
    }
}

public static void main(String[] args) throws IOException {
    Server server = new Server();

}

}

我可以运行它,并通过端口9000上的netcat连接到它,并从那里发送消息。只需一个线程,拥有尽可能多的客户端连接....

我使用了这个ressources / examples

http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.htmlhttp://docs.oracle.com/javase/7/docs/technotes/guides/io/example/index.html