J'étudie Websocket et ai fait un programme de chat avec websocket/json. Mais je suis bloqué au téléchargement de fichiers ATM. Tout conseil et réponse seraient reconnaissants.
Du côté serveur:
package websocket;
import Java.io.File;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.nio.ByteBuffer;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/receive/fileserver")
public class FileServer {
@OnOpen
public void open(Session session, EndpointConfig conf) {
System.out.println("chat ws server open");
}
@OnMessage
public void processUpload(ByteBuffer msg, boolean last, Session session) {
System.out.println("Binary message");
FileOutputStream fos = null;
File file = new File("D:/download/tmp.txt");
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte readdata = (byte) -999;
while(readdata!=-1) {
readdata=msg.get();
try {
fos.write(readdata);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@OnMessage
public void message(Session session, String msg) {
System.out.println("got msg: " + msg + msg.length());
}
@OnClose
public void close(Session session, CloseReason reason) {
System.out.println("socket closed: "+ reason.getReasonPhrase());
}
@OnError
public void error(Session session, Throwable t) {
t.printStackTrace();
}
}
Client:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Chat</title>
<script type="text/javascript" src="/MyHomePage/jquery-2.0.3.min.js"></script>
</head>
<body>
<h2>File Upload</h2>
Select file
<input type="file" id="filename" />
<br>
<input type="button" value="Connect" onclick="connectChatServer()" />
<br>
<input type="button" value="Upload" onclick="sendFile()" />
<script>
var ws;
function connectChatServer() {
ws = new WebSocket(
"ws://localhost:8080/MyHomePage/receive/fileserver");
ws.binaryType = "arraybuffer";
ws.onopen = function() {
alert("Connected.")
};
ws.onmessage = function(evt) {
alert(evt.msg);
};
ws.onclose = function() {
alert("Connection is closed...");
};
ws.onerror = function(e) {
alert(e.msg);
}
}
function sendFile() {
var file = document.getElementById('filename').files[0];
var reader = new FileReader();
var rawData = new ArrayBuffer();
reader.loadend = function() {
}
reader.onload = function(e) {
rawData = e.target.result;
ws.send(rawData);
alert("the File has been transferred.")
}
reader.readAsBinaryString(file);
}
</script>
</body>
</html>
le message de raison fermé côté serveur est comme ci-dessous
socket fermé: le message texte décodé était trop volumineux pour le tampon de sortie et le noeud final ne prend pas en charge les messages partiels
Q1: Il semble qu’il trouve une méthode de traitement de texte au lieu d’une méthode de traitement binaire en fonction de la raison fermée, comment puis-je résoudre ce problème?
Q2: Devrais-je changer le type de données en Blob pour transférer le fichier côté javascript? Alors comment?
extra Q: Quelqu'un peut-il créer un lien vers des exemples de source (s) de transfert de fichier Websocket (Java Websocket ou javascript soit/les deux)?
Merci d'avoir lu :)
Après quelques recherches et essais, j'ai découvert que 'reader.readAsBinaryString (file);' était une cause de la question 1. Le changer en 'reader.readAsArrayBuffer (file);' mon premier problème a été résolu.
De plus, depuis que websocket transfère automatiquement un fichier sous forme de plusieurs données partielles, j'ai changé de source comme ci-dessous. Cela marche! uniquement lorsque la taille du fichier n'est pas si grande. :/
Source côté serveur modifiée:
package websocket;
import Java.io.File;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.nio.ByteBuffer;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/receive/fileserver")
public class FileServer {
static File uploadedFile = null;
static String fileName = null;
static FileOutputStream fos = null;
final static String filePath="d:/download/";
@OnOpen
public void open(Session session, EndpointConfig conf) {
System.out.println("chat ws server open");
}
@OnMessage
public void processUpload(ByteBuffer msg, boolean last, Session session) {
System.out.println("Binary Data");
while(msg.hasRemaining()) {
try {
fos.write(msg.get());
} catch (IOException e) {
e.printStackTrace();
}
}
}
@OnMessage
public void message(Session session, String msg) {
System.out.println("got msg: " + msg);
if(!msg.equals("end")) {
fileName=msg.substring(msg.indexOf(':')+1);
uploadedFile = new File(filePath+fileName);
try {
fos = new FileOutputStream(uploadedFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@OnClose
public void close(Session session, CloseReason reason) {
System.out.println("socket closed: "+ reason.getReasonPhrase());
}
@OnError
public void error(Session session, Throwable t) {
t.printStackTrace();
}
}
Côté navigateur (client):
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Chat</title>
<script type="text/javascript" src="/MyHomePage/jquery-2.0.3.min.js"></script>
</head>
<body>
<h2>File Upload</h2>
Select file
<input type="file" id="filename" />
<br>
<input type="button" value="Connect" onclick="connectChatServer()" />
<br>
<input type="button" value="Upload" onclick="sendFile()" />
<script>
var ws;
function connectChatServer() {
ws = new WebSocket(
"ws://localhost:8080/MyHomePage/receive/fileserver");
ws.binaryType = "arraybuffer";
ws.onopen = function() {
alert("Connected.")
};
ws.onmessage = function(evt) {
alert(evt.msg);
};
ws.onclose = function() {
alert("Connection is closed...");
};
ws.onerror = function(e) {
alert(e.msg);
}
}
function sendFile() {
var file = document.getElementById('filename').files[0];
ws.send('filename:'+file.name);
var reader = new FileReader();
var rawData = new ArrayBuffer();
//alert(file.name);
reader.loadend = function() {
}
reader.onload = function(e) {
rawData = e.target.result;
ws.send(rawData);
alert("the File has been transferred.")
ws.send('end');
}
reader.readAsArrayBuffer(file);
}
</script>
</body>
</html>
Je n'arrive toujours pas à comprendre comment transférer un fichier de plus grande taille . (Je soupçonne un délai d'attente automatique et/ou la taille de la mémoire tampon). Un conseil plz?
Dans mon cas, il fonctionne pour télécharger de gros fichiers sans plantage du navigateur ou fermeture du socket.
Veuillez suivre les étapes suivantes pour le faire fonctionner.
Vous pouvez utiliser cet article pour vous faire une idée du flux de travail complet, de son utilisation avec Websocket.