文件上传的步骤: 打开websocket--连接websocket服务器--在浏览器里选择文件--将文件读入到内存中(以arraybuffer的形式)--在socket里发送文件--完毕!
服务器端:
先配置好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的用法参见
2. 如果是用Chrome的话,必须把网页放在服务器上或插件里,file协议下会失败。FileRead的onload函数不会响应!
参考资料:
完整代码:
websocket.html(有用到Jquery):
WebSocket Chat Client
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; }); });
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; } }