Android使用WebSocket实现设备登录限制(与后台建立长连接)

前言:由于我们的项目是一款针对于海外用户的APP,国内的一些第三方SDK
会受到一些限制,项目中要做的一个功能,本来国内使用极光推送就可以完全实现,然后我们就部署了,但是做完之后发现国外的用户有时候会收不到推送信息,这时候联系极光的客服,对方说需要开通海外服务器的权限(其实就是开通VIP),然后给了几天的测试,效果确实不错,然后价格也确实不错,千人日活的年费大概是3万元左右,我们现在应用的总用户达到了600多万(具体日活就不说了),费用可想而知,最后就给PASS掉了,有点说 跑偏了。。。接下来进入正题:
APP运行环境:
机顶盒或电视

实现的功能
1:用户打开微信登录页面,使用手机微信扫描二维码完成登录功能。
2:用户在设备A登录成功,用同一个微信账号在设备B登录,设备A退出
3:用的打开微信支付页面,用户扫码付款后关闭支付页面并显示到期时间。(和1逻辑一样)
具体实现:
其实Android端要做的事情很少,基本就是一个发送和接收的过程,然后做一个心跳,保证和服务端的长连接不会断掉,能收到服务端发送过来的信息并且处理就可以了。本来这个功能使用轮询也可以做到,功能1和3使用轮询是没有问题的,因为他们只是在一个Activity页面中去做这个事情,大不了给他一个时间,固定的时间内没有完成操作直接把页面和轮询关掉就可以了,这时候对应用本身是没有任何影响的,但是功能2就不一样了,只要是登录状态下,应用就要一直和后台保持连接,如果服务器有信息发送过来就要立马接收并且退出账号(其实也可以把这个功能放到页面间的跳转或者某个事件里面,但是需求如此,没有办法。。。),好了,废话又开始了,直接上代码:

  /**
     * 心跳检测时间
     */
    private static final long HEART_BEAT_RATE = 15 * 1000;//每隔15秒进行一次对长连接的心跳检测
    private static final String WEBSOCKET_HOST_AND_PORT = "ws://ws.*****.net:8090";//替换为自己的主机名和端口号
    private WebSocket mWebSocket;
    // 初始化socket
    private void initSocket() throws UnknownHostException, IOException {
        OkHttpClient client = new OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS).build();
        Request request = new Request.Builder().url(WEBSOCKET_HOST_AND_PORT).build();
       client.newWebSocket(request, new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {//开启长连接成功的回调
                super.onOpen(webSocket, response);
                mWebSocket = webSocket;

                mWebSocket.send("要发送给服务端的信息,比如设备id等等");

                   
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {//接收消息的回调
                super.onMessage(webSocket, text);
                //这里的text就是服务端发送过来的信息了,可以是json格式,具体和后台去定
               

            }

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                super.onMessage(webSocket, bytes);
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                super.onClosing(webSocket, code, reason);
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                super.onClosed(webSocket, code, reason);
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) {//长连接连接失败的回调
                super.onFailure(webSocket, t, response);
            }
        });
        client.dispatcher().executorService().shutdown();
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
    }
    private long sendTime = 0L;
    // 发送心跳包
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
             if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                try {
                    boolean isSuccess = mWebSocket.send("");//发送一个空消息给服务器,通过发送消息的成功失败来判断长连接的连接状态
                    if (!isSuccess) {//长连接已断开
                        mHandler.removeCallbacks(heartBeatRunnable);
                        mWebSocket.cancel();//取消掉以前的长连接
                        new InitSocketThread().start();//创建一个新的连接
                    } else {//长连接处于连接状态

                    }

                    sendTime = System.currentTimeMillis();
                }catch (Exception e){

                }

            }
            mHandler.postDelayed(this, HEART_BEAT_RATE);//每隔一定的时间,对长连接进行一次心跳检测
        }
    };

后记

我是把这个websocket放到了service中,所有的开启和关闭都是在Activity中实现的:

//关闭长连接
    public  void CancelWebSocket(){
      mWebSocket.cancel();
   }
//初始化长连接
    public  void StartlWebSocket(){
      new InitSocketThread().start();
    }

你可能感兴趣的:(android)