首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

网络游戏服务器架构研究(-)代理服务器的简略实践

2013-11-19 
网络游戏服务器架构研究(-)代理服务器的简单实践网络游戏的服务器框架中,通常需要代理服务器ProxyServer来

网络游戏服务器架构研究(-)代理服务器的简单实践
网络游戏的服务器框架中,通常需要代理服务器ProxyServer来解决高并发的请求。
目前实现了一个很简单代理服务器,没有考虑高并发的问题,只是实现了从客户端、代理服务器和游戏服务器的简单通信。
从客户端发送数据,经过代理服务器转发,到达游戏服务器
游戏服务器反射数据到代理服务器,后者在传递给客户端;

1. 负责接收来自客户端的消息
2. 负责转发来自服务器的消息
3. 管理客户端连接
   增加、删除客户端连接
   每个连接唯一标记
4. 管理服务器端连接
   根据serverid管理服务器端连接;

目前存在很多需要后续完善的地方
1. 客户端连接的管理,
       代理服务器接收到客户端连接后,产生随机的clientid, 构造出ClientConnectIon, 并且保存在map中待用
       目前的clientid是固定的
       所以目前还不支持多个客户端连接
       当然还涉及到客户端的断开的管理,从map中移除相关的连接;

2.   代理服务器的并发能力差
       后续考虑采用netty 或者mina来解决
       关键点是当客户端连接上来后,需要产生随机clientid, 保存到map中
       从游戏服务器下来的数据,能够找到正确clientid的客户端连接
       将数据传到正确的客户端中
       netty4.x的版本貌似比较复杂,和3.5的版本比较,多了很多新的类和接口,需要些时间来学习;

3.   数据包的封装
      一般都有数据包的封装,包头+包体;
      包头比较包括TAG,bodylen,cmdtype等

代理服务器先这样,后面的关于游戏服务器的框架更加重要;

