使用Html5的WebSocket在瀏覽器上傳文件


文件上傳的步驟: 打開websocket--連接websocket服務器--在瀏覽器里選擇文件--將文件讀入到內存中(以arraybuffer的形式)--在socket里發送文件--完畢!

 

服務器端:

先配置好websocket的服務器, 這里用一個java的開源websocket服務器: Java-WebSocket  

根據該項目的快速教程可以建立一個websocket服務器, 就是里面的一個ChatServer.java文件. 一個聊天室服務器.

 

客戶端(html):

1.建立連接

ws = new WebSocket($("#uri").val());
//連接成功建立后響應
ws.onopen = function() {
}
//收到服務器消息后響應
ws.onmessage = function(e) {
}
//連接關閉后響應
ws.onclose = function() {
ws = null;
}

2.讀取並發送文件

var inputElement = document.getElementById("file");
var file = inputElement.files;
var reader = new FileReader();
//以二進制形式讀取文件
reader.readAsArrayBuffer(file);
//文件讀取完畢后該函數響應
reader.onload = function loaded(evt) {
var binaryString = evt.target.result;
//發送文件
ws.send(binaryString);
}

3. 服務端響應:

public void onMessage(WebSocket conn, byte[] message) {
//saveFileFromBytes
System.out.println("收到2進制流");
}

在服務端響應並保存文件, 文件傳送完畢!

未完善的地方:

1. 多個文件讀取, file標簽中加入"multiple"屬性可以選擇多個文件.

2. FileRead是將文件讀入到內存的, 文件太大的話需要分段讀取.

要注意的地方: 

1. 讀取文件時要用使用"readAsArrayBuffer"方法, 更多FileRead的用法參見 w3c的file API

2. 如果是用Chrome的話,必須把網頁放在服務器上或插件里,file協議下會失敗。FileRead的onload函數不會響應!

參考資料:

w3c的file API

用JavaScript讀取和保存文件

FileReader詳解與實例---讀取並顯示圖像文件


完整代碼:

websocket.html(有用到Jquery):

<!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" >
//判讀瀏覽器是否支持websocket
$().ready(function() {
if ( !window.WebSocket ) {
alert(
"童鞋, 你的瀏覽器不支持該功能啊");
}

});

//在消息框中打印內容
function log(text) {
$(
"#log").append(text+"\n");
}

//全局的websocket變量
var ws;

//創建連接
$(function() {
$(
"#uriForm").submit(function() {
log(
"准備連接到" + $("#uri").val());

ws
= new WebSocket($("#uri").val());
//連接成功建立后響應
ws.onopen = function() {
log(
"成功連接到" + $("#uri").val());
}
//收到服務器消息后響應
ws.onmessage = function(e) {
log(
"收到服務器消息:" + e.data + "'\n");
}
//連接關閉后響應
ws.onclose = function() {
log(
"關閉連接");
$(
"#disconnect").attr({"disabled":"disabled"});
$(
"#uri").removeAttr("disabled");
$(
"#connect").removeAttr("disabled");
ws
= null;
}
$(
"#uri").attr({"disabled":"disabled"});
$(
"#connect").attr({"disabled":"disabled"});
$(
"#disconnect").removeAttr("disabled");
return false;
});
});

//發送字符串消息
$(function() {
$(
"#sendForm").submit(function() {
if (ws) {
var textField = $("#textField");
ws.send(textField.val());
log(
"我說:" + textField.val());
textField.val(
"");
textField.focus();
}
return false;
});
});

//發送arraybuffer(二進制文件)
$(function() {
$(
"#sendFileForm").submit(function() {
var inputElement = document.getElementById("file");
var fileList = inputElement.files;

for ( var i = 0; i < fileList.length; i++) {
console.log(fileList[i]);
log(fileList[i].name);
//發送文件名
ws.send(fileList[i].name);
// reader.readAsBinaryString(fileList[i]);
//讀取文件  
       var reader = new FileReader();
            reader.readAsArrayBuffer(fileList[i]);
// reader.readAsText(fileList[i]);
//文件讀取完畢后該函數響應
reader.onload = function loaded(evt) {
var binaryString = evt.target.result;
// Handle UTF-16 file dump
log("\n開始發送文件");
ws.send(binaryString);
}
}
return false;
});
});

