文件上传的步骤: 打开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
完整代码:
websocket.html(有用到Jquery):
DOCTYPE html>
<html>
<head>
<title>WebSocket Chat Clienttitle>
<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 text 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; } }