首先,我不是开发人员(我已经编程了2周),所以请随时告诉我,我完全误解了这个问题(同样,我为自己写了所有这些,所以我“我相信它超级不酷”:)。我想学习并把它弄好,所以我很想听听建议或完成重写。
我想以非阻塞模式连接到套接字(我是客户端,而不是服务器)。我主要需要阅读它,但有时我也需要写它。程序如下:
我的解决方案如下(我用Java编写它,因为我读过它是一种快速而优秀的编程语言,但如果需要,我很乐意改变......但希望不需要!):< / p>
public class SocketClient {
public static void main(String[] args) {
new Feed().init();
}
private boolean isSocketConnected() {
return socket != null && socket.isConnected();
}
public void init() {
try {
if (isSocketConnected()) {
// What here if I'm in non-blocking mode?
// Would be good to know if the "close API" request succeeded
// otherwise next time I won't be able to connect to their socket...
sendCloseRequestToApi();
socket.close();
}
run();
} catch (Exception e) {
if (isSocketConnected()) {
// Same question as above...
sendCloseRequestsToApi();
socket.close();
}
}
}
public void run() throws IOException {
System.out.println("Starting connection in blocking mode...");
SocketChannel channel = SocketChannel.open();
socket = channel.socket();
socket.setReceiveBufferSize(RECEIVE_BUFFER_SIZE);
socket.setSendBufferSize(SEND_BUFFER_SIZE);
channel.connect(new InetSocketAddress("127.0.0.1", 2121));
channel.finishConnect();
System.out.println("Finished connecting in blocking mode");
// Writes to the socket (user and password)
initialiseTheApi();
System.out.println("Sent API requests in blocking mode");
System.out.println("Now we should probably go non-blocking (I guess)");
channel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ);
selector = Selector.open();
channel.configureBlocking(false);
System.out.println("Selector created and switched to non-blocking mode...");
long timeWithoutData = 0;
boolean needsReconnection = false;
while (!needsReconnection) {
selector.select();
Iterator < SelectionKey > keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (!key.isValid()) {
continue;
}
if (key.isWritable()) {
// Execute write...
// What if I need to know the result to the write operation?
}
if (key.isReadable()) {
int dataRead = readDataFromSocket(buffer);
buffer.flip();
if (buffer.remaining() > 0) {
// I process the data read here,
// but sometimes the data sent is
// "reconnect to API". So I need to close
// the connection and start again.
// How can I do that if I'm in non-blocking mode?
// I mean, I need to make sure when I send that request
// (for reconnection).
// I need to know that the request got to the server and
// was processed OK before moving on and
// reading/writing again...
}
if (dataRead > -1) {
timeWithoutData = 0;
} else {
if (timeWithoutData > 0) {
long diffInMillis = System.currentTimeMillis() - timeWithoutData;
if (diffInMillis > 2000) {
System.out.println("Timeout or something? I need to reconnect I think");
needsReconnection = true;
}
} else {
timeWithoutData = System.currentTimeMillis();
}
}
// Do I even need this? Already did it before, right?
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
}
if (needsReconnection) {
// We need full reconnection, go back up and reconnect
init();
}
}
}
为方便起见,我删除了导入和其他无用的方法,并保持帖子简短。
正如您在代码中的问题中看到的那样(加上一些已添加的代码):
我已经看到这可以使用Netty或其他东西进行简化,但我已经臃肿了这么多东西! :(
我希望我的问题很明确。请告诉我。
非常感谢。
答案 0 :(得分:0)
我试图做一些没有意义的事情。在我的情况下,我绝对可以使用阻塞连接,我只是不知道:/。互联网有时是一个糟糕的信息来源!我一直在这里读,不要使用阻塞连接:D。但现在它完全适合不同的场景。 - 将