基于html5 websocket API简单实现断点上传文件
本实例只是简单地实现文件的断点上传功能,有更好的建议请不吝赐教
本实例基于html5的 websocket API和netty框架,如果您对两个技术不太熟悉,可以点击下面连接了解
websocket: http://www.chinaz.com/web/2012/0806/267188.shtml
netty: https://netty.io/
netty jar包:http://download.csdn.net/detail/wudasong_/4650052
准备:
fiefox浏览器或chrome浏览器
在classpath中导入netty类库,json类库
好拉,一切准备就绪...
服务器端:
WebSocketServerInitializer.java
/* * 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
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
/* * 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
<!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
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); } }; }
搞定..
求多多指教!!
相关推荐
本工程为MyEclipse javaWeb工程,用于展示如何使用 HTML5 webSocket API实现即时通讯的功能。 本工程编码方式:UTF-8 功能说明: 1、本功能支持多人聊天,类似于http://www.htkaoyan.com/网站中的在线自询; 2、...
本大文件分块上传断点续传处理器基于Netty和WebSocket实现,包含41个文件,包括Java源代码、XML配置文件、LICENSE文件、Markdown文档、Properties配置文件和HTML页面。系统界面友好,功能完善,适合用于大文件的上传...
构建实时Web应用:基于HTML5 WebSocket、PHP和jQuery(英文版) Realtime Web Apps: With HTML5 WebSocket, PHP, and jQuery
本篇文章主要介绍了HTML5-WebSocket实现多文件同时上传的实例,HTML5结合Websocket进行文件的传输就变得更加方便和灵活,有兴趣的可以了解一下。
基于Springboot+Websocket的简单聊天室 基于Springboot+Websocket的简单聊天室 基于Springboot+Websocket的简单聊天室 基于Springboot+Websocket的简单聊天室 基于Springboot+Websocket的简单聊天室 基于Springboot+...
基于html5websocket+java实现简单通讯
主要内容包括: WebSocket API和协议、WebSocket协议通信的例子、WebSocket的安全性和企业部署、内置即时通信和聊天应用程序的WebSocket与XMPP、通过WebSocket的STOMP实现发布/订阅消息传递协议,以及用远程帧缓冲...
赠送Maven依赖信息文件:javax.websocket-api-1.1.pom; 包含翻译后的API文档:javax.websocket-api-1.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:javax.websocket:javax.websocket-api:1.1; 标签:javax、...
基于html5websocket java实现简单通讯 index.jsp在输入框输入1234id5发送就可以发送给index1.jsp index1.jsp在输入框输入12332234id4发送就可以发送给index.jsp id前的消息随意,后面跟着要发送目标的id即可
基于Springboot websocket + js实现的即时聊天系统 基于Springboot websocket + js实现的即时聊天系统 基于Springboot websocket + js实现的即时聊天系统 基于Springboot websocket + js实现的即时聊天系统 基于...
案例使用html5+websocket实现文件断点续传功能,支持实时显示文件上传进度,支持同时上传多个文件,更多内容请关注github:https://github.com/songyou91/FileUploadCase.git,持续更新中。详细内容请关注微信公众号...
赠送Maven依赖信息文件:websocket-api-9.4.11.v20180605.pom; 包含翻译后的API文档:websocket-api-9.4.11.v20180605-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.eclipse.jetty.websocket:websocket-api:...
使用 HTML5 webSocket API实现即时通讯的功能.zip
赠送Maven依赖信息文件:jakarta.websocket-api-1.1.2.pom; 包含翻译后的API文档:jakarta.websocket-api-1.1.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:jakarta.websocket:jakarta.websocket-api:1.1.2; ...
主要内容包括: WebSocket API和协议、WebSocket协议通信的例子、WebSocket的安全性和企业部署、内置即时通信和聊天应用程序的WebSocket与XMPP、通过WebSocket的STOMP实现发布/订阅消息传递协议,以及用远程帧缓冲...
Java开发基于SpringBoot+WebSocket+Redis分布式即时通讯群聊系统。一个基于Spring Boot + WebSocket + Redis,可快速开发的分布式即时通讯群聊系统。适用于直播间聊天、游戏内聊天、客服聊天等临时性群聊场景。 ...
基于HTML5 WebSocket服务端的封装,绝对能用,让你不用费神捣鼓websocket方面的东西了,
php+html5实现无刷新上传,大文件分片上传,断点续传具体案例完整代码 详情:https://blog.csdn.net/qq43599939/article/details/79762042
C# WinForm 通过WebSocket 实现文件传输示例,包含了客户端和服务端。