我使用Trilead和Jsch作为Hg的SSH客户端,现在我正在尝试使用SSHJ,因为它似乎提供了更现代的关键支持。草绘的代码读作
SSHClient client = createClientAndAuthenticate();
Session session = client.startSession();
Command cmd = session.exec(command); // command usually is "hg -R /path/to/hg/repository serve --stdio"
startThreadToCopyInputStream(cmd.getOutputStream());
startThreadToCopyOutputStream(cmd.getInputStream());
startThreadToCopyOutputStream(cmd.getErrorStream());
cmd.join(); // here it hangs endlessly
startThreadToCopyInputStream
方法将本地Hg进程中的所有字节复制到cmd.getOutputStream()
,然后完成输入流。但与Trilead和JSch相比,cmd.getInputStream()
和cmd.getErrorStream()
仍然无休止地开放。
我现在将代码更改为:
SSHClient client = createClientAndAuthenticate();
Session session = client.startSession();
Command cmd = session.exec(command); // command usually is "hg -R /path/to/hg/repository serve --stdio"
startThreadToCopyInputStream(cmd.getOutputStream());
startThreadToCopyOutputStream(cmd.getInputStream());
startThreadToCopyOutputStream(cmd.getErrorStream());
waitUntilInputStreamIsClosed();
cmd.close();
这种方法在90%的情况下运行良好,但有时Hg抱怨服务器提前关闭了连接。我应该怎么知道何时能够调用cmd.close()
,因为服务器进程已经完成了?
答案 0 :(得分:0)
看起来这是SSHJ中的一个错误(请参阅ticket 143)。解决方法是不直接使用VirtualPathUtility.ToAbsolute($"~/App_Themes/Default/Icons/myimage.gif")
,而是:
cmd.getOutputStream()
在传递给OutputStream cmdOutputStream = new FilterOutputStream(cmd.getOutputStream()) {
@Override
public void close() throws IOException {
try {
super.close();
}
finally {
client.getTransport().write(new SSHPacket(Message.CHANNEL_EOF).putUInt32(session.getRecipient()));
}
}
};
之前。