package net.tuolian.main;import net.tuolian.client.Client;import net.tuolian.proxy.SocketProxy;import net.tuolian.server.GameServer;public class TestAll {public static void main(String[] args) {// boot game servernew GameServer(8080);try {Thread.sleep(1000 * 3);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}// boot socket proxySocketProxy proxy = new SocketProxy(8081);proxy.connectToLogicServer("localhost", 8080);try {Thread.sleep(1000 * 3);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}// start clientnew Client("localhost", 8081).doTest();}}


package net.tuolian.server;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.net.UnknownHostException;import org.apache.log4j.LogManager;import org.apache.log4j.Logger;public class GameServer implements Runnable{ServerSocket serverSocket = null;Logger logger = LogManager.getLogger(GameServer.class);public GameServer(int port){try {serverSocket = new ServerSocket(port);logger.info("GameServer initialized");new Thread(this).start();} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void run(){while(true){try {Socket socket = serverSocket.accept();logger.info("client accepted: " + socket.getRemoteSocketAddress());new MyClient(socket);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}public void doTest(){new Thread(this).start();}class MyClient extends Thread{DataInputStream dis = null;DataOutputStream dos = null;public MyClient(Socket socket){try {dis = new DataInputStream(socket.getInputStream());dos = new DataOutputStream(socket.getOutputStream());start();logger.info("MyClient init");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void run(){while(true){byte[] tmp =new byte[1024];try {if(dis.available()>0){dis.read(tmp);logger.info("recv data from proxy len: " + new String(tmp));}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//int cmd = 1;try {dos.write("this is echo from gameserver: ".getBytes());dos.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}


package net.tuolian.proxy;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.net.UnknownHostException;import java.util.HashMap;import java.util.Random;import org.apache.log4j.LogManager;import org.apache.log4j.Logger;public class SocketProxy implements Runnable{Logger logger = LogManager.getLogger(SocketProxy.class);ServerSocket sSocket = null;public SocketProxy(int port){logger.info("SocketProxy init");try {sSocket = new ServerSocket(port);new Thread(this).start();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void run(){while(true){Socket client = null;try {client = sSocket.accept();if(client!=null){logger.info("accept client ");// new clientconnint clientId = new Random().nextInt();ClientConnection clientConn = new ClientConnection(this, clientId,client);addClientConn(clientConn, 1);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void connectToLogicServer(String ip, int port){logger.info("connectToLogicServer");Socket socket;try {socket = new Socket(ip, port);ServerConnection serverConn =new ServerConnection(this, 1, socket);addServerConn(serverConn, 1);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}private HashMap<Integer,ClientConnection> clientConns = new HashMap<Integer, ClientConnection>();private HashMap<Integer,ServerConnection> serverConns = new HashMap<Integer, ServerConnection>();public void addClientConn(ClientConnection clientConn, int clientId) {// TODO Auto-generated method stubclientConns.put(clientId, clientConn);}public ClientConnection getClientConn(int clientId){return clientConns.get(clientId);}public void removeClientConn(int clientId){clientConns.remove(clientId);}public void addServerConn(ServerConnection serverConn, int serverid) {// TODO Auto-generated method stubserverConns.put(serverid, serverConn);}public ServerConnection getServerConn(int serverid){return serverConns.get(serverid);}public void removeServerConn(int serverId){serverConns.remove(serverId);}}


package net.tuolian.proxy;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;import org.apache.log4j.LogManager;import org.apache.log4j.Logger;public class ClientConnection implements Runnable {Logger logger = LogManager.getLogger(ClientConnection.class);SocketProxy proxy = null;int clientId = 0;Socket client = null;DataInputStream dis = null;DataOutputStream dos = null;public ClientConnection(SocketProxy proxy, int clientId, Socket socket) {logger.info("ClientConnection init");this.proxy = proxy;this.clientId = clientId;this.client = socket;try {dis = new DataInputStream(socket.getInputStream());dos = new DataOutputStream(socket.getOutputStream());new Thread(this).start();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void run(){while(true){logger.info("run" );try {byte[] rawData = new byte[1024];while(dis.available()>0){logger.info("recv client data: " );dis.read(rawData);String msg = new String(rawData);logger.info(msg);int serverid = 1;ServerConnection severConn = proxy.getServerConn(serverid);if(severConn!=null){severConn.sendData(rawData);}}Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void sendDataBack(byte[] data){logger.info(new String(data));try {dos.write(data);dos.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}


package net.tuolian.proxy;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;import org.apache.log4j.LogManager;import org.apache.log4j.Logger;public class ServerConnection implements Runnable {Logger logger = LogManager.getLogger(ServerConnection.class);SocketProxy proxy = null;int serverId = 0;Socket client = null;DataInputStream dis = null;DataOutputStream dos = null;public ServerConnection(SocketProxy proxy, int serverId, Socket socket) {// TODO Auto-generated constructor stublogger.info("ServerConnection init");this.proxy = proxy;this.serverId = serverId;this.client = socket;try {dis = new DataInputStream(socket.getInputStream());dos = new DataOutputStream(socket.getOutputStream());new Thread(this).start();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void run(){while(true){try {byte[] rawData = new byte[1024];while(dis.available()>0){dis.read(rawData);logger.info(new String(rawData));// send to serverId;int clientId = 1;ClientConnection clientConn = proxy.getClientConn(clientId);if(clientConn!=null){clientConn.sendDataBack(rawData);}}Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void sendDataBack(byte[] data){try {dos.write(data);dos.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void sendData(byte[] data) {// TODO Auto-generated method stubtry {dos.write(data);dos.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

package net.tuolian.client;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import org.apache.log4j.LogManager;import org.apache.log4j.Logger;public class Client implements Runnable{Logger logger = LogManager.getLogger(Client.class);public Client(){}Socket socket = null;DataInputStream dis = null;DataOutputStream dos = null;public Client(String ip, int port){try {socket = new Socket(ip, port);dis = new DataInputStream(socket.getInputStream());dos = new DataOutputStream(socket.getOutputStream());logger.info("connect to proxy server success");} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void run(){while(true){byte[] tmp =new byte[1024];try {if(dis.available()>0){dis.read(tmp);logger.info(new String(tmp));}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {dos.write("hello from client ".getBytes());dos.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void doTest(){new Thread(this).start();}}

热点排行