我正在尝试使用 Java 中的套接字将 RDF/XML 从客户端发送到服务器。当我发送信息时,服务器程序会挂起并且不会接收信息,除非我关闭客户端的 Socket 或 OutputStream。即使我刷新客户端上的 OutputStream,服务器也不会收到数据,除非我关闭套接字/流。我想在不关闭套接字的情况下发送信息。以下是客户端的一些示例代码(使用 Sesame):
import java.io.*;
import java.net.*;
import org.openrdf.rio.*;
import org.openrdf.rio.helpers.*;
import org.openrdf.model.URI;
import org.openrdf.model.Model;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.Statement;
import org.openrdf.model.impl.*;
import org.openrdf.model.vocabulary.*;
public class SimpleRDFClient {
private Socket socket = null;
public static void main(String[] args) {
new SimpleRDFClient(args[0],Integer.parseInt(args[1])).launch();
}
public SimpleRDFClient(String host, int port) {
try {
socket = new Socket(host,port);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void launch() {
try {
OutputStream out = socket.getOutputStream();
BufferedOutputStream dos = new BufferedOutputStream(out);
Model model = new LinkedHashModel();
ValueFactory factory = new ValueFactoryImpl();
URI clive = factory.createURI("http://www.site.org/cliveAnderson");
Statement st = factory.createStatement(clive, RDF.TYPE, FOAF.PERSON);
model.add(st);
Rio.write(model,dos,RDFFormat.RDFXML);
dos.flush();
//Some other stuff
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
和服务器处理程序:
import java.io.*;
import java.net.*;
import org.openrdf.rio.*;
import org.openrdf.rio.helpers.*;
import org.openrdf.model.*;
import org.openrdf.model.impl.*;
public class SimpleRDFSHandler implements Handler {
public void handleConnection(Socket socket) {
Model model = null;
try {
InputStream in = socket.getInputStream();
model = Rio.parse(in,"www.blah.com",RDFFormat.RDFXML);
for (Statement st: model) {
System.out.println(st);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
问题似乎来自 Rio.parse() 方法挂起(我认为是因为它不知道输入何时结束)。当我以类似的方式使用 Jena api 时,即使用 Model.write(outputstream,format) 和 Model.read(inputstream,format) 而不是 Rio,我遇到了类似的问题。我已经查看了源代码和 javadoc 很长时间了,但无法解决问题。我想这一定是我误解的简单的事情。有什么想法吗?
最佳答案
我认为这绝不是 Jena/Sesame 特定的问题,而是围绕套接字使用的 Java 问题。您实际上是否有不想关闭套接字的实际原因?
我不明白为什么这会是明智的,除非您想连续发布数据并在服务器端收到数据时对其进行处理?如果是这种情况,Jena 和 Sesame 都有 API,专门允许您控制解析数据时发生的情况,这样您就不会依赖于在处理数据之前完成的读取调用。
为什么要使用套接字,Sesame 和 Jena 都具有全面的 HTTP 集成,这比滚动您自己的基于套接字的服务器和客户端更容易使用和部署。
丑陋的 Hacky 解决方案
如果您确实必须这样做,那么有一个解决方法,但它有点可怕和脆弱,我强烈建议您不要这样做。
在写入数据后,在客户端写入指示流结束的字节序列。在服务器端,使用自定义的 InputStream 实现包装套接字流,该实现可识别该序列并在看到该序列时停止返回数据。这应该允许期望流完成的 Jena/Sesame 代码正常运行。
需要仔细选择字节序列,使其不会自然地出现在数据中。
说实话,这是一个糟糕的想法,如果您的目标是不断发布数据,这并不能真正解决您的问题,因为除非您将服务器端套接字处理代码放在while (true)
循环这可能是另一个坏主意。
关于java - 使用 Sesame 或 Apache Jena 通过套接字发送 RDF/XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17577398/