android集成websocket下载方式
2016-01-04 17:22
399 查看
http://www.zhihu.com/question/20215561 协议介绍可以看看这里。
通过一次简单的握手,建立了客户端和服务器的联系后,服务器可以主动推送信息给客户端,而不需要客户端的反复请求。
一个websocket连接是客户端与服务器端在http协议的初始握手阶段将其升级到websocket协议来建立的,其底层还是tcp/ip连接。
优点:
我们基于开源框架autobahn开源框架来实现上诉需求。
首先介绍一下autobahn:
特点:
源码地址:https://github.com/qq451682583/autobahn-android/blob/master/Autobahn/src/de/tavendo/autobahn/WebSocketOptions.java
使用websocket首先创建所需实例:
之后我们通过三个接口,即可完成链接,下载,关闭websocket。同时,根据需求我们要保证每次只能有一个文件下载,所以我们加入同步机制来实现。
本博文,只给出一个大致思路,旨为记录需求的解决。
下面稍微总结一下:
webstocket是html5的一种新的协议,它实现了浏览器与服务器的双向通道,使得数据可以快速的双向传播.通过一次简单的握手,建立了客户端和服务器的联系后,服务器可以主动推送信息给客户端,而不需要客户端的反复请求。
一个websocket连接是客户端与服务器端在http协议的初始握手阶段将其升级到websocket协议来建立的,其底层还是tcp/ip连接。
优点:
客户端和服务器端之间数据交流的表头比较小。大概2个字节 服务器和客户端可以主动的发送数据给对方 不需要有频率的创建TCP请求和销毁,节约宽带和服务器的资源
需求下载流程
确定下载方式。当客户端确定下载方式为WebSocket方式时,客户端根据资源类型确定是同步或者异步方式下载离线资源,WebSocket需要支持异步下载和同步下载。 建立与服务器的连接。WebSocket初始化时,会根据“w”字段提供的Websockethost和服务端建立安全连接。连接失败两次,直接用http连接下载。 处理上送数据。WebSocket连接成功后,对上送的数据进行处理。处理方式同TCP。 发送数据到服务器。由于WebSocket通信是全双工通信的,确保更新下载,采用队列模式单文件下载,每次保证只有一个文件正在下载,只有当文件下载结束、超时或者取消下载的时候才会进行下一次的下载。 处理下载数据,对接收到得信息解析、组包、文件校验同TCP。 全部下载结束,断开连接,清空缓存。当所有文件下载完成后,客户端须主动断开WebSocket连接,并且清空相关缓存。如下载过程中连接断开,客户端须根据已成功下载的文件更新本地资源描述,并重新请求客户端更新接口。
我们基于开源框架autobahn开源框架来实现上诉需求。
首先介绍一下autobahn:
AutobahnAndroid 是 Android 平台上的 WebSocket & WAMP (WebSocket Application Messaging Protocol) 实现。
特点:
WebSocket 和 WAMP 客户端 实现了 WebSocket RFC6455, Draft Hybi-10+ and WAMP v1 支持 Android 2.2+ 良好遵循标准 高性能异步设计 易用的 API 无缝集成 Android UI 应用 UI 线程上无网络 Activity
源码地址:https://github.com/qq451682583/autobahn-android/blob/master/Autobahn/src/de/tavendo/autobahn/WebSocketOptions.java
使用websocket首先创建所需实例:
mWebSocket = new WebSocketConnection(); mWSOptions = new WebSocketOptions(); // 设置最大下载文件大小(目前为5M) mWSOptions.setMaxFramePayloadSize(5 * 1024 * 1024);
之后我们通过三个接口,即可完成链接,下载,关闭websocket。同时,根据需求我们要保证每次只能有一个文件下载,所以我们加入同步机制来实现。
public WebSocketDownload init() { try { mIsConnecting = true; mWebSocket.connect(mWS + Constants.OTA_WS, new WebSocketConnectionHandler() { @Override public void onOpen() { Utils.printLog(Constants.OFF_TAG, "Status: connected to..."); mIsConnecting = false; if (mIsDownloading) { // 服务器器重连成功,处理待请求的Model mWebSocket.sendBinaryMessage(mBodys); } else { notifyConnecting(); } } @Override public void onBinaryMessage(byte[] bytes) { mBytes = handleResponse(bytes); mIsDownloading = false; // 下载成功 notifyDownloading(); } @Override public void onClose(int code, String reason) { Utils.printLog(Constants.OFF_TAG, "Status: closed...[" + code + " : " + reason + "]"); mIsConnecting = false; if (mIsDownloading) {// 若资源下载时需要重连,若主动断开不用重连 reconnectServer(); } else { notifyConnecting(); } } }, mWSOptions); return this; } catch (WebSocketException e) { Utils.printLog(Constants.OFF_TAG, "Status: connect exception..."); Utils.printException(e); } return null; } /** * 叫醒等待连接的线程 */ private void notifyConnecting() { try { if (mWait != null) { // 叫醒等待连接的线程 synchronized (mWait) { mWait.notify(); } } } catch (Exception e) { Utils.printException(e); } } /** * 叫醒等待下载的线程 */ private void notifyDownloading () { try { synchronized (mModel) { mModel.notify(); } } catch (Exception e) { Utils.printException(e); } } public void close() { try { if (mWebSocket != null && mWebSocket.isConnected()) { mWebSocket.disconnect(); } mWebSocket = null; } catch (Exception e) { Utils.printException(e); } } /** * 是否文件下载中 * @return */ public boolean isDownloading () { return mIsDownloading; } /** * 获取经过处理后的文件内容 * * @return */ public byte[] getBytes() { return mBytes; } /** * 是否连接websocket 服务器中 * @return */ public boolean isConnecting () { return mIsConnecting; } /** * 是否websocket 已连接服务器 * @return */ public boolean isConnected () { return mWebSocket == null ? false : mWebSocket.isConnected(); }
// 等待是否建立成功 try { synchronized (wait) { if (wsDownload.isConnecting()) { Utils.printLog(Constants.OFF_TAG, "websocket wait connecting ..."); wait.wait(); } } } catch (InterruptedException e) { Utils.printException(e); } // websocket 为异步下载 if (download instanceof WebSocketDownload) { WebSocketDownload wsDownload = (WebSocketDownload)download; // 再判断是否文件下载中 synchronized (model) { if (wsDownload.isDownloading()) { model.wait(); } } bytes = wsDownload.getBytes(); } //开启下载任务的时候,wait,等待链接成功,链接成功后开始下载,wait,下载完后唤醒,继续下载下一个文件。
本博文,只给出一个大致思路,旨为记录需求的解决。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories