简单的 websocket


项目由于要实现一些自主定位推送,tcp协议后台不知怎么搭不上,决定还是换成http协议  用websocket 去实现推送。当时我是懵的,没去了解过这个websocket,和同事花了一下时间搞懂了一部分,深入的东西项目里没用到就先过了。


           需要的jar  包                        Java-WebSocket-1.3.1-SNAPSHOT.jar 

直接上代码


ClientReceiver.java

package com.qpp.websocketPush;

import java.io.Serializable;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.qpbox.R;
import com.qpp.MainActivity;
import com.qpp.entity.Comment;
import com.qpp.http.XHLog;


import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;
import android.widget.RemoteViews;

public class ClientReceiver extends BroadcastReceiver {
	public static final String LOGIN_BOX = "com.box";
	public static final String LOGIN_USER = "";
	public static final String LOGIN_LOACTION = "";
	public static final String MSG_SERVICE = "";
	/** Notification构造器 */
	NotificationCompat.Builder mBuilder;

	/** Notification的ID */
	int notifyId = 100;

	/** Notification管理 */
	public NotificationManager mNotificationManager;
	public Context context;
	//public PushBean push;
	public String MsgContent;
	public int MsgType;
	public String MsgImgpath;
	private List<WPush> content;

	@SuppressLint("NewApi")
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		// String action = intent.getAction();
		System.out.println("接受到广播");
		this.context = context;
		initNotify();
		mNotificationManager = (NotificationManager) context
				.getSystemService(Context.NOTIFICATION_SERVICE);// 获取系统通知的服务

