与插座保持恒定连接

时间:2012-07-08 15:58:08

标签: java sockets

我正在尝试为多线程服务器程序保持连接打开。当我点击按钮时,我希望它向所有连接的客户端发送测试消息。

public void run() {
    try {
        Scanner in = new Scanner(socket.getInputStream());
        PrintWriter out = new PrintWriter(socket.getOutputStream());
        readUpdate(out, in);
        while(true){sendUpdate(out);}
    } catch (Exception e) {
        e.printStackTrace();
    }
}

使用多CPU的方式。

这是我的sendUpdate方法。

private void sendUpdate(final PrintWriter out) {
    new Thread(new Runnable() {

        public void run() {
            if(Server.send) {
                try {
                    if (Server.command != "idle") {
                        System.out.println("Sending");
                        out.println("!msg@" + Server.command);
                        out.flush();
                        Server.send = false;
                        Thread.sleep(100);
                    }
                } catch (Exception ex) {
                }
            }
        }
    }).start();
}

如果有人可以帮我保持连接打开,并准备发送数据,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

如果您的服务器可以启动消息,您的客户端也可以启动消息,您可能需要单独的线程读写。一个线程对请求 - 响应样式通信有意义,您可以阻止下一个客户端请求,执行一些服务器端处理,响应客户端,然后再次阻止。

但是如果您需要在两个不同的条件下阻止(从客户端接收消息并单击服务器上的按钮),那么您应该有两个单独的线程。否则,您将发现自己需要反复唤醒线程以检查其中任何一个条件是否为真。

因此,创建两个主题,并为Scanner提供一个readUpdate逻辑,另一个为PrintWriter。这就是输出处理程序的样子:

public class WriteHandler implements Runnable {
    private final PrintWriter out;
    private final BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();

    //initialize the above in a constructor;

    public void run() {
       while(true) {
          String nextMessageToWrite = messageQueue.poll();
          out.println(nextMessageToWrite);
       }
    }

    public void send(String message) {
        messageQueue.add(message);
    }
}

这使用blocking queue,这是一种比check-sleep循环更好的并发机制。然后当点击按钮时,你可以这样:

public void actionPerformed() {
    for ( WriteHandler handler : handlers ) {
        handler.send("PING!");
    }
}