android websocket的使用

websocket的使用

上一篇我写的是notifation通知的使用,这篇呢,介绍下websocket实现即时通讯

首先在这里说下websocket

WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是:

  • WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket 一样;
  • WebSocket 需要类似 TCP 的客户端和服务器端通过握手连接,连接成功后才能相互通信。
  • 如果想深入了解websocket机制和原理:http://www.ibm.com/developerworks/cn/java/j-lo-WebSocket/


废话不多说,以下步骤

1、添加网络权限,在通信的过程中我们都需要notifaction进行提示,所以还得加上notifaction所需权限

<!-- 网络权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

2、创建服务service,有人会问,为什么还需要服务,我想这个问题我可能不用过多的解释大家应该都明白

3、建立websocket连接,启动服务,startService的时候建立连接

      配置Service文件内容

<service
    android:name=".chat.MyService"
    android:enabled="true"
    android:persistent="true"/>
    MyService.class

package com.zy.fire.ui.chat;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Vibrator;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.zy.fire.ui.R;

import org.java_websocket.WebSocketImpl;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;




public class MyService extends Service {
    public static WebSocketClient client;
    private ConnectivityManager connectivityManager;
    private NetworkInfo info;
    private ArrayList<String> msgQueen = new ArrayList<String>();
    private boolean isSaveInSrevice = true;
    private MyBinder mBinder = new MyBinder();
    private boolean iscon = true;//用于在broadcast中判断是否是需要重新连接的
    private NotificationManager manager;
    private NotificationCompat.Builder notifyBuilder;
    private Vibrator vibrator;


    @Override
    public void onCreate() {
        super.onCreate();
        manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        IntentFilter mFilter = new IntentFilter();
        mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(mReceiver, mFilter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        String deviceID = SystemTool.phoneDeviceID(this);

        String address = "ws://192.168.3.5:8080/COMM/socket?" +
                "userId=123456ghjgjh789" +
                "&deviceNO=android_" + deviceID;   
        try {
            WebSocketImpl.DEBUG = true;
            System.setProperty("java.net.preferIPv6Addresses", "false");
            System.setProperty("java.net.preferIPv4Stack", "true");
            client = new WebSocketClient(new URI(address), new Draft_17()) {
                @Override
                public void onOpen(final ServerHandshake serverHandshakeData) {
                    iscon = true;
                    if (!isSaveInSrevice) {
                        Message msg = new Message();
                        msg.what = ChatClientActivity.ONOPEN;
                        ChatClientActivity.uihandler.sendMessage(msg);
                    } else {
                        Log.e("wz", "没有打开activity是的Onopen+1");
                    }
                }

                @Override
                public void onMessage(final String message) {
                    //接受到消息就发送震动
                    openVibrator();
                    //判断activity是否是在最前端,如果是就将消息直接传给activity,如果不是就保存在service                    //并且发送
                    if (!isSaveInSrevice) {
                        Message msg = new Message();
                        msg.what = ChatClientActivity.ONMESSEGE;
                        Bundle b = new Bundle();
                        b.putString("msg", message);
                        msg.setData(b);
                        ChatClientActivity.uihandler.sendMessage(msg);
                    } else {
                        msgQueen.add(message);
                        //发送通知
                        sendNotification();
                        Log.e("wz", message);
                    }
                }

                @Override
                public void onClose(final int code, final String reason, final boolean remote) {
                    iscon = false;
                    if (!isSaveInSrevice) {
                        Message msg = new Message();
                        msg.what = ChatClientActivity.ONCLOSE;
                        ChatClientActivity.uihandler.sendMessage(msg);
                    } else {
                        Log.e("wz", "没有activity时的" + " onClose");
                    }

                }

                @Override
                public void onError(final Exception e) {
                    iscon = false;
                    client.close();
                    Log.e("wz", String.valueOf(e));
                }
            };
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        client.connect();
        return super.onStartCommand(intent, flags, startId);

    }

    private void openVibrator() {
        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        long[] pattern = {100, 400, 100, 400};   // 停止 开启 停止 开启
        vibrator.vibrate(pattern, -1);           //重复两次上面的pattern 如果只想震动一次,index设为-1
    }

    @Override
    public boolean onUnbind(Intent intent) {
        mBinder.setIsSaveInSer();
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("wz", "+++++++++++Srevice Destroy++++++++++");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    /**
     * 接受到网络重连的广播时重新执行startcommoned方法让client重连
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                connectivityManager = (ConnectivityManager)
                        getSystemService(Context.CONNECTIVITY_SERVICE);
                info = connectivityManager.getActiveNetworkInfo();
                if (info != null && info.isAvailable() && iscon == false) {
                    //断网的时候client会被close (调用了onclose方法)
                    Intent serviceIntent = new Intent(context, MyService.class);
                    context.startService(serviceIntent);
//                    client.connect(); //不能用client直接connect,具体原因期待有人指出,可能是classnotfind                    Log.e("wz", "StartService");
                }
            }
        }
    };

    /**
     * 实现1.act到屏幕最前方时将保存在service中的msgUI发送
     * 2.act不再屏幕最前方时通知service保存消息
     */
    class MyBinder extends Binder {

        public void sendToUI() {
            Message msg = new Message();
            msg.what = ChatClientActivity.ONMESSEGELIST;
            Bundle b = new Bundle();
            ArrayList l = new ArrayList();
            l.addAll(msgQueen);
            b.putParcelableArrayList("list", l);
            msg.setData(b);
            ChatClientActivity.uihandler.sendMessage(msg);
            isSaveInSrevice = false;
            msgQueen.clear();
            manager.cancel(121);
        }

        public void setIsSaveInSer() {
            isSaveInSrevice = true;
        }
    }

    //发送notification
    private void sendNotification() {
        //点击的意图ACTION是跳转到Intent
        Log.e("wz", "sendNotification");
        Intent resultIntent = new Intent(this, ChatClientActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        notifyBuilder = new NotificationCompat.Builder(this)
            /*设置large icon*/
                .setLargeIcon(bitmap)
             /*设置small icon*/
                .setSmallIcon(R.mipmap.ic_launcher)
            /*设置title*/
                .setContentTitle("您收到了" + String.valueOf(msgQueen.size()) + "条消息")
            /*设置详细文本*/
                .setContentText(msgQueen.get(msgQueen.size() - 1))
             /*设置发出通知的时间为发出通知时的系统时间*/
                .setWhen(System.currentTimeMillis())
             /*设置发出通知时在status bar进行提醒*/
                .setTicker("收到新消息")
            /*setOngoing(boolean)设为true,notification将无法通过左右滑动的方式清除 * 可用于添加常驻通知,必须调用cancle方法来清除 */
                .setOngoing(false)
             /*设置点击后通知消失*/
                .setAutoCancel(true)
             /*设置通知数量的显示类似于QQ那种,用于同志的合并*/
//                .setNumber(3)
             /*点击跳转到MainActivity*/
                .setContentIntent(pendingIntent);

        manager.notify(121, notifyBuilder.build());
    }

}

4、实现长连接

      为啥还要长连接呢,可能有人会问,这是防止在一段时候后websocket断开,导致接受不到消息,和发送不出消息  ,大家可以使用下两种方法去实现

    <1>service +Thread

    <2>service+AlarmManager+Thread

    参考:http://blog.csdn.net/mingzhnglei/article/details/53464001

5、如果需要开机启动服务

    在applicaton类里初始化启动服务

Intent i = new Intent(this, MyService.class);
this.startService(i);

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值