提示: 因为工程稍微有点大对我个人来说,所以可能在某些方面讲的不清楚或逻辑性不够强,如果有问题请@我。
原工程:https://github.com/LineChen/
五、转发信息
因为客户端和服务器是保持长连接的,所以可以根据用户Id得到用户的会话session,得到session就可以发送消息。
对于聊天,主要分聊天双方都在线和一方离线的情况。都在线的情况好办,直接转发;一方离线时,需要在数据库中保存离线消息,等到离线好友登录时会发送给ta。保存离线消息需要注意的是,要根据消息类型做相应的处理(文本消息、语音消息、图片消息)。
/**
* 发送信息给单个用户
*
* @param moMoMsg
* @param getterId
*/
private void sendMsgToUser(iMoMoMsg moMoMsg, String getterId) {
if (ManageClientSession.isContainsId(getterId)) {
ManageClientSession.getSession(getterId).write(moMoMsg);
// System.out.println(“转发成功..”);
} else {
SqlModel model = new SqlModel();
if (!model.isTableExists(“mc_” + getterId))// “mc_” + userId
model.createCacheTable(getterId);// 创建缓存数据库
MsgDb msgDb = MsgTranceUtil.getInstance().Trance_Net2Db(moMoMsg);
if (model.insertCacheMsg(msgDb, getterId)) {
// System.out.println(“缓存成功”);
} else {
// System.out.println(“缓存失败”);
}
}
}
下面是存储在数据库的离线消息和发送的消息转化类:
package com.imomo_msg;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.server_utils.FileTools;
import com.server_utils.StaticValues;
/**
* 消息包转换工具
*
* @author Administrator
*
*/
public class MsgTranceUtil {
public static MsgTranceUtil getInstance() {
return new MsgTranceUtil();
}
/**
* 数据库存数消息转化为网络传输消息
*
* @param msgDb
* @return
*/
public iMoMoMsg Trance_Db2Net(MsgDb msgDb) {
iMoMoMsg moMsg = new iMoMoMsg();
switch (msgDb.msgType) {
case iMoMoMsgTypes.CHATING_TEXT_MSG:
moMsg.symbol = ‘+‘;
moMsg.msgJson = msgDb.msgJson;
break;
case iMoMoMsgTypes.CHATING_IMAGE_MSG:
JSONObject json = JSON.parseObject(msgDb.msgJson);
moMsg.symbol = ‘-‘;
String imagePath = json.getString(MsgKeys.imagePath);
moMsg.msgBytes = FileTools.getInstance().getMultyFileBytes(
imagePath);
json.remove(MsgKeys.imagePath);
moMsg.msgJson = json.toJSONString();
//删除本地缓存图片
FileTools.getInstance().deleteFile(imagePath);
break;
case iMoMoMsgTypes.CHATING_VOICE_MSG:
moMsg.symbol = ‘-‘;
JSONObject json2 = JSON.parseObject(msgDb.msgJson);
String voicePath = json2.getString(MsgKeys.voicePath);
moMsg.msgBytes = FileTools.getInstance().getMultyFileBytes(
voicePath);
json2.remove(MsgKeys.voicePath);
moMsg.msgJson = json2.toJSONString();
FileTools.getInstance().deleteFile(voicePath);
break;
case iMoMoMsgTypes.ADD_FRIEND:
moMsg.symbol = ‘+‘;
moMsg.msgJson = msgDb.msgJson;
break;
case iMoMoMsgTypes.RESET_HEAD:
JSONObject resetHeadjson = JSON.parseObject(msgDb.msgJson);
moMsg.symbol = ‘-‘;
String headPath = resetHeadjson.getString(MsgKeys.imagePath);
moMsg.msgBytes = FileTools.getInstance().getMultyFileBytes(
headPath);
resetHeadjson.remove(MsgKeys.imagePath);
moMsg.msgJson = resetHeadjson.toJSONString();
//删除本地缓存图片
FileTools.getInstance().deleteFile(headPath);
break;
}
return moMsg;
}
/**
* 网络消息转化为数据库存储消息
*
* @param moMsg
* @return
*/
public MsgDb Trance_Net2Db(iMoMoMsg moMsg) {
MsgDb msgDb = new MsgDb();
JSONObject json = JSON.parseObject(moMsg.msgJson);
int msgtype = json.getIntValue(MsgKeys.msgType);
switch (msgtype) {
case iMoMoMsgTypes.CHATING_TEXT_MSG:
break;
case iMoMoMsgTypes.CHATING_IMAGE_MSG:
String imagePath = StaticValues.MSG_CACHE_IMA_P_PATH
+ json.getString(MsgKeys.userId) + "_"
+ System.currentTimeMillis() + ".png";
FileTools.getInstance().saveMultyFile(imagePath, moMsg.msgBytes);
json.put(MsgKeys.imagePath, imagePath);
break;
case iMoMoMsgTypes.CHATING_VOICE_MSG:
String voicePath = StaticValues.MSG_CACHE_VOI_P_PATH
+ json.getString(MsgKeys.userId) + "_"
+ System.currentTimeMillis() + ".amr";
FileTools.getInstance().saveMultyFile(voicePath, moMsg.msgBytes);
json.put(MsgKeys.voicePath, voicePath);
break;
case iMoMoMsgTypes.ADD_FRIEND:
// String headPath = StaticValues.HEAD_P_PATH
// + json.getString(MsgKeys.userId) + “.png”;
// json.put(MsgKeys.imagePath, headPath);
break;
case iMoMoMsgTypes.RESET_HEAD:
String headPath = StaticValues.MSG_CACHE_IMA_P_PATH
+ json.getString(MsgKeys.userId) + "_"
+ System.currentTimeMillis() + ".png";
FileTools.getInstance().saveMultyFile(headPath, moMsg.msgBytes);
json.put(MsgKeys.imagePath, headPath);
break;
}
msgDb.msgType = msgtype;
msgDb.msgJson = json.toJSONString();
return msgDb;
}
}
然后是转发离线消息:
/**
* 转发离线消息
*
* @param session
* @param userId
* @param model
*/
private void sendCacheMsg(IoSession session, String userId, SqlModel model) {
if (model.isTableExists(“mc_” + userId)) {
if (model.getMsgCount(userId) > 0) {
// 说明有离线消息
List list = model.getCacheMsgs(userId);
for (MsgDb msgDb : list) {
iMoMoMsg moMsg = MsgTranceUtil.getInstance().Trance_Db2Net(
msgDb);
session.write(moMsg);
}
// 清空数据库离线文件
model.clearMsgCache(userId);
}
}
}
原文地址:http://blog.csdn.net/u011102153/article/details/46670517