2017-10-06 13 views
0

J'ai ce petit morceau de code dans mon servlet java, qui utilise des canaux NIO pour diffuser de la vidéo:Java HTTPServlet OutputStream ne pas transférer toutes les données

int bufferSize = 32 * 1024; 
os = response.getOutputStream(); 
in = Channels.newChannel(contentStream); 
out = Channels.newChannel(os); 
ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize); 
while (in.read(buffer) > -1 || buffer.position() > 0) { 
       endByte += 1; 
       buffer.flip(); 
       out.write(buffer); 
       buffer.compact(); 
       if(endByte == 1830) 
        break; 
} 

Si une plage d'octets I est demandé chercherai à l'aide du tampon et puis commencez à diffuser à partir de l'octet de démarrage demandé. Telle est la réponse du navigateur Chrome

GET/Request: 
Accept:*/* 
Accept-Encoding:identity;q=1, *;q=0 
Accept-Language:en-US,en;q=0.8 
Connection:keep-alive 
Range:bytes=0- 

Response: 
Accept-Ranges:bytes 
Content-Disposition:inline; filename="SampleVideo.mp4" 
Content-Length:1055736 
Content-Type:video/mp4 

Le code java ci-dessus est en cours d'exécution, mais au bout du navigateur seulement 64Ko montre que transféré avant une autre demande est envoyée pour les octets restants:

GET/Request: 
Accept:*/* 
Accept-Encoding:identity;q=1, *;q=0 
Accept-Language:en-US,en;q=0.8 
Connection:keep-alive 
Range:bytes=1048576- 

Response: 
Accept-Ranges:bytes 
Content-Disposition:inline; filename="SampleVideo.mp4" 
Content-Length:7160 
Content-Range:bytes 1048576-1055735/1055736 
Content-Type:video/mp4 

Et dans ce cas, les données renvoyées (7 Ko) correspondent bien au contenu de Content-Length. La lecture de la vidéo échoue et le lecteur affiche une erreur. Cependant, si je ne renvoie pas un en-tête ACCEPT-RANGES, la vidéo fonctionne bien, mais ne me permet pas de chercher une autre partie de la vidéo.

Cela ne semble être un problème pour les petits fichiers < 10 Mo une fois qu'il est autour de la plage 30 Mo il semble bien fonctionner même si les montants retournés ne correspondent pas à la valeur de la réponse de longueur de contenu. Il va revenir autour de 35 Mo sur la première réponse parfois pour les très grandes vidéos < 500MB. Sur Firefox, le navigateur semble faire beaucoup de petites requêtes GET beaucoup plus que le navigateur Chrome. Je ne sais pas pourquoi cela se passe comme ça ou comment je peux vérifier combien a été/sera effectivement envoyé

Répondre

0

read() ne lit pas un octet à la fois. Donc endByte += 1; est un non-sens. Le montant qu'il lit est disponible en tant que valeur de retour. Il devrait être endByte += count;count était la valeur retournée par read, si elle était positive, sinon zéro.

+0

Je sais que c'est la quantité maximale de fois que le tampon est lu, ce qui serait la limite supérieure de 1830 * 32 * 1024 octets au total. Ma question est pourquoi le navigateur n'obtient-il pas ce qui a été transmis, il envoie immédiatement une autre demande de GET sans attendre. –