conversation层(会话层)主要用于处理收发信息,当它接收到对端发送的经过网络协议规范化的信息时,会自动将信息解析后进行分类处理:
void dealmessage(NetMessag mess) {
//Netmessage就是为了保护框架而编写的网络协议,其中包括:
EMessagetype type = mess.getType();//命令类型
String action = mess.getAction();//请求响应
String para = mess.getPara();//对应参数
switch(type) {
//处理客户端请求上线
case Request_online:
server.addMap(para,this);
server.reportmessage("客户端"+ mess.getPara() + "上线");
send(new NetMessag().setType(EMessagetype.Success_online));
break;
//处理客户端下线
case Request_offline:
server.reportmessage("用户" + this.id + "已正常退出");
closed();
server.remove(id);
break;
//处理客户端请求资源
case Requset_resource:
try {
String result;
result = server.Sic.dealrescore(para , action);
send(new NetMessag().setType(EMessagetype.Response_result)
.setAction(action).setPara(result));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
break;
}
通过上面的代码段我们可以看到:在编写信息分类处理的方法时,由于该方法要处理不同类型请求,所以要不断的通过case进行分类扩容,这就导致方法很长很杂且不利于修改。为了解决这个问题,我们可以采用反射机制.
我们先做初步整理,将不同类型处理提出来写成不同的方法,:
public void dealRequestOnline(NetMessag mess) {
server.addMap(mess.getPara(),this);
server.reportmessage("客户端"+ mess.getPara() + "上线");
send(new NetMessag().setType(EMessagetype.Success_online));
}
public void dealNormal_conversation(NetMessag mess) {
server.reportmessage("来自客户端的消息: "+mess.getPara());
System.out.println("Ok");
}
public void dealRequestOffline(NetMessag mess) {
server.reportmessage("用户" + this.id + "已正常退出");
closed();
server.remove(id);
}
public void dealRequsetResource(NetMessag mess) {
try {
String result;
result = server.Sic.dealrescore(mess.getPara()mess.getAction());
send(newNetMessag().setType(EMessagetype.Response_result)
.setAction(mess.getAction())
.setPara(result));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void dealmessage(NetMessag mess) {
DealNetmessage.dealcommend(this, mess);
}
在看上面的代码段是不是就觉得整洁明了了许多,我们的dealmessage方法一下子被缩减到一行,最关键的是他的功能和自动性并没有因此受到丝毫影响。是不是有了些惊讶这个新增的DealNetmessage方法里具体发生了什么,以下便是对该方法的详解:
先要注意的一点是,我们整理后的每个方法名不是乱起的而是以“deal”+协议命令构建的:
public void dealRequestOnline(NetMessag mess) {
//该方法名以“deal”+RequestOnline(请求上线命令)组成,且每个单词首字母大写其他字母小写
server.addMap(mess.getPara(),this);
server.reportmessage("客户端"+ mess.getPara() + "上线");
send(new NetMessag().setType(EMessagetype.Success_online));
}
这样做的好处就是为了接下来反射机制调用时自动生成方法名:
import java.lang.reflect.Method;
public class DealNetmessage {
public DealNetmessage(){
}
//该方法通过传递的参数自动生成方法名以供反射机制内部调用
private static String getCommend(String name) {
StringBuffer st = new StringBuffer("deal");
String word[] = name.split("_");//取消参数中的下划线
for(int i = 0;i<word.length;i++) {//让每个单词首字母大写其他字母小写
st.append(word[i].substring(0, 1).toUpperCase());
st.append(word[i].substring(1).toLowerCase());
}
return st.toString();
}
public static void dealcommend(Object obj,NetMessag mess) {
Class<?> klass = obj.getClass();
String Methodname = getCommend(mess.getType().name());//调用生成名字的方法
Method method;
try {
//这里的参数类型肯定是我们协议类型NetMessag.class
method = klass.getMethod(Methodname, NetMessag.class);
method.invoke(obj, mess);//反射机制调用该方法
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过上面对反射机制对类内方法的调用,让我们代码更加清晰,更加利于修改,而且其功能没有受到丝毫影响,这种解决问题的方法我们可以在特定场合灵活运用。