Androidに基づいて開発されたチャットルームChatRoom 1.0:(二)メッセージ処理メカニズム
本アプリケーションはsocket通信メカニズムに基づいており、クライアントとサーバ側がメッセージのインタラクションを行う際にメッセージに識別行を追加し、メッセージのタイプ(登録、ログイン、終了、文字メッセージ、音声メッセージ)を識別し、異なるメッセージタイプに応じて異なるデータ処理を行う.一対のマルチチャットであるため、サーバ側ではすべてのオンラインユーザー情報がキャッシュされ、各ユーザーの顔データが含まれている.ここでは、通常のxmlファイルを使用して、データベースとしてユーザの登録情報を保存します.次に、クライアントとサーバ側のメッセージ処理の概略的な流れを列挙します.
サーバ側:サーバ側がオンになると、socketリクエストが送信されると、スレッドがリクエストを処理します.まず識別行を読み出し,メッセージのタイプを判断し,メッセージのタイプに応じて異なる処理を行う.同時に、サーバ側ですべてのオープンスレッドがコレクションでキャッシュされるため、1対以上の送信が必要なメッセージに対してそのコレクションがループし、すべてのオンラインクライアントがメッセージを受信できることを保証します.
クライアント:socket接続が確立されると、メッセージを待つ処理が開始され、サーバ側と同様に、まずデータ行を読み出し、メッセージタイプを判断し、異なるタイプに応じて異なるデータ処理を行う.
完全なリソースコードのダウンロードアドレス:http://download.csdn.net/detail/jiangliloveyou/6457969
サーバ側:サーバ側がオンになると、socketリクエストが送信されると、スレッドがリクエストを処理します.まず識別行を読み出し,メッセージのタイプを判断し,メッセージのタイプに応じて異なる処理を行う.同時に、サーバ側ですべてのオープンスレッドがコレクションでキャッシュされるため、1対以上の送信が必要なメッセージに対してそのコレクションがループし、すべてのオンラインクライアントがメッセージを受信できることを保証します.
public class ChatServer {
private ExecutorService executorService;//
private int port;//
private boolean quit = false;//
private ServerSocket server;
private List<SocketTask> taskList = new ArrayList<SocketTask>();// socket
public ChatServer(int port) {
this.port = port;
// , (cpu *50)
executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
.availableProcessors() * 50);
}
/**
* ,
*/
public void quit() {
this.quit = true;
try {
for (SocketTask tast : taskList) {
tast.input.close();
}
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
*
* @throws Exception
*/
public void start() throws Exception {
server = new ServerSocket(port);
new Thread(new Runnable() {
public void run() {
while (!quit) {
try {
System.out.println(" socket ");
Socket socket = server.accept();
// ,
SocketTask newTask = new SocketTask(socket);
taskList.add(newTask);
executorService.execute(newTask);
System.out.println(" socket ");
} catch (Exception e) {
System.out.println(" ! ");
}
}
}
}).start();
}
/**
* ,
*
* @author Administrator
*/
private final class SocketTask implements Runnable {
private Socket s;
private DataInputStream input;
private DataOutputStream output;
private User curUser;
public SocketTask(Socket socket) {
s = socket;
try {
input = new DataInputStream(s.getInputStream());
output = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
*
* @param msg
* @param datas
*/
public void sendMsg(String msg, byte[] datas) {
try {
if (null != msg) {
output.writeUTF(msg);
}
if (null != datas) {
output.writeInt(datas.length);
output.write(datas, 0, datas.length);
}
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (true) {
String msgCtn = input.readUTF();
if (msgCtn.startsWith(ContentFlag.REGOSTER_FLAG)) { //
String name = msgCtn.substring(
ContentFlag.REGOSTER_FLAG.length()).trim();
String userId = XmlParser.saveUserInfo(name, input);
System.out.println(" id" + userId);
this.sendMsg(userId, null);
taskList.remove(this);
break;
} else if (msgCtn.startsWith(ContentFlag.ONLINE_FLAG)) { //
//
String loginId = msgCtn.substring(
ContentFlag.ONLINE_FLAG.length()).trim();
System.out.println(" ID:" + loginId);
curUser = XmlParser.queryUserById(Integer
.parseInt(loginId));
//
int imgNums = taskList.size() - 1; //
System.out.println(" :" + taskList.size());
this.output.writeInt(imgNums);
if (imgNums > 0) {
for (SocketTask task : taskList) {
if (task != this) {
long userId = task.curUser.getId();
File img = new File("image\\"
+ XmlParser.queryUserById(userId)
.getImg());
FileInputStream flleInput = new FileInputStream(
img);
byte data[] = StreamTool
.readStream(flleInput);
this.sendMsg(String.valueOf(userId), data);
}
}
}
//
File imgFile = new File("image\\" + curUser.getImg());
FileInputStream flleInput = new FileInputStream(imgFile);
byte datas[] = StreamTool.readStream(flleInput);
String send_person = curUser.getName(); //
String send_ctn = " !"; //
String send_date = FormatDate.getCurDate(); //
StringBuilder json = new StringBuilder();
json.append("[{");
json.append("id:").append(loginId)
.append(",send_person:\"").append(send_person)
.append("\",send_ctn:\"").append(send_ctn)
.append("\",send_date:\"").append(send_date);
json.append("\"}]");
System.out.println("json:" + json);
// Socket
for (SocketTask tast : taskList) {
System.out.println(" ");
tast.sendMsg(
ContentFlag.ONLINE_FLAG
+ this.curUser.getId(), null);
tast.sendMsg(json.toString(), datas);
}
flleInput.close();
} else if (msgCtn.startsWith(ContentFlag.OFFLINE_FLAG)) { //
taskList.remove(this);
// ID
String id = msgCtn.substring(
ContentFlag.OFFLINE_FLAG.length()).trim();
StringBuilder json = new StringBuilder();
json.append("[{");
json.append("id:").append(this.curUser.getId())
.append(",send_person:\"")
.append(this.curUser.getName())
.append("\",send_ctn:\"").append(" !")
.append("\",send_date:\"")
.append(FormatDate.getCurDate());
json.append("\"}]");
for (SocketTask tast : taskList) {
if (tast != this) {
tast.sendMsg(ContentFlag.OFFLINE_FLAG + id,
null);
tast.sendMsg(json.toString(), null);
}
}
System.out.println(" " + curUser.getName() + " !, "
+ Thread.currentThread().getName());
break;
} else if (msgCtn.startsWith(ContentFlag.RECORD_FLAG)) { //
String filename = msgCtn
.substring(ContentFlag.RECORD_FLAG.length());
long recordTime = input.readLong();
byte datas[] = StreamTool.readStream(input);
StringBuilder json = new StringBuilder();
json.append("[{");
json.append("id:").append(this.curUser.getId())
.append(",send_person:\"")
.append(this.curUser.getName())
.append("\",send_ctn:\"")
.append(recordTime / 1000 + "\'")
.append("\",send_date:\"")
.append(FormatDate.getCurDate())
.append("\",recordTime:\"").append(recordTime);
json.append("\"}]");
System.out.println("json:" + json);
// Socket
for (SocketTask tast : taskList) {
tast.sendMsg(ContentFlag.RECORD_FLAG + filename,
null);
tast.sendMsg(json.toString(), datas);
}
} else { //
StringBuilder json = new StringBuilder();
json.append("[{");
json.append("id:").append(this.curUser.getId())
.append(",send_person:\"")
.append(this.curUser.getName())
.append("\",send_ctn:\"").append(msgCtn)
.append("\",send_date:\"")
.append(FormatDate.getCurDate());
json.append("\"}]");
for (SocketTask tast : taskList) {
tast.sendMsg(json.toString(), null);
}
}
}
} catch (Exception e) {
taskList.remove(this);
System.out.println(" " + Thread.currentThread().getName());
} finally {
try {
if (null != input)
input.close();
if (null != output)
output.close();
if (null != s)
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
クライアント:socket接続が確立されると、メッセージを待つ処理が開始され、サーバ側と同様に、まずデータ行を読み出し、メッセージタイプを判断し、異なるタイプに応じて異なるデータ処理を行う.
public void receiveMsg(IhandleMessge handle) throws IOException {
try {
while(true){
String msgCtn = input.readUTF();
if(msgCtn.startsWith(ContentFlag.ONLINE_FLAG)){ //
String json = input.readUTF();
Message msg = parseJsonToObject(json);
byte[] datas = StreamTool.readStream(input);
Bitmap bitmap = BitmapFactory.decodeByteArray(datas, 0, datas.length);
msg.setBitmap(bitmap);
handle.handleMsg(msg);
imgMap.put(msg.getId(), bitmap);
}else if(msgCtn.startsWith(ContentFlag.OFFLINE_FLAG)){ //
String json = input.readUTF();
Message msg = parseJsonToObject(json);
msg.setBitmap(imgMap.get(msg.getId()));
handle.handleMsg(msg);
imgMap.remove(msg.getId());
}else if(msgCtn.startsWith(ContentFlag.RECORD_FLAG)){ //
String filename = msgCtn.substring(ContentFlag.RECORD_FLAG.length());
File dir = new File(Environment.getExternalStorageDirectory() + "/recordMsg/");
if(!dir.exists()) dir.mkdirs();
File file = new File(dir, filename);
String json = input.readUTF();
Message msg = parseJsonToObject(json);
msg.setRecord_path(file.getAbsolutePath());
msg.setBitmap(imgMap.get(msg.getId()));
msg.setIfyuyin(true);
handle.handleMsg(msg);
saveRecordFile(file);
}else{ //
Message msg = parseJsonToObject(msgCtn);
msg.setBitmap(imgMap.get(msg.getId()));
handle.handleMsg(msg);
}
}
} catch (Exception e) {
if (!socket.isClosed()) {
throw new IOException("fail connect to the server");
}
}
}
完全なリソースコードのダウンロードアドレス:http://download.csdn.net/detail/jiangliloveyou/6457969