[JNI] 开发实例(2) 编译libwebsocket,封装jni函数,搭建IM通信基础服务
WebSocket协议是基于TCP的一种新的协议。WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符。它实现了浏览器与服务器全双工(full-duplex)通信。这段介绍来自百科。
当然websocket也可以用于android建立长链接,实现IM通信
优势:节省内存空间。当然这个是服务端并发时候节省内存空间,支持的并发量更大 ,这个我没做服务端没有验证。
原理和优势不再本文讨论范围内,今天主要记录下怎么编译libwebsocket.so
1.下载Libwebseocket库
git clone https://github.com/warmcat/libwebsockets.git
2.环境准备(Mac版)
2.1安装zlib :
brew install zlib
2.2安装makedepend:
brew install makedepend
2.3安装cmake :
brew install cmake
3.编译.a静态文件
有了上面这些工具,准备工作差不多了,然后通过libwebsocket/contrib目录下的android-make-script.sh编译.a文件 这个sh文件有些问题,比如:只能编译出arm架构的文件,并且在编译zlib库时使用的libtool有问题,libwebsocket原文件编译出错。
针对这些问题作了一些修改:
3.1 修改output.c和http2.c原文件编译错误,这个已经提交到libwebsocket base2.2版本上了
https://github.com/warmcat/libwebsockets/commit/34842d7492b728349f6a6898e3893b08d70625fa
3.2 替换libtool文件
mv ./Makefile ./Makefile.old
sed "s/AR=libtool/AR=`echo ${AR}|sed 's#\/#\\\/#g'`/" ./Makefile.old > Makefile.mid
sed "s/ARFLAGS=-o/ARFLAGS=-r/" ./Makefile.mid > Makefile
3.3 增加build x86架构文件编译
android支持的架构不光是arm,还有x86 x86-64等架构的机器,常用的armabi 和x86 这里提供了编译方式 如果还需要其他架构的可以根据android-make-script-all.sh文件 修改对应的参数
其他架构的参数可以在原始项目的test-server中的NativeLibs.mk中找到,然后修改android-make-script-all.sh文件
4.JNI封装websocket.
4.1初始化 initLws
初始化context
先准备好必要的参数 :host ,port ,path,timeout, ping,ca cert
涉及到函数:
jni_setConnectionParameters // host port path
jni_setTimeout //超时
jni_setPingInterval //ping 间隔
jni_setCaCert //证书
然后调用lws_create_context初始化context
jni_initLws
4.2连接 connect
当context初始化后,就可以连接服务器了
jni_connectLws
在jni_connectLws调用lws_client_connect_via_info连接服务器
还有一个重要的函数
jni_serviceLws
这个方法的作用是,轮训,不断的去检查是否有消息接收,检查到有新消息到达,通过callback回调,然后通过receiveMessage回调到java层
4.3发送/接收消息 writeLws/callback
接收消息:
我们在初始化context时注册了一个协议,这个protocol中包含一个callback,我们就是通过这个callback来接收服务端的消息,及错误信息
static int callback(struct lws *wsi,enum lws_callback_reasons reason,void *user,void *in,size_t len
) {//return 0;
}
只需要关注下面两个参数
reason:回执code
in :消息体
发送消息:
jni_sendMessageLws
调用的lws_write来发送消息,这里要注意的是发送消息的大小(初始化时候设置的),如果超过这个大小消息会分片,分片的消息需要自行处理,在callback中LWS_CALLBACK_SERVER_WRITEABLE处理剩下的报文。
当然我们平时发送的消息体不会太大,一般几百个字节最够了,我这里设置的4K
够发1500+个汉字。
4.4断开 exitLws
调用lws_context_destroy断开连接
重要函数参数:
状态值 | 含义 |
---|---|
LWS_CALLBACK_WSI_CREATE | 含义:正在创建ws连接对象备注:此时表1中wsi对象和user对象依然为空指针,因此,还不能初始化用户自定义对象。回调函数的参数含义: context: 全局上下文 wsi: 空指针 user: 空指针 in: 空指针len: 0 |
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION | 使用lws库的人员可以在此过滤协议。备注:在此处返回非0值时,lws库将会关闭该链接;该处返回0时,表示ws连接已经建立成功。此时表1中的wsi对象和user对象已不为空,因此,此时可以对用户自定义对象user进行初始化处理。 |
LWS_CALLBACK_RECEIVE | 表示WS服务端收到客户端发送过来的一帧完整数据,此时表1中的in表示收到的数据,len表示收到的数据长度。需要注意的是:指针in的回收、释放始终由LWS框架管理,只要出了回调函数,该空间就会被LWS框架回收。因此,开发者若想将接收的数据进行转发,则必须对该数据进行拷贝 |
LWS_CALLBACK_CLOSED | ws连接已经断开 备注:不能在此释放内存空间,否则存在内存泄漏的风险!!!因为连接断开时,并不总是会回调LWS_CALLBACK_CLOSED的处理! |
LWS_CALLBACK_WSI_DESTROY | 正在销毁ws连接对象 表示libwebsockets框架即将销毁wsi对象。此时如果用户自定义对象中存在动态分配的空间,则需要在此时进行释放 |
重要函数:
状态值 | 功能 |
---|---|
lws_send_pipe_choked | 功能:判断ws连接是否阻塞 备注:如果ws连接阻塞,则返回1,否则返回0 |
lws_create_context | 功能:初始化websocket服务,返回context 如果不为null 初始化成功 |
lws_client_connect_via_info | 功能:建立websocket连接 ,返回wsi 如果不为null 连接成功 |
lws_write | 功能:将数据发送给对端 备注:函数参数说明 wsi: ws连接对 buf: 需要发送数据的起始地址 返回:result > 0 成功,result = 0 失败 |
lws_callback_on_writable | 将ws连接加入可写事件监听 |
lws_service | 检查是否有新消息接收 |
lws_context_destroy | 断开websocket服务 |
5.搭建简易服务端测试
进入到python服务器所在目录 运行下面命令 启动python服务器
python testServer.py
这个py服务器比较简单,只能支持1024字节传输,超过这个长度会乱码,要测试超长字符,服务器还是要自己去搭建。
通过上面的步骤,就可以编译了下面是我编译好的源码及demo,有需要可以下载
https://github.com/honjane/buildLibWebSocket
demo使用步骤:
1.进入buildws目录,运行sh文件 生成.a文件,然后把生成的.a文件拷贝到websocket/src/main/jni/ 对应架构下 libcrypto.a libssl.a libwebsocket.a libz.a
2.使用build-ndk 编译 jni目录生成对应libwebsocket.so 怎么编译就不多说,生成的so文件会在libs和obj目录下,把这些生存的so拷贝到jniLibs/对应架构下目录
3.启动python服务器 ,连接服务器,发送消息
[JNI] 开发实例(2) 编译libwebsocket,封装jni函数,搭建IM通信基础服务相关推荐
- Android studio 下 JNI 开发实例
在AS中进行 NDK 开发之前,我们先来简单的介绍几个大家都容易搞懵的概念: 到底什么是JNI,什么是NDK? 何为"交叉编译"? 先看什么是 JNI?JNI 的全称就是 Java ...
- JNI开发笔记(一)--Android Studio安装与环境搭建
Android Studio安装与环境搭建 1. 前言 1.1 什么是JNI 1.2 JNI从零开发流程 2. Java环境配置 3. Android Studio安装 参考链接 1. 前言 工作中需 ...
- RESTLET开发实例(二)使用Component、Application的REST服务
2019独角兽企业重金招聘Python工程师标准>>> 上一篇文章,我们介绍了基于JAX-RS的REST服务,本篇文章我们介绍不基于JAX-RS的模式.JAX-RS其实就是一个简单的 ...
- Linux环境下NDK JNI开发实例
今天搞了一天这个实例,也不是那么的容易,中间碰到很多的问题 一,在windows下创建Test JNI工程 步骤: 1,在Eclipse中创建Android工程...(省略) 2,添加一个简单的功能, ...
- Android JNI开发摘录(四)之JNI异常处理
五.处理本机代码中的异常 为了处理以Java代码实现的方法执行中抛出的异常,或者是以本机代码编写的方法抛出的Java异常,JNI提供了Java异常机制的钩子程序.该机制与C/C++中常规函数实现的标准 ...
- JNI开发笔记(三)--JNI工程的框架分析
JNI工程的框架分析 引 1. JNI工程的组成部分 2. 各个部分之间的关系 引 JNI开发笔记(一)–Android Studio安装与环境搭建 JNI开发笔记(二)–创建JNI基础工程并运行 1 ...
- JNI开发笔记(五)--JNI语法总结
JNI语法总结 引 前言 1. 传参类型为变量/变量指针 1.1 变量 1.2 变量指针 2. 传参类型为数组指针 3. 传参类型为结构体指针 引 JNI开发笔记(一)–Android Studio安 ...
- 鸿蒙so系统,鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)
鸿蒙JNI开发现状 现阶段,不仅鸿蒙JNI相关的开发资料较少,而且Phone相关的JNI开发资料几乎没有,这对于新入行的鸿蒙开发者们来说,非常不友好. 也可能会给Android工程(使用了SO库的工程 ...
- java jni开发_Java JNI开发实践记录
当使用到JNI的时候,基本可以肯定Java的平台移植性注定减弱,接下来记录一次使用Java JNI开发的经历. 关于Java JNI的相关资料参见: 下面是使用JNI常见三种场景: 1.在Java应用 ...
- JNI开发笔记(八)--Java读取txt文件进行JNI测试
Java读取txt文件进行JNI测试 引 前言 1. 新建assets文件夹 2. 载入测试文件 3. 建立文件读取方法 4. 在MainActivity中读取文件数据 引 JNI开发笔记(一)–An ...
最新文章
- 汇编寄存器(内存访问)基础知识之三---mov指令
- html5边框有圆弧,CSS圆角有立体感的DIV边框
- 业务层面缓存穿透的解决方案
- C# 海康DVR客户端开发系列(2)—— 封装API
- qt linux 串口eventdriven,详解 Qt 串口通信程序全程图文 (1)
- MongoDB 教程四: 高级更改操作
- 参数调整 新部署rac_详解Oracle数据库RAC架构性能优化--参数设置+优化设计
- 知识图谱入门 ,语义搜索
- 对象池 IObjectPool -- ESBasic 可复用的.NET类库(15)
- 发工资条软件如何使用?
- 计算机无法启动打印服务,电脑重启print spooler服务无法启动怎么处理
- nvm下载太慢问题解决
- 《天涯明月刀》服务器端3D引擎设计与开发
- 从仿射变化到STN网络
- Windows Server 2016 搭建DHCP服务器(踩坑后总结)
- 数字图像处理:基本算法-卷积和相关
- docker之旅,附带实例脚本
- SliceM与SliceL
- 20230223 作业
- 计算机常用英语对话,英语口语对话之买电脑时常用基本口语
热门文章
- OSG实时纹理提取 离屏渲染 输出到OpenCV 反向渲染 OSG摄像头反转 OSG动态模型 摄像机实时渲染
- 使用Gotestwaf测试WAF检测能力
- 数据库进行大数据量插入/更新操作
- 四、docker-compose的编程模版
- JAVA-初步认识-常用对象API(String类-常见功能-比较)
- 2017-2018 20155309 南皓芯 信息安全基础设计第八周博客
- tips to understand kexec
- lua table remove元素的问题
- 基于Bootstrap的后台通用模板
- 不常用,但热门的IOS第三方库(转)