一、概述:
1、把发送者发送的信息全部封装在blockqueue队列里,然后使用connManager把队列里的信息取出,分发出去
2、原理图:
二、实现:
/**
* @描述 使用socket实现长连接
* @项目名称 App_Chat
* @包名 com.android.chat.utils
* @类名 TcpUtil
* @author chenlin
* @date 2012年6月26日 下午4:06:43
* @version 1.0
*/
public class ConnManager {
protected static final int STATE_FROM_SERVER_OK = 0;
private static String dsName = "192.168.31.239";
private static int dstPort = 10002;
private static Socket socket;
//队列,封装发送的信息
private static ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(8);
private static ConnManager instance;
private ConnManager() {
}
public static ConnManager getInstance() {
if (instance == null) {
synchronized (ConnManager.class) {
if (instance == null) {
instance = new ConnManager();
}
}
}
return instance;
}
/**
* 连接
*
* @return
*/
public boolean connect(final Handler handler) {
if (socket == null || socket.isClosed()) {
new Thread(new Runnable() {
@Override
public void run() {
try {
socket = new Socket(dsName, dstPort);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException("连接错误: " + e.getMessage());
}
new Thread(new RequestWorker()).start();
try {
// 输入流,为了获取客户端发送的数据
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = is.read(buffer)) != -1) {
final String result = new String(buffer, 0, len);
Message msg = Message.obtain();
msg.obj = result;
msg.what = STATE_FROM_SERVER_OK;
handler.sendMessage(msg);
}
} catch (IOException e) {
throw new RuntimeException("getInputStream错误: " + e.getMessage());
}
}
}).start();
}
return true;
}
/**
* 连接
*
* @return
*/
public void connect() {
if (socket == null || socket.isClosed()) {
try {
socket = new Socket(dsName, dstPort);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException("连接错误: " + e.getMessage());
}
try {
// 输入流,为了获取客户端发送的数据
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = is.read(buffer)) != -1) {
final String result = new String(buffer, 0, len);
if (mListener !=null) {
mListener.pushData(result);
}
}
} catch (IOException e) {
throw new RuntimeException("getInputStream错误: " + e.getMessage());
}
}
}
/**
* 添加请求
* @param content
*/
public void putRequest(String content) {
try {
queue.put(content);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 发送信息
*
* @param auth
*/
public void sendAuth(String auth) {
OutputStream os = null;
try {
if (socket != null) {
os = socket.getOutputStream();
os.write(auth.getBytes());
os.flush();
}
} catch (IOException e) {
throw new RuntimeException("发送失败:" + e.getMessage());
}
}
/**
* 关闭连接
*/
public void disConnect() {
if (socket != null && !socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {
throw new RuntimeException("关闭异常:" + e.getMessage());
}
socket = null;
}
}
public class RequestWorker implements Runnable{
@Override
public void run() {
OutputStream os = null;
try {
if (socket != null) {
os = socket.getOutputStream();
//take是个阻塞式方法,所以必须是用while(true)
while(true){
String content = queue.take();
os.write(content.getBytes());
os.flush();
}
}
} catch (IOException e) {
throw new RuntimeException("发送失败:" + e.getMessage());
} catch (InterruptedException e) {
throw new RuntimeException("信息被中断:" + e.getMessage());
}
}
}
public interface ConnectionListener{
void pushData(String str);
}
private ConnectionListener mListener;
public void setConnectionListener(ConnectionListener listener){
this.mListener = listener;
}
}