HZhoog

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在实施项目的过程中,一个项目一般是不会只是架构在一个服务器上,针对项目的各个部分分布在各自独立的服务器中。

例如手机网游的服务器架构:

     

其中架构这些服务器是一个复杂且技术含量相当高的工作,其中各个服务器之间的通信是一个很重要的部分,登录服务器与游戏服务器,log服务器之间采用socket通信。

而GM服务器与游戏服务器之间的通信科采用Http通信。本文主要介绍GM服务器与游戏服务器之间的跨服通信:

以GM服务器获取游戏服务器中角色的信息的过程为例。

游戏服务器中执行查找角色并返回角色信息的类和方法为:PlayerController.getPlayerInfo(long uid);

那么GM服务器只需通过PostCall(String serverName, String className, String methodName, Map<ClassType,Value> params);方法即可调用游戏服务器的业务逻辑处理.PostCall的过程通过配置表读取serverName的地址,并将类名,方法名和参数名通过ObjectOutStream读到流中发送对应服务器中并接受服务器返回的Object。

PostCall具体实现如下:

View Code
 1         HttpURLConnection conn = null;
 2         ObjectOutputStream os = null;
 3         ObjectInputStream in=null;
 4         try {
 5             String path = GmtoolXml.getInstance().getServerPath(server);
 6             System.out.println("connect server: " + server + "  :   " + path);
 7             List<Map> params = GetParamBuffer();
 8 
 9             URL url = new URL(path);
10             conn = (HttpURLConnection) url.openConnection();
11             conn.setRequestMethod("POST");
12             conn.setReadTimeout(2000);    
13             conn.setDoOutput(true);
14             
15             ByteArrayOutputStream oss = new ByteArrayOutputStream();
16             os = new ObjectOutputStream(oss);
17             os.writeUTF(className);
18             os.writeUTF(methodName);
19             os.write(params.size());
20             for (int i = 0; i < params.size(); i++) {
21                 Map param = (Map) params.get(i);
22                 Object key = param.keySet().toArray()[0];
23                 os.writeObject(key);
24                 os.writeObject(param.get(key));
25             }
26             os.flush();
27 
28             OutputStream outStrm = conn.getOutputStream();
29             outStrm.write(oss.toByteArray());
30 
31             if (conn.getResponseCode() == 500) {
32                 // DataInputStream di = new
33                 // DataInputStream(conn.getInputStream());
34                 // System.out.println(di.readUTF());
35                 return null;
36             } else {
37                 in = new ObjectInputStream(conn.getInputStream());
38                 return in.readObject();
39             }
40         } catch (Exception ex) {
41             try {
42                 in.close();
43                 os.close();
44             } catch (IOException e) {
45                 e.printStackTrace();
46             }
47             conn.disconnect();
48             ex.printStackTrace();
49             Logger.getLogger(Net.class.getName()).log(Level.SEVERE, null, ex);
50             return null;
51         } finally {
52             try {
53                 in.close();
54                 os.close();
55             } catch (IOException e) {
56                 e.printStackTrace();
57             }
58             conn.disconnect();
59         }

至于游戏服务如何来接受和处理GM服务器传递的数据流,你可以使用Netty做架构,启用一个端口用来监听来自GM服务器的请求,解析数据,并执行对应的方法。

以下是我解析来自GM服务器的数据流,并执行对应方法的代码:

View Code
 1 public void exec(HttpRequest request, HttpResponse response) {
 2         // TODO Auto-generated method stub
 3         ByteArrayOutputStream bos = null;
 4         ObjectOutputStream oos = null;
 5         try {
 6             ChannelBuffer cb = request.getContent();
 7             byte[] b = cb.array();
 8             ByteArrayInputStream bis = new ByteArrayInputStream(b);
 9             ObjectInputStream data = new ObjectInputStream(bis);
10             String className = data.readUTF();
11             String methodName = data.readUTF();
12             int count = data.read();
13             Class c = Class.forName(className);
14             //#debug
15             System.out.println(className + "." + methodName);
16             List<Class> cl = new ArrayList<Class>();
17             List<Object> vl = new ArrayList<Object>();
18             for (int i = 0; i < count ; i++) {
19                 cl.add((Class) data.readObject());
20                 vl.add(data.readObject());
21             }
22             Class[] cls = new Class[cl.size()];
23             cl.toArray(cls);
24             String mk = toMethodKey(className, methodName, cls);
25             Method m = methods.get(mk);
26             if (m == null) {
27                 m = c.getMethod(methodName, cls);
28                 methods.put(mk, m);
29             }
30             Object[] values = new Object[vl.size()];
31             vl.toArray(values);
32             Object o = m.invoke(c, values);
33             bos = new ByteArrayOutputStream();
34             oos = new ObjectOutputStream(bos);
35             oos.writeObject(o);
36             oos.flush();
37             response.getContent().writeBytes(bos.toByteArray());
38             cl.clear();
39             vl.clear();
40         } catch (Exception e) {
41             e.printStackTrace();
42             try {
43                 response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);//.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
44                 bos = new ByteArrayOutputStream();
45                 DataOutputStream dos = new DataOutputStream(bos);
46                 dos.writeUTF(e.getClass() + "." + e.getMessage());
47                 bos.flush();
48                 response.getContent().writeBytes(bos.toByteArray());
49                 bos.close();
50             } catch (IOException e1) {
51                 // TODO Auto-generated catch block
52                 e1.printStackTrace();
53             }
54         } finally {
55             if (oos != null)
56                 try {
57                     oos.close();
58                 } catch (IOException e) {
59                     // TODO Auto-generated catch block
60                     e.printStackTrace();
61                 }
62         }
63     }

本人技术水平不足,希望各位朋友予以指点,共同进步,Eamil:zhong678*yeah.net , QQ:982925115 

posted on 2013-01-13 14:26  HZhoog  阅读(2470)  评论(0编辑  收藏  举报