私はwebsocketを勉強していて、websocket/jsonとチャットプログラムを実行しました。しかし、私はファイルアップロードATMで立ち往生しています。どんなアドバイスと答えもありがたいです。
サーバー側:
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();
}
}
クライアント:
<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>
サーバー側のクローズ理由メッセージは以下のとおりです
ソケットが閉じています:デコードされたテキストメッセージが出力バッファに対して大きすぎ、エンドポイントは部分的なメッセージをサポートしていません
Q1:クローズドな理由により、バイナリ処理方式ではなくテキスト処理方式を探しているようですが、どうすれば修正できますか?
Q2:JavaScript側でファイルを転送するには、データ型をBlobに変更する必要がありますか?では、どうやって?
追加のQ:誰かがwebsocketファイル転送のサンプルソース(Java websocketまたはjavascriptのいずれか/両方)をリンクできますか?
読んでくれてありがとう :)
いくつかの調査と試行の結果、「reader.readAsBinaryString(file);」であることがわかりました。質問1の原因でした。「reader.readAsArrayBuffer(file);」に変更します。私の最初の問題は解決されました。
また、websocketはファイルを複数の部分データとして自動的に転送するため、ソースを以下のように変更しました。 これは機能します!ファイルサイズがそれほど大きくない場合のみ。:/
サーバー側のソースを変更しました:
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();
}
}
ブラウザ(クライアント)側:
<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>
それでも私は理解できませんより大きなサイズのファイルを転送する方法。 (自動タイムアウトやバッファサイズが疑われます)。何かアドバイスplz?
私の場合、ブラウザがクラッシュしたりソケットが閉じたりすることなく、大きなファイルをアップロードすることができます。
次の手順に従って作業してください。
これを介して article 完全なワークフロー、Websocketでの動作についてのアイデアを得ることができます。