mars icon indicating copy to clipboard operation
mars copied to clipboard

心跳,登录

Open VectorWen opened this issue 5 years ago • 4 comments

心跳的协议是如何?

心跳发送的协议头是?需要服务器返回的协议头是?

登录

登录逻辑是?

VectorWen avatar Jun 11 '19 07:06 VectorWen

android sample 心跳:

心跳协议头

客户端主动发送心跳,服务端收到后不需要修改,原封不动的返回

headLength: 20
version: 200
cmdid: 6
seq: -1
bodyLength: 0
body: 没有

运行就会发送一次心跳

  1. 连接成功
  2. 发送心跳(原封不动收到返回证明连接成功了)

注意点:cmdid 在请求和响应中是不变的,有些协议使用不同的响应cmdid

心跳间隔

  1. 说除了android 其他平台是4.5 分钟发送一次(测试的时候android 也是4.5分钟),也说是智能心跳(自己不用管,留着框架去完成即可)
  2. sample 的服务端是15分钟无操作断开连接。(但是我看了一些文档,建议设置不超过1分钟,也不知道为什么这里这么大)

VectorWen avatar Jun 11 '19 07:06 VectorWen

登录(自定义鉴权)

  1. 是否需要鉴权(验证)?由 StnLogic.getLongLinkIdentifyCheckBuffer() 返回值决定。

    • ECHECK_NOW = 0 需要鉴权,立即发送验证包。
    • ECHECK_NEXT = 1 下次再说,等真正需要发送请求了再说。
    • ECHECK_NEVER = 2 不需要鉴权。
  2. 第一个包是什么包?心跳包还是验证包。默认是验证包。由longlink_complexconnect_need_verify 决定,修改需要重新编译mars。建议使用默认的。

我重写的代码

    @Override
    public int getLongLinkIdentifyCheckBuffer(ByteArrayOutputStream identifyReqBuf, ByteArrayOutputStream hashCodeBuffer, int[] reqRespCmdID) {
        // Send identify request buf to server
        // identifyReqBuf.write();
        // 1-0,发送验证包的cmdid
        reqRespCmdID[0] = 65536;
        reqRespCmdID[1] = 65536;

        //为了方便,我直接把写了byte[] 因为android sample 比较难使用protobuf
        //只是测试鉴权,所以没事,正在开发的时候修正就好
        identifyReqBuf.write(10);
        identifyReqBuf.write(36);
        byte[] token = "d00026c0-caf5-408b-8b9e-c1f713cd732d".getBytes();
        try {
            identifyReqBuf.write(token);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 立即发送验证包
        return StnLogic.ECHECK_NOW;
    }

    @Override
    public boolean onLongLinkIdentifyResp(byte[] buffer, byte[] hashCodeBuffer) {
        // 成功,为了方便,也没有对buffer 解密判断了。
        return true;
    }

------------- 以下是我调试的时候碰到的坑

1、断点无效

在getLongLinkIdentifyCheckBuffer() 方法里面打了断点,但是没有效果。

常见问题提到

longlink_complexconnect_need_verify的含义是如果设为 true 经过心跳包验证的连接才认为是成功的连接。如果你的长连接建立连接后第一个包必须是验证包,该函数的返回值一定要设为false。 长连的鉴权是会回调GetLonglinkIdentifyCheckBuffer这个函数,实现即可,记得处理回包:OnLonglinkIdentifyResponse,需要区分开长连接的鉴权和用户的登陆。长连的鉴权只是用来表示这个长连接是某个人的,不要用来做登陆功能。

但是我true 和false 都试过了,还是无法回调getLonglinkIdentifyCheckBuffer 方法,不知道为什么。

原因:android sample 使用了多进程,所以没有把调试切换到逻辑进程,切换了就可以看到效果。

切换调试进程方法:Run -> Attach Debugger to Android Process ...

2、后台服务鉴权成功后,立马断开了连接

因为服务响应的 seq(sequence) 和version 不一致导致的,改为和请求过来的一致即可。

mars 要求:seq 用来对应请求和响应,必须一致。version 对应客户端版本号,必须响应客户端一致的version,否则客户端(mars) 立马断开。

3、看了makesureAuthed() 方法

---- 2019年06月12日12:53:02

看到了一个makesureAuthed() 方法,好像是返回是否已经鉴权的。一直返回true 所以不回调。也不知道是不是,待我认证。

    @Override
    public boolean makesureAuthed() {
        //
        // Allow you to block all tasks which need to be sent before certain 'AUTHENTICATED' actions
        // Usually we use this to exchange encryption keys, sessions, etc.
        //
        return true;
    }

VectorWen avatar Jun 11 '19 11:06 VectorWen

心跳的协议是如何?

心跳发送的协议头是?需要服务器返回的协议头是?

登录

登录逻辑是?

大佬,请问你们接通了吗?623125868,请问能否方便加下我qq,请教下,谢谢

superzjcy avatar Nov 03 '20 07:11 superzjcy

上面的VectorWen的这段代码有问题呢,文档说了这个长度是1,所以只要一个。 reqRespCmdID[0] = 65536; reqRespCmdID[1] = 65536;

我弄了好久,关于回包,服务器收到数据以后,需要原样返回,其实不原样返回也行。但是seq必须要保持一致,否则不知道哪个是登录的回报。

另外严格意义上,这个getLongLinkIdentifyCheckBuffer 这个方法不是用来登录,是用来给每个ctx绑定一个唯一的值,后台通过该这个值查找对应的通道,再推送。

还有关于不能调试问题,上面他解答了。我也是弄了好久不能调试,我直接就输出日志了。 “切换调试进程方法:Run -> Attach Debugger to Android Process ...” 其实点上面的小虫子旁边带箭头的也能attach debug进程,不过要等进程启动才行。

算是给要对接的人一点启示吧。

agoodcoolman avatar Apr 13 '22 09:04 agoodcoolman