当前位置: 代码迷 >> Android >> Android NanoHTTPD流内容持久连接
  详细解决方案

Android NanoHTTPD流内容持久连接

热度:166   发布时间:2023-08-04 11:50:54.0

我一直在我们的一个应用程序中使用NanoHTTPD来提供内容,包括从本地SDCard到Webview的音频和视频。 内容范围和内容长度标头以及HTTP状态已正确配置。 现在,我们有一个用例,我们想通过NanoHTTPD在服务器上提供内容。

NanoHTTPD方法的问题在于它读取Webview要求的完整内容。 如果是本地文件,它仍然可以,但是您不能等待它从服务器中获取大量内容并刷新输出流。

我正在寻找一种方法,可以打开连接并继续提供一部分请求的数据。 就像在请求中获取带有范围标头的内容时一样。 连接保持打开状态,只要有足够的缓冲区,视频播放器就会立即播放。

请帮忙。

我通过使用HTTP客户端解决了这个问题。 我在本地主机上使用唯一端口注册了一种模式,并通过添加适当的标头,状态和内容长度来处理大型媒体的响应。 这里要做的三件事:

1)将标头从HTTP响应复制到本地响应
2)设置响应代码。 全部内容(200)或部分内容(206)
3)创建一个新的InputStreamEntity并将其添加到响应中

@Override
    public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
        String range = null;
        //Check if there's range in request header 
        Header rangeHeader = request.getFirstHeader("range");

        if (rangeHeader != null) {
            range = rangeHeader.getValue();
        }

        URL url = new URL(mediaURL);
        URLConnection urlConn = url.openConnection();

        if (!(urlConn instanceof HttpURLConnection)) {
            throw new IOException("URL is not an Http URL");
        }
        HttpURLConnection httpConn = (HttpURLConnection) urlConn;
        httpConn.setRequestMethod("GET");

        //If range is present, direct HTTPConnection to fetch data for that range only    
        if(range!=null){
            httpConn.setRequestProperty("Range",range);
        }
        //Add any custom header to request that you want and then connect.
        httpConn.connect();

        int statusCode = httpConn.getResponseCode();

        //Copy all headers with valid key to response. Exclude content-length as that's something response gets from the entity. 
        Map<String, List<String>> headersMap =  httpConn.getHeaderFields();
        for (Map.Entry<String, List<String>> entry : headersMap.entrySet())
        {
            if(entry.getKey() != null && !entry.getKey().equalsIgnoreCase("content-length")) {
                for (int i = 0; i < entry.getValue().size(); i++) {
                    response.setHeader(entry.getKey(), entry.getValue().get(i));
                }
            }
        }

        //Important to set correct status code
        response.setStatusCode(statusCode);

        //Pass the InputStream to response and that's it.
        InputStreamEntity entity = new InputStreamEntity(httpConn.getInputStream(), httpConn.getContentLength());
        entity.setContentType(httpConn.getContentType());
        response.setEntity(entity);

    }
  相关解决方案