		// push = new PushBean();
		Object msg = intent.getExtras().get("msg");
		Log.e(ClientReceiver.class.getName(), msg.toString());
		if (msg instanceof String) {
			deal_string(msg.toString());
		} else if (msg instanceof Serializable) {
			deal_serializable((Serializable) msg);
		}
	}

	private void deal_serializable(Serializable serializable) {
		// showIntentActivityNotify(serializable.toString());
		showIntentActivityNotify(serializable.toString());
		System.out.println("11111");
	}

	// / {"type":1,"msg":{}} type 类型 0 1 2 3 4 5 6   接收后台传来的数据 json  解析  设置到通知里
	private void deal_string(String string) {
		XHLog.e("json", string);
//		try {
//			JSONObject jo = new JSONObject(string);
//			String mainTitle = jo.getString("mainTitle");
//			String secondaryTitle  =jo.getString("secondaryTitle");
//			int fd= jo.getInt("fd");
//			int type = jo.getInt("type");
//			//if (code == 200) {
//			if(type==1){
//				
//				JSONArray jsonArray = jo.getJSONArray("content");
//				String contenttext = jsonArray.getString(0);
//			}
//			if(type==2){
//				JSONArray jsonArray = jo.getJSONArray("content");
//				for (int i = 0; i < jsonArray.length(); i++) {
//					content.add(WPush.getpush(jsonArray
//							.getJSONObject(i)));
//				}
//			}
//			if(type==3){
//				JSONArray jsonArray = jo.getJSONArray("content");
//				String webpath = jsonArray.getString(0);
//			}
//		} catch (JSONException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
			
		
		
		showIntentActivityNotify(string);
	}



	public PendingIntent getDefalutIntent(int flags) {
		PendingIntent pendingIntent = PendingIntent.getActivity(context, 1,
				new Intent(), flags);
		return pendingIntent;
	}

	public void showIntentActivityNotify(String text) {
		// Notification.FLAG_ONGOING_EVENT --设置常驻
		// Flag;Notification.FLAG_AUTO_CANCEL 通知栏上点击此通知后自动清除此通知
		// notification.flags = Notification.FLAG_AUTO_CANCEL;
		// //在通知栏上点击此通知后自动清除此通知
		try {
			// mBuilder = new NotificationCompat.Builder(context);
			mBuilder.setAutoCancel(true)
					// 点击后让通知将消失
					.setContentTitle("name").setContentText(text)
					.setSmallIcon(R.drawable.ico_qpp).setTicker("有新的更新");
			// 点击的意图ACTION是跳转到Intent
			Intent resultIntent = new Intent(context, MainActivity.class);
			resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
			PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
					resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
			mBuilder.setContentIntent(pendingIntent);
			mNotificationManager.notify(notifyId, mBuilder.build());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 初始化通知栏 "192.168.1.103"
	 * */
	private void initNotify() {
		mBuilder = new NotificationCompat.Builder(context);
		mBuilder.setContentTitle("name")
				.setContentText("name有新的更新")
				.setContentIntent(
						getDefalutIntent(Notification.FLAG_AUTO_CANCEL))
				// .setNumber(number)//显示数量
				.setTicker("测试通知来啦")// 通知首次出现在通知栏,带上升动画效果的
				.setWhen(System.currentTimeMillis())// 通知产生的时间,会在通知信息里显示
				.setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级
				.setAutoCancel(true)// 设置这个标志当用户单击面板就可以让通知将自动取消
				.setOngoing(false)// ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
				.setDefaults(Notification.DEFAULT_VIBRATE)// 向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:
				// Notification.DEFAULT_ALL Notification.DEFAULT_SOUND 添加声音 //
				// requires VIBRATE permission
				.setSmallIcon(R.drawable.ic_launcher);
	}

	
}


QppWebsocket.java

package com.qpp.websocketPush;

import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.ServerHandshake;

import com.qpp.QPPApplication;
import com.qpp.http.XHLog;
import com.qpp.util.NetworkManagement;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class QppWebsocket extends WebSocketClient {

	private Context context;
	private static QppWebsocket websocket;
	public static boolean Websocket_exit = false;
	public boolean is_conn = false;

	public QppWebsocket(URI serverUri, Draft draft, Context context) {
		super(serverUri, draft);
		this.context = context;
	}

	public QppWebsocket(URI serverURI) {
		super(serverURI);
	}

	public static QppWebsocket webSocket(URI serverUri, Draft draft,
			Application context) {
		if (websocket != null) {
			websocket.close();
			websocket = null;
		}
		if (websocket == null) {
			synchronized (QppWebsocket.class.getName()) {
				if (websocket == null) {
					websocket = new QppWebsocket(serverUri, draft, context);
				}
			}
		}
		return websocket;
	}

	@Override
	public void onOpen(ServerHandshake handshakedata) {
		System.out.println("opened connection");
		is_conn = true;
		// if you plan to refuse connection based on ip or httpfields
		// overload:onWebsocketHandshakeReceivedAsClient

	}
<span style="white-space:pre">	</span>//接受到消息时处理
	@Override
	public void onMessage(String message) {
		System.out.println("received: " + message);
		Intent intent = new Intent();
		intent.setAction("com.qpbox");
		Log.e("=========", "走没走");
		if (message instanceof String) {
			intent.putExtra("msg", message);
		} else if (message instanceof Serializable) {
			Serializable s = (Serializable) message;
			intent.putExtra("msg", s);
		}
		context.sendOrderedBroadcast(intent, null); // 有序广播发送
		// Toast.makeText(context, "发送广播成功", Toast.LENGTH_SHORT).show();

	}

	@Override
	public void onFragment(Framedata fragment) {
		System.out.println("received fragment: "
				+ new String(fragment.getPayloadData().array()));
	}
<span style="white-space:pre">	</span>//websocket 断开时处理
	@Override
	public void onClose(int code, String reason, boolean remote) {
		// The codecodes are documented in class
		// org.java_websocket.framing.CloseFrame
		is_conn = false;
		System.out.println("Connection closed by "
				+ (remote ? "remote peer" : "us"));
<span style="white-space:pre">		</span>//重连
		conn();

		if (Websocket_exit) {
		}

	}
<span style="white-space:pre">	</span>//websocket有错误时处理
	@Override
	public void onError(Exception ex) {
		ex.printStackTrace();
		// if the error is fatal then onClose will be called additionally
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
			XHLog.e("!!!!!!!", "XXXXXXXXXXXXXXXXXXXXXXX");
			conn();
		}
	};
<span style="white-space:pre">	</span>//重连方法
	public synchronized void conn() {
		if (!NetworkManagement.isNetworkAvailable(QPPApplication.context)) {
			handler.sendEmptyMessageDelayed(0, 5000);
		} else {
			try {
				URI uri = new URI("http://mpp.7pa.com:9503");
				Draft_17 draft = new Draft_17();
				QPPApplication.websocket = QppWebsocket.webSocket(uri,
						new Draft_17(), QPPApplication.context);
				QPPApplication.websocket.connectBlocking();
				int size = msgs.size();
				for (int i = 0; i < size; i++) {
					sendMsg(msgs.get(i));
				}
				msgs.removeAll(msgs);
			} catch (Exception e) {
				// TODO: handle exception
				handler.sendEmptyMessageDelayed(0, 5000); //每5秒重连一次
				e.printStackTrace();
			}
		}
	}

	private List<String> msgs = new ArrayList<String>();

	// 客户端发送消息
	public synchronized void sendMsg(String string) {
		if (QPPApplication.websocket.is_conn)
			QPPApplication.websocket.send(string);
		else {
			if (msgs.indexOf(string) < 0)
				msgs.add(string);
		}
	}
<span style="white-space:pre">	</span>//重新websocket的连接的方法  使用标签  is_conn  true表示已经连接 不会调用重连的方法
	@Override
	public boolean connectBlocking() throws InterruptedException {
		// TODO Auto-generated method stub
		if (is_conn)
			return is_conn;
		return super.connectBlocking();
	}
}

在Application中初始化 并连接

// websocket
		try {
			uri = new URI("服务器ip或者域名"); //例如:http://rdp.7wa.com:5503
			Draft_17 draft = new Draft_17();
			websocket = QppWebsocket.webSocket(uri, new Draft_17(), this);
			Field field = websocket.getClass().getDeclaredField("engine");
			field.set(websocket, new MyWebSocketImpl(websocket, draft));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


清单文件要记得给广播进行注册

  <!-- websocket -->
         <receiver 
            android:name="com.qpp.websocketPush.ClientReceiver" 
            >
            <intent-filter android:priority="1000"
                >
                <action android:name="com.qpbox"/>
            </intent-filter>
        </receiver>





如果是要用户登录时客户端发送消息到服务器后服务器对登录用户进行针对推送 


在登录成功的方法里调用

QPPApplication.websocket.connectBlocking();
QPPApplication.websocket.sendMsg(map_2_json(login("14778327", "0", "62236824340")));

客户端发送什么唯一标识来给服务端 请行约定好即可。 我这里是推荐手机标识符+时间戳+随机数;




如果有更多优化会继续更新的。代码全在这里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值