使⽤Html5的WebSocket在浏览器上传⽂件,⽀持多⽂件和⼤⽂
件.
使⽤websocket上传⽂件的简单例⼦:
上篇⽂章没有解决的问题就是⼤⽂件的上传问题, ⽽且多⽂件上传问题也未协调. 所以这篇⽂章就是解决这两个问题的.
如果将⼀个⼤⽂件直接读⼊内存再发送的话, 内存会吃不消, 所以我们把⼤⽂件分块传输.  Html5的Fileread⽅法提供了读取⽂件部分内容Blob 的⽅法.
为了保证后台接收到的分块数据的顺序不会乱掉, 我们需要后台确定写⼊分块数据后再发送下⼀块数据.
在Html端:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Chat Client</title>
<meta charset="utf-8"/>
<script type="text/javascript" src="jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="jquery.json-2.3.min.js"></script>
<script type="text/javascript">
$().ready(
function() {
// Check for the various File API support.
              if (window.File && window.FileReader && window.FileList
&& window.Blob) {
// Great success! All the File APIs are supported.
} else {
alert('The File APIs are not fully supported in this browser.');
}
});
//在消息框中打印内容
function log(text) {
$("#log").append(text+"\n");
}
//全局的websocket变量
var ws;
var paragraph = 10485760;
var fileList ;
var file;
var startSize,endSize = 0;
var i = 0; j = 0;
//连接服务器
$(function() {
$("#connect").click(function() {
ws = new WebSocket($("#uri").val());
//连接成功建⽴后响应
log("成功连接到" + $("#uri").val());
}
//收到服务器消息后响应
log("服务器说" + e.data + (e.data=="ok"));
if(e.data == "ok"){
if(endSize < file.size){
startSize = endSize;
endSize += paragraph ;
if (file.webkitSlice) {
var blob = file.webkitSlice(startSize, endSize);
} else if (Slice) {
var blob = Slice(startSize, endSize);
}
var reader = new FileReader();
var ArrayBuffer = sult;
log("发送⽂件第" + (i++) + "部分");
ws.send(ArrayBuffer);
}
}
else{
startSize = endSize = 0;
i = 0;
log("发送" + file.name +"完毕");
file = fileList[j++];
if(file.name){
ws.send(file.name);
}
log("发送⽂件完毕");
}
}
//连接关闭后响应
log("关闭连接");
ws = null;
}
return false;
getsavefilename}
});
});
$(function() {
$("#sendFileForm").click(function() {
fileList = ElementById("file").files;
file = fileList[0];
ws.send(file.name);
})
});
$(function() {
$("#reset").click(function() {
$("#log").empty();
return false;
});
});
</script>
</head>
<body>
<span>Html5功能测试</span>
<span id="progress">0</span><br>
<input type="text" id="uri" value="ws://localhost:8887"
><input type="button" id="connect"
value="Connect"><input type="button" id="disconnect"
value="Disconnect" disabled="disabled">
<form >
<input id="file" type="file" multiple />
<input type="button" id="sendFileForm" value="测试"/>
<input type="button" id="reset" value="清空消息框"/>
</form>
<form>
<textarea id="log" rows="30" cols="100"
></textarea>
</form>
</body>
</html>
这⾥设置了⽂件⼤于paragraph (10M)时就会分块发送⽂件.
服务器端:
/**
* 处理字符串消息
*/
public void onMessage( WebSocket conn, String message ) {
System.out.println("⽂件名" + message);
//将⽂件名写⼊连接对象中,(需要⼿动修改webSocket类)
conn.setFileName(message);
try {
conn.send("ok");
} catch (NotYetConnectedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 处理⼆进制消息
*/
public void onMessage(WebSocket conn, byte[] message) {
System.out.println("收到⼆进制流:");
//将⼆进制流保存为⽂件, ⽂件名从连接对象中取出
saveFileFromBytes(message, "src/" + FileName());
//告诉前台可以继续发送了.
try {
conn.send("ok");
} catch (NotYetConnectedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
/
/ TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 将⼆进制byte[]数组写⼊⽂件中
* @param b byte[]数组
* @param outputFile ⽂件位置
* @return成功: true 失败: false
*/
public static boolean saveFileFromBytes(byte[] b, String outputFile)
{
FileOutputStream fstream = null;
File file = null;
try
{
file = new File(outputFile);
fstream = new FileOutputStream(file, true);
fstream.write(b);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
finally
{
if (fstream != null)
{
try
{
fstream.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
return true;
}
好了, 顺序发送保证了后台写⼊的数据也是顺序的, ⽂件就不会出错了! 搞定!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。