我有一个Android应用程序连接到服务器并连续发送一些信号数据(使用HttpURLConnection)。在服务器上,脚本(shell或python,不完全知道,它不是我的部分)当前处理此流,并且每个incomming数据包都设置curl请求以将此包发布到servlet(在Jetty 8 web中运行)容器)。这只是一个临时解决方案,因为我不知道如何直接连接数据并将数据流传输到servlet。根据要求,数据传输应使用HTTP协议,以免被任何防火墙阻止。
那么,是否可以初始连接到servlet,然后长时间(例如几分钟或几小时)流式传输数据?我想知道我没有找到类似的问题/解决方案。我的意思是这不是一个特殊的场景。这与将大文件上传到servlet的操作相同吗?
servlet实际上是这样的:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
System.out.println("StreamingServlet#doPost(): IN");
BufferedReader reader = request.getReader();
String data = "";
while ((data = reader.readLine()) != null)
{
System.out.println("Data: " + data);
}
reader.close();
System.out.println("StreamingServlet#doPost(): OUT");
}
Android应用程序有3个方法使用HttpURLConnection:
private Boolean connect(URL URLdest)
{
try
{
connection = (HttpURLConnection) URLdest.openConnection();
connection.setDoOutput(true);
connection.setChunkedStreamingMode(0);
oSWout = new OutputStreamWriter(connection.getOutputStream());
}
catch (IOException e)
{
return false;
}
return true;
}
public void send(String packet)
{
try
{
// TODO clOSWout.write and clOSWout.flush block may freeze if connection is lost. Somehow no exception is thrown and thread hangs instead.
// It only occurs if the Server breaks the connection
oSWout.write(packet);
oSWout.flush();
}
catch (IOException e)
{
...
}
}
public void stopConnection()
{
try
{
oSWout.close();
connection.disconnect();
}
catch (IOException e)
{
...
}
}
我最终期望的是,当连接到servlet时,它打印“StreamingServlet#doPost():IN”,然后,对于每个incomming数据包,它应该打印数据字符串,当关闭连接时,它应该打印“StreamingServlet #doPost():OUT”,最后从方法返回。
但我想我错过了一些东西,这在Java EE中以另一种方式完成。我不知道。
答案 0 :(得分:2)
最后,我自己解决了这个问题:
使用BufferedReader,收集(缓冲)所有数据包,并在连接关闭时作为一个包装进行读取和打印。所以我不得不使用ServletInputStream [由HttpServletRequest#getInputStream()获取]并使用read()方法将数据包读入字节数组。现在一切都按照我的预期运作。
但我仍然想知道,如果使用阻塞操作或多或少的典型场景,因此在doPost()方法中保持很长时间(比如几分钟或几小时),或者如果服务器以某种方式预期响应更短的时间。