$(
function() {
$(
"#disconnect").click(function() {
if (ws) {
$(
"#log").empty();
ws.close();
ws
= null;
}
return false;
});
});

$(
function() {
$(
"#reset").click(function() {
$(
"#log").empty();
return false;
});
});


</script>
</head>
<body>
<form id="uriForm">
<input type="text" id="uri" value="ws://localhost:8887"
style
="width: 200px;"> <input type="submit" id="connect"
value
="Connect"><input type="button" id="disconnect"
value
="Disconnect" disabled="disabled">
</form>
<br>

<form id="sendFileForm">
<input id="file" type="file" multiple />
<input type="submit" value="Send" />
<input type="button" id="reset" value="清空消息框"/>
</form>
<br>
<form id="sendForm">
<input type="text" id="textField" value="" style="width: 200px;">
<input type="submit" value="Send">
</form>
<br>
<form>
<textarea id="log" rows="30" cols="100"
style
="font-family: monospace; color: red;"></textarea>
</form>
<br>
</body>
</html>


ChatServer.java(需要導入WebSocket.jar):

package jyu.webserver;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketServer;
import org.java_websocket.handshake.ClientHandshake;

/**
* A simple WebSocketServer implementation. Keeps track of a "chatroom".
*/
public class ChatServer extends WebSocketServer {
private String fileName = null;

public ChatServer( int port ) throws UnknownHostException {
super( new InetSocketAddress( InetAddress.getByName( "localhost" ), port ) );
}

public ChatServer( InetSocketAddress address ) {
super( address );
}
public ChatServer( String address ,int port) throws UnknownHostException {
super( new InetSocketAddress( InetAddress.getByName( address ), port ) );
}

@Override
public void onOpen( WebSocket conn, ClientHandshake handshake ) {
try {
this.sendToAll( conn + " entered the room!" );
} catch ( InterruptedException ex ) {
ex.printStackTrace();
}
System.out.println( conn + " entered the room!" );
}

@Override
public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
try {
this.sendToAll( conn + " has left the room!" );
} catch ( InterruptedException ex ) {
ex.printStackTrace();
}
System.out.println( conn + " has left the room!" );
}

@Override
public void onMessage( WebSocket conn, String message ) {
conn.getRemoteSocketAddress().getAddress().getAddress();
try {
this.sendToAll( conn + "說: " + message );
} catch ( InterruptedException ex ) {
ex.printStackTrace();
}
// System.out.println( conn + ": " + message );
// byte[] fileBanary = message.getBytes();
// saveFileFromBytes(fileBanary, "src/test.png");
fileName = message;
System.out.println("收到字符串流");
}

@Override
public void onMessage(WebSocket conn, byte[] message) {
saveFileFromBytes(message, "src/" + fileName);
System.out.println("收到2進制流");
}

public static void main( String[] args ) throws InterruptedException , IOException {
WebSocket.DEBUG = false;
int port = 8887;
try {
port = Integer.parseInt( args[ 0 ] );
} catch ( Exception ex ) {
}
ChatServer s = new ChatServer("localhost", port );
s.start();
System.out.println( "ChatServer started on port: " + s.getPort() );

BufferedReader sysin = new BufferedReader( new InputStreamReader( System.in ) );
while ( true ) {
String in = sysin.readLine();
s.sendToAll( in );
}
}

@Override
public void onError( WebSocket conn, Exception ex ) {
ex.printStackTrace();
}

/**
* Sends <var>text</var> to all currently connected WebSocket clients.
*
*
@param text
* The String to send across the network.
*
@throws InterruptedException
* When socket related I/O errors occur.
*/
public void sendToAll( String text ) throws InterruptedException {
for( WebSocket c : connections() ) {
c.send( text );
}
}

public static boolean saveFileFromBytes(byte[] b, String outputFile)
{
BufferedOutputStream stream = null;
File file = null;
try
{
file = new File(outputFile);
FileOutputStream fstream = new FileOutputStream(file);
stream = new BufferedOutputStream(fstream);
stream.write(b);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
finally
{
if (stream != null)
{
try
{
stream.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
return true;
}
}



 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM