基于html5 websocket API简单实现断点上传文件
来源:互联网 发布:网络直播要哪些设备 编辑:程序博客网 时间:2024/06/08 00:55
本实例基于html5的 websocket API和netty框架,如果您对两个技术不太熟悉,可以点击下面连接了解
websocket: http://www.chinaz.com/web/2012/0806/267188.shtml
http://www.websocket.org/
netty: https://netty.io/
netty jar包:http://download.csdn.net/detail/wudasong_/4650052
准备:
fiefox浏览器或chrome浏览器
在classpath中导入netty类库,json类库
好拉,一切准备就绪...
服务器端:
WebSocketServerInitializer.java
[java] view plain copy
- /*
- * Copyright 2012 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
- package com.wudasong.breakPoinUploadServer;
- import io.netty.bootstrap.ServerBootstrap;
- import io.netty.channel.Channel;
- import io.netty.channel.socket.nio.NioEventLoop;
- import io.netty.channel.socket.nio.NioServerSocketChannel;
- /**
- * A HTTP server which serves Web Socket requests at:
- *
- * http://localhost:8080/websocket
- *
- * Open your browser at http://localhost:8080/, then the demo page will be loaded and a Web Socket connection will be
- * made automatically.
- *
- * This server illustrates support for the different web socket specification versions and will work with:
- *
- * <ul>
- * <li>Safari 5+ (draft-ietf-hybi-thewebsocketprotocol-00)
- * <li>Chrome 6-13 (draft-ietf-hybi-thewebsocketprotocol-00)
- * <li>Chrome 14+ (draft-ietf-hybi-thewebsocketprotocol-10)
- * <li>Chrome 16+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
- * <li>Firefox 7+ (draft-ietf-hybi-thewebsocketprotocol-10)
- * <li>Firefox 11+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
- * </ul>
- */
- public class WebSocketServer {
- private final int port;
- public WebSocketServer(int port) {
- this.port = port;
- }
- public void run() throws Exception {
- ServerBootstrap b = new ServerBootstrap();
- try {
- b.eventLoop(new NioEventLoop(), new NioEventLoop())
- .channel(new NioServerSocketChannel())
- .localAddress(port)
- .childHandler(new WebSocketServerInitializer());
- Channel ch = b.bind().sync().channel();
- System.out.println("Web socket server started at port " + port + '.');
- System.out.println("Open your browser and navigate to http://localhost:" + port + '/');
- ch.closeFuture().sync();
- } finally {
- b.shutdown();
- }
- }
- public static void main(String[] args) throws Exception {
- int port;
- if (args.length > 0) {
- port = Integer.parseInt(args[0]);
- } else {
- port = 8082;
- }
- new WebSocketServer(port).run();
- }
- }
WebSocketServerHandler.java
[java] view plain copy
- package com.wudasong.breakPoinUploadServer;
- import static io.netty.handler.codec.http.HttpHeaders.*;
- import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
- import static io.netty.handler.codec.http.HttpMethod.*;
- import static io.netty.handler.codec.http.HttpResponseStatus.*;
- import static io.netty.handler.codec.http.HttpVersion.*;
- import java.io.File;
- import java.io.IOException;
- import java.io.RandomAccessFile;
- import java.nio.ByteBuffer;
- import java.nio.channels.FileChannel;
- import org.json.JSONException;
- import org.json.JSONObject;
- import io.netty.buffer.Unpooled;
- import io.netty.channel.ChannelFuture;
- import io.netty.channel.ChannelFutureListener;
- import io.netty.channel.ChannelHandlerContext;
- import io.netty.channel.ChannelInboundMessageHandlerAdapter;
- import io.netty.handler.codec.http.DefaultHttpResponse;
- import io.netty.handler.codec.http.HttpHeaders;
- import io.netty.handler.codec.http.HttpRequest;
- import io.netty.handler.codec.http.HttpResponse;
- import io.netty.handler.codec.http.HttpResponseStatus;
- import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
- import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
- import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
- import io.netty.handler.codec.http.websocketx.WebSocketFrame;
- import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
- import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
- import io.netty.util.CharsetUtil;
- /**
- * Handles handshakes and messages
- */
- public class WebSocketServerHandler extends ChannelInboundMessageHandlerAdapter<Object> {
- private static final String WEBSOCKET_PATH = "/websocket";
- private static final long BLOCK_SIZE=1024*65L;
- private static final int BYTE_BUFFER_SIZE=1024*65;
- private static final String SERVER_SAVE_PATH="D:\\fileUpload\\";
- private long startByte=0;
- private long stopByte=0;
- private JSONObject fileInfo;
- private WebSocketServerHandshaker handshaker;
- @Override
- public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
- if (msg instanceof HttpRequest) {
- handleHttpRequest(ctx, (HttpRequest) msg);
- } else if (msg instanceof WebSocketFrame) {
- handleWebSocketFrame(ctx, (WebSocketFrame) msg);
- }
- }
- private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
- // Allow only GET methods.
- if (req.getMethod() != GET) {
- sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));
- return;
- }
- // Handshake
- WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
- getWebSocketLocation(req), null, false,1048576);
- handshaker = wsFactory.newHandshaker(req);
- if (handshaker == null) {
- wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
- } else {
- handshaker.handshake(ctx.channel(), req);
- }
- }
- private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) throws JSONException, IOException {
- // Check for closing frame
- if (frame instanceof CloseWebSocketFrame) {
- handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame);
- return;
- } else if(frame instanceof TextWebSocketFrame){
- TextWebSocketFrame message=(TextWebSocketFrame)frame;
- fileInfo=new JSONObject(message.getText());
- System.out.println("上传的文件名:\t"+fileInfo.getString("name")+
- "\n文件大小:\t"+fileInfo.getLong("size")+
- "\n最后修改时间:\t"+fileInfo.getString("lastModifiedDate"));
- JSONObject message4client=new JSONObject();
- File file = new File(SERVER_SAVE_PATH+fileInfo.getString("name"));
- long fileSize=fileInfo.getLong("size");
- if(file.createNewFile()){
- stopByte=BLOCK_SIZE;
- message4client.put("startByte", 0);
- if(stopByte<fileSize){
- message4client.put("stopByte", stopByte);
- }else {
- message4client.put("stopByte", fileSize);
- }
- message4client.put("complete", false);
- }else {
- startByte=file.length();
- stopByte=startByte+BLOCK_SIZE;
- if(startByte>=fileInfo.getLong("size")){
- message4client.put("startByte", 0);
- message4client.put("stopByte", 0);
- message4client.put("complete", true);
- }
- if(stopByte<fileSize){
- message4client.put("startByte", startByte);
- message4client.put("stopByte", stopByte);
- message4client.put("complete", false);
- }else {
- message4client.put("startByte", startByte);
- message4client.put("stopByte", fileSize);
- message4client.put("complete", false);
- }
- }
- ctx.channel().write(new TextWebSocketFrame(message4client.toString()));
- }else if(frame instanceof BinaryWebSocketFrame){
- BinaryWebSocketFrame binaryFrame=(BinaryWebSocketFrame)frame;
- File file = new File(SERVER_SAVE_PATH+fileInfo.getString("name"));
- long fileSize=fileInfo.getLong("size");
- if(stopByte>=fileSize){
- stopByte=fileSize;
- }
- JSONObject message4client=new JSONObject();
- if(startByte>=fileInfo.getLong("size")){
- message4client.put("startByte", 0);
- message4client.put("stopByte", 0);
- message4client.put("complete", true);
- ctx.channel().write(new TextWebSocketFrame(message4client.toString()));
- }
- FileChannel fileChannel=new RandomAccessFile(file, "rw").getChannel();
- fileChannel.position(fileChannel.size());
- if(stopByte<fileSize){
- ByteBuffer byteBuffer=ByteBuffer.allocate(BYTE_BUFFER_SIZE);
- byteBuffer.clear();
- byteBuffer.put(binaryFrame.getBinaryData().array());
- byteBuffer.flip();
- fileChannel.write(byteBuffer);
- fileChannel.close();
- startByte=stopByte;
- stopByte=startByte+BLOCK_SIZE;
- message4client.put("startByte", startByte);
- message4client.put("stopByte", stopByte);
- message4client.put("complete", false);
- ctx.channel().write(new TextWebSocketFrame(message4client.toString()));
- }else {
- ByteBuffer byteBuffer=ByteBuffer.allocate(binaryFrame.getBinaryData().capacity());
- byteBuffer.clear();
- byteBuffer.put(binaryFrame.getBinaryData().array());
- byteBuffer.flip();
- fileChannel.write(byteBuffer);
- fileChannel.close();
- message4client.put("startByte", 0);
- message4client.put("stopByte", 0);
- message4client.put("complete", true);
- ctx.channel().write(new TextWebSocketFrame(message4client.toString()));
- }
- }
- }
- private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) {
- // Generate an error page if response status code is not OK (200).
- if (res.getStatus().getCode() != 200) {
- res.setContent(Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8));
- setContentLength(res, res.getContent().readableBytes());
- }
- // Send the response and close the connection if necessary.
- ChannelFuture f = ctx.channel().write(res);
- if (!isKeepAlive(req) || res.getStatus().getCode() != 200) {
- f.addListener(ChannelFutureListener.CLOSE);
- }
- }
- private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status);
- response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
- response.setContent(Unpooled.copiedBuffer(
- "Failure: " + status.toString() + "\r\n",
- CharsetUtil.UTF_8));
- ctx.write(response).addListener(ChannelFutureListener.CLOSE);
- }
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- cause.printStackTrace();
- ctx.close();
- }
- private static String getWebSocketLocation(HttpRequest req) {
- return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
- }
- }
WebServerSocket.java
[java] view plain copy
- /*
- * Copyright 2012 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
- package com.wudasong.breakPoinUploadServer;
- import io.netty.bootstrap.ServerBootstrap;
- import io.netty.channel.Channel;
- import io.netty.channel.socket.nio.NioEventLoop;
- import io.netty.channel.socket.nio.NioServerSocketChannel;
- /**
- * A HTTP server which serves Web Socket requests at:
- *
- * http://localhost:8080/websocket
- *
- * Open your browser at http://localhost:8080/, then the demo page will be loaded and a Web Socket connection will be
- * made automatically.
- *
- * This server illustrates support for the different web socket specification versions and will work with:
- *
- * <ul>
- * <li>Safari 5+ (draft-ietf-hybi-thewebsocketprotocol-00)
- * <li>Chrome 6-13 (draft-ietf-hybi-thewebsocketprotocol-00)
- * <li>Chrome 14+ (draft-ietf-hybi-thewebsocketprotocol-10)
- * <li>Chrome 16+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
- * <li>Firefox 7+ (draft-ietf-hybi-thewebsocketprotocol-10)
- * <li>Firefox 11+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17)
- * </ul>
- */
- public class WebSocketServer {
- private final int port;
- public WebSocketServer(int port) {
- this.port = port;
- }
- public void run() throws Exception {
- ServerBootstrap b = new ServerBootstrap();
- try {
- b.eventLoop(new NioEventLoop(), new NioEventLoop())
- .channel(new NioServerSocketChannel())
- .localAddress(port)
- .childHandler(new WebSocketServerInitializer());
- Channel ch = b.bind().sync().channel();
- System.out.println("Web socket server started at port " + port + '.');
- System.out.println("Open your browser and navigate to http://localhost:" + port + '/');
- ch.closeFuture().sync();
- } finally {
- b.shutdown();
- }
- }
- public static void main(String[] args) throws Exception {
- int port;
- if (args.length > 0) {
- port = Integer.parseInt(args[0]);
- } else {
- port = 8082;
- }
- new WebSocketServer(port).run();
- }
- }
客户端代码:
MyHtml.html
[html] view plain copy
- <!DOCTYPE html>
- <html>
- <head>
- <title>MyHtml.html</title>
- <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
- <meta http-equiv="description" content="this is my page">
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- </head>
- <body>
- <input type="file" id="files" name="file" />
- <input type="button" id="upload" value="上传" />
- <input type="button" id="stop" value="暂停" />
- <script type="text/javascript" src="upload.js"></script>
- </body>
- </html>
upload.js
[javascript] view plain copy
- var socket;
- //openSocket("ws://localhost:8082/websocket");
- document.getElementById("stop").addEventListener("click", function(){
- socket.close();
- }, false);
- document.getElementById("upload").addEventListener("click", function(){
- openSocket("ws://localhost:8082/websocket");
- setTimeout(function(){
- fileUpload();
- }, 500);
- }, false);
- function openSocket(url){
- if(!window.WebSocket){
- window.WebSocket=window.MozWebSocket;
- }
- if(window.WebSocket){
- socket=new WebSocket(url);
- // socket=new WebSocket("ws://localhost:8082/websocket");
- socket.onopen=onOpen;
- socket.onclose=onClose;
- }else {
- alert("your browser does not support websocket");
- }
- };
- function onOpen(event){
- console.log("websocket is opened");
- }
- function onClose(event){
- console.log("websocket is closed");
- }
- function fileUpload(){
- var files = document.getElementById('files').files;
- if (!files.length) {
- alert('Please select a file!');
- return;
- }
- var file = files[0];
- var fileInfo={
- "opcode":1,
- "name":file.name,
- "size":file.size,
- "lastModifiedDate":file.lastModifiedDate
- };
- // console.log(JSON.stringify(fileInfo));
- send(JSON.stringify(fileInfo));
- socket.onmessage=function(event){
- var startStop=JSON.parse(event.data);
- if(startStop.startByte===startStop.stopByte||startStop.complete){
- console.log(startStop);
- alert("文件上传成功!");
- }else {
- console.log(startStop);
- readBlob(files,startStop.startByte, startStop.stopByte);
- }
- };
- }
- function send(message){
- if(!window.WebSocket){
- return;
- }
- if(socket.readyState==WebSocket.OPEN){
- socket.send(message);
- }else{
- console.log("the socket is not open");
- }
- }
- function readBlob(files,opt_startByte, opt_stopByte) {
- if (!files.length) {
- alert('Please select a file!');
- return;
- }
- var file = files[0];
- var start = parseInt(opt_startByte) || 0;
- var stop = parseInt(opt_stopByte) || file.size - 1;
- var reader = new FileReader();
- if (file.webkitSlice) {
- var blob = file.webkitSlice(start, stop);
- } else if (file.mozSlice) {
- var blob = file.mozSlice(start, stop);
- }
- reader.readAsArrayBuffer(blob);
- reader.onloadend = function(evt) {
- if (evt.target.readyState == FileReader.DONE) { // DONE == 2
- send(reader.result);
- }
- };
- }
阅读全文
0 0
- 基于html5 websocket API简单实现断点上传文件
- 基于html5 websocket API简单实现断点上传文件
- HTML5-WebSocket实现多文件同时上传
- HTML5-WebSocket实现多文件同时上传
- 利用HTML5+的API实现基于MUI的文件上传
- 基于 HTML5 File API 的文件上传
- html5 websocket 简单实现
- html5 大文件断点上传
- html5 file slice()对文件进行分块,实现断点上传
- 后端springmvc,前端html5的FormData实现文件断点上传
- Html5,Java WebSocket简单实现
- HTML5基于Tomcat 7.0实现WebSocket连接并实现简单的实时聊天
- HTML5使用 JavaScript File API 实现文件上传
- HTML5使用 JavaScript File API 实现文件上传
- HTML5使用 JavaScript File API 实现文件上传
- HTML5文件上传FileReader API
- 文件上传HTML5 File API
- 基于HT for Web矢量实现HTML5文件上传进度条
- CodeForces
- SCUT Training 20170913 Problem P
- java代码块的划分及作用
- Java生成和操作Excel文件
- Elasticsearch 429,logstash没有更新kafka队列状态的问题
- 基于html5 websocket API简单实现断点上传文件
- C++ error LNK1169:找到一个或多个多重定义的符号 解决
- POJ
- webSocket 消息推送
- 归并排序--Python
- VS2010护眼色
- eclispe 快捷键收集
- iOS代码加密的几种方式
- 网格走法数目