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

标签 java sockets client-server observer-pattern

每个客户端一旦连接到服务器就被注册为观察者。 当任何客户端进行更改时,将通知其他客户端。

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

我可以像 Socket[] 一样存储所有连接并每秒检查它们的 InputStream 吗?

最佳答案

我不知道我是否答对了你的问题......但我会试一试。

问题似乎是,您有 1 个 ServerSocket 和多个套接字(每个客户端一个),现在您想要收到有关这些套接字上的 Activity 的通知/通知。所以您打算遍历套接字列表?

关键字是非阻塞 I/O。搜索关键字“selector”或“multiplexing”。 我将尝试举一个简单的例子。

我构建了一个非常小的示例。但这是一个开始。这是全部

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 连接到它,并从那里发送消息。只有一个线程,有任意多的客户端连接....

我使用了这个资源/示例

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

关于java - 在套接字客户端服务器上实现观察者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23855604/

相关文章:

Java - JNDI/Active Directory/Kerberos/WebLogic Server - 密码配置

java - Android 应用程序 - 开发 Wifi 文件传输

c - FTP服务器返回码: How to connect with a host using my own TCP server and Linux built-in client

Java - 客户端/服务器游戏服务器协议(protocol)。如何传输命令?

java - 通过将类骨架从服务器传输到客户端来创建服务器端类的客户端对象

java - ExecutorService 令人惊讶的性能盈亏平衡点——经验法则?

具有模式属性的 Java Hibernate Generic DAO

python - 服务器连接问题 : "socket.gaierror: [Errno 11004] getaddrinfo failed"

c++ - asio 的多套接字架构

c - 多个节点在 open62541 中读取来自客户端的单个请求