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通信基础服务相关推荐

  1. Android studio 下 JNI 开发实例

    在AS中进行 NDK 开发之前,我们先来简单的介绍几个大家都容易搞懵的概念: 到底什么是JNI,什么是NDK? 何为"交叉编译"? 先看什么是 JNI?JNI 的全称就是 Java ...

  2. JNI开发笔记(一)--Android Studio安装与环境搭建

    Android Studio安装与环境搭建 1. 前言 1.1 什么是JNI 1.2 JNI从零开发流程 2. Java环境配置 3. Android Studio安装 参考链接 1. 前言 工作中需 ...

  3. RESTLET开发实例(二)使用Component、Application的REST服务

    2019独角兽企业重金招聘Python工程师标准>>> 上一篇文章,我们介绍了基于JAX-RS的REST服务,本篇文章我们介绍不基于JAX-RS的模式.JAX-RS其实就是一个简单的 ...

  4. Linux环境下NDK JNI开发实例

    今天搞了一天这个实例,也不是那么的容易,中间碰到很多的问题 一,在windows下创建Test JNI工程 步骤: 1,在Eclipse中创建Android工程...(省略) 2,添加一个简单的功能, ...

  5. Android JNI开发摘录(四)之JNI异常处理

    五.处理本机代码中的异常 为了处理以Java代码实现的方法执行中抛出的异常,或者是以本机代码编写的方法抛出的Java异常,JNI提供了Java异常机制的钩子程序.该机制与C/C++中常规函数实现的标准 ...

  6. JNI开发笔记(三)--JNI工程的框架分析

    JNI工程的框架分析 引 1. JNI工程的组成部分 2. 各个部分之间的关系 引 JNI开发笔记(一)–Android Studio安装与环境搭建 JNI开发笔记(二)–创建JNI基础工程并运行 1 ...

  7. JNI开发笔记(五)--JNI语法总结

    JNI语法总结 引 前言 1. 传参类型为变量/变量指针 1.1 变量 1.2 变量指针 2. 传参类型为数组指针 3. 传参类型为结构体指针 引 JNI开发笔记(一)–Android Studio安 ...

  8. 鸿蒙so系统,鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)

    鸿蒙JNI开发现状 现阶段,不仅鸿蒙JNI相关的开发资料较少,而且Phone相关的JNI开发资料几乎没有,这对于新入行的鸿蒙开发者们来说,非常不友好. 也可能会给Android工程(使用了SO库的工程 ...

  9. java jni开发_Java JNI开发实践记录

    当使用到JNI的时候,基本可以肯定Java的平台移植性注定减弱,接下来记录一次使用Java JNI开发的经历. 关于Java JNI的相关资料参见: 下面是使用JNI常见三种场景: 1.在Java应用 ...

  10. JNI开发笔记(八)--Java读取txt文件进行JNI测试

    Java读取txt文件进行JNI测试 引 前言 1. 新建assets文件夹 2. 载入测试文件 3. 建立文件读取方法 4. 在MainActivity中读取文件数据 引 JNI开发笔记(一)–An ...

最新文章

  1. 汇编寄存器(内存访问)基础知识之三---mov指令
  2. html5边框有圆弧,CSS圆角有立体感的DIV边框
  3. 业务层面缓存穿透的解决方案
  4. C# 海康DVR客户端开发系列(2)—— 封装API
  5. qt linux 串口eventdriven,详解 Qt 串口通信程序全程图文 (1)
  6. MongoDB 教程四: 高级更改操作
  7. 参数调整 新部署rac_详解Oracle数据库RAC架构性能优化--参数设置+优化设计
  8. 知识图谱入门 ,语义搜索
  9. 对象池 IObjectPool -- ESBasic 可复用的.NET类库(15)
  10. 发工资条软件如何使用?
  11. 计算机无法启动打印服务,电脑重启print spooler服务无法启动怎么处理
  12. nvm下载太慢问题解决
  13. 《天涯明月刀》服务器端3D引擎设计与开发
  14. 从仿射变化到STN网络
  15. Windows Server 2016 搭建DHCP服务器(踩坑后总结)
  16. 数字图像处理:基本算法-卷积和相关
  17. docker之旅,附带实例脚本
  18. SliceM与SliceL
  19. 20230223 作业
  20. 计算机常用英语对话,英语口语对话之买电脑时常用基本口语

热门文章

  1. OSG实时纹理提取 离屏渲染 输出到OpenCV 反向渲染 OSG摄像头反转 OSG动态模型 摄像机实时渲染
  2. 使用Gotestwaf测试WAF检测能力
  3. 数据库进行大数据量插入/更新操作
  4. 四、docker-compose的编程模版
  5. JAVA-初步认识-常用对象API(String类-常见功能-比较)
  6. 2017-2018 20155309 南皓芯 信息安全基础设计第八周博客
  7. tips to understand kexec
  8. lua table remove元素的问题
  9. 基于Bootstrap的后台通用模板
  10. 不常用,但热门的IOS第三方库(转)