ZMQ的介绍到处都有,这里就不说了,直接介绍如何使用
GitHub地址
JAR包下载地址
-
创建基本类,实现ZMQ连接断开
import android.util.Log import org.zeromq.SocketType import org.zeromq.ZContext import org.zeromq.ZMQ abstract class BaseMQ(_port: String, _type: SocketType) { val TAG = "BaseMQ" var context: ZContext? = null var socket: ZMQ.Socket? = null var url: String? = null var type:SocketType?=null init { type = _type url = BuildConfig.SERVER_URL+":"+_port } fun connect(): Int { context = ZContext() socket = context?.createSocket(type) socket?.let { it.setReceiveTimeOut(2000) it.setSendTimeOut(2000) if (type == SocketType.REQ){ it.setReqCorrelate(true); it.setReqRelaxed(true); } it.connect(url) } return MQError.SUCCESS } fun close(): Int { socket?.let { it.disconnect(url) it.close() socket = null } context?.let { it.close() it.destroy() context = null } return MQError.SUCCESS } }
-
建立REQ客户端
import org.zeromq.SocketType import java.lang.Exception class RequestMQ(_port: String, _type: SocketType) : BaseMQ(_port, _type) { val TAG_T = "RequestMQ" @Synchronized fun requestMsg(request: String?): ByteArray? { try { socket?.let { it.send(request) return it.recv() } }catch (e:Exception){ e.printStackTrace() } return null } }
-
建立SUB客户端
import kotlinx.coroutines.* import org.zeromq.SocketType import org.zeromq.ZMQ class SubcribeMQ(_port: String, _type: SocketType) : BaseMQ(_port, _type) { val TAG_T = "SubcribeMQ" var isSub = false; var job:Job ?=null @Synchronized fun subcribeFilter(filter: String) { socket?.subscribe(filter.toByteArray()) } fun startSub() { isSub = true job = Job() var scope = CoroutineScope(job as CompletableJob) scope.launch(Dispatchers.IO) { while (isSub) { var byteArray = socket?.recv() byteArray?.let { processReply(it) } } } } fun stopSub(){ isSub = false; job?.cancel() } private fun processReply(reply: ByteArray) { } }
-
连接服务器
subcribeMq = SubcribeMQ(MQConst.PORT, SocketType.SUB) requestMq = RequestMQ(MQConst.PORT, SocketType.REQ)
-
常见问题
ZMQ send和recv需要成对出现,否则会出现:W/System.err: org.zeromq.ZMQException: Errno 156384763 : Operation cannot be accomplished in current state W/System.err: at org.zeromq.ZMQ$Socket.mayRaise(ZMQ.java:3732) W/System.err: at org.zeromq.ZMQ$Socket.send(ZMQ.java:3329) W/System.err: at org.zeromq.ZMQ$Socket.send(ZMQ.java:3239) W/System.err: at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1978) W/System.err: at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:2010) W/System.err: at android.os.Handler.handleCallback(Handler.java:938) W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99) W/System.err: at android.os.Looper.loop(Looper.java:223) W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7664) W/System.err: at java.lang.reflect.Method.invoke(Native Method) W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:596) W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
这时候可以通过将REQ的 ZMQ_REQ_CORRELATE 和 ZMQ_REQ_RELAXED开关打开,这样就会取消一发一收限制;
SUB非阻塞可以使用:
var byteArray = socket?.recv(ZMQ.DONTWAIT)
监听所有消息和指定消息:
it.subcribeFilter("")
it.subcribeFilter(ZMQFilter.FILTER)