1、sgs的AS3客户端有两个版本的alienos和sun官方的beyondo。我这里使用的是sun官方网站上的darkstar-as-client,里面的项目结构如下:
相关连接:
Sun公司开源游戏服务器Project Darkstar Server(SGS)-----AS3客户端技术详解(一)
2、服务端代码:
MainApp.java:
代码
package
net.papaya;
import java.io.Serializable;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.sgs.app.AppListener;
import com.sun.sgs.app.ClientSession;
import com.sun.sgs.app.ClientSessionListener;
public class MainApp implements Serializable, AppListener {
/**
*
*/
private static final long serialVersionUID = 1L ;
private static final Logger logger = Logger.getLogger(MainApp. class .getName());
public void initialize(Properties arg0) {
// TODO Auto-generated method stub
logger.log(Level.INFO, " 程序已经启动了... " );
}
public ClientSessionListener loggedIn(ClientSession session) {
// TODO Auto-generated method stub
return new UserClientSessionListener(session);
}
}
import java.io.Serializable;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.sgs.app.AppListener;
import com.sun.sgs.app.ClientSession;
import com.sun.sgs.app.ClientSessionListener;
public class MainApp implements Serializable, AppListener {
/**
*
*/
private static final long serialVersionUID = 1L ;
private static final Logger logger = Logger.getLogger(MainApp. class .getName());
public void initialize(Properties arg0) {
// TODO Auto-generated method stub
logger.log(Level.INFO, " 程序已经启动了... " );
}
public ClientSessionListener loggedIn(ClientSession session) {
// TODO Auto-generated method stub
return new UserClientSessionListener(session);
}
}
UserClientSessionListener.java
代码
package
net.papaya;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.sgs.app.AppContext;
import com.sun.sgs.app.ClientSession;
import com.sun.sgs.app.ClientSessionListener;
import com.sun.sgs.app.ManagedReference;
public class UserClientSessionListener implements Serializable,
ClientSessionListener {
/**
*
*/
private static final long serialVersionUID = 1L ;
private static final Logger logger = Logger.getLogger(MainApp. class .getName());
private final ManagedReference < ClientSession > sessionRef;
private final String sessionName;
public UserClientSessionListener(ClientSession session)
{
if (session == null )
{
throw new NullPointerException( " session is null " );
}
sessionRef = AppContext.getDataManager().createReference(session);
sessionName = session.getName();
logger.log(Level.INFO, " User {0} logger in " ,sessionName);
}
public ClientSession getSession()
{
return sessionRef.get();
}
public void disconnected( boolean arg0) {
// TODO Auto-generated method stub
}
public void receivedMessage(ByteBuffer message) {
// TODO Auto-generated method stub
this .getSession().send(message);
}
}
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.sgs.app.AppContext;
import com.sun.sgs.app.ClientSession;
import com.sun.sgs.app.ClientSessionListener;
import com.sun.sgs.app.ManagedReference;
public class UserClientSessionListener implements Serializable,
ClientSessionListener {
/**
*
*/
private static final long serialVersionUID = 1L ;
private static final Logger logger = Logger.getLogger(MainApp. class .getName());
private final ManagedReference < ClientSession > sessionRef;
private final String sessionName;
public UserClientSessionListener(ClientSession session)
{
if (session == null )
{
throw new NullPointerException( " session is null " );
}
sessionRef = AppContext.getDataManager().createReference(session);
sessionName = session.getName();
logger.log(Level.INFO, " User {0} logger in " ,sessionName);
}
public ClientSession getSession()
{
return sessionRef.get();
}
public void disconnected( boolean arg0) {
// TODO Auto-generated method stub
}
public void receivedMessage(ByteBuffer message) {
// TODO Auto-generated method stub
this .getSession().send(message);
}
}
3、客户端:
客户端主类client
代码
package
net.papaya
{
import com.beyondo.sgs.client.client.ClientChannel;
import com.beyondo.sgs.client.client.ClientChannelListener;
import com.beyondo.sgs.client.client.simple.SimpleClient;
import com.beyondo.sgs.client.client.simple.SimpleClientListener;
import com.beyondo.sgs.client.impl.client.comm.ClientConnector;
import com.beyondo.sgs.util.PasswordAuthentication;
import com.beyondo.util.BeyondoByteArray;
import flash.events.EventDispatcher;
import net.papaya.event.ExecptionEvent;
import net.papaya.event.SGSEvent;
import net.papaya.event.TestMessageEvent;
public class Client extends EventDispatcher implements SimpleClientListener
{
private var _client:SimpleClient;
private var _user:PasswordAuthentication;
public function Client()
{
this ._client = new SimpleClient( this );
}
public function connect(host:String,port:String): void
{
var connectProps:Object = new Object();
connectProps[ClientConnector.HOST] = host;
connectProps[ClientConnector.PORT] = port;
this ._client.login(connectProps);
}
// 发送数据
public function send(message:String): void
{
var buf:BeyondoByteArray = new BeyondoByteArray();
buf.writeUTF(message);
this ._client.send(buf);
}
public function get passwordAuthentication():PasswordAuthentication
{
return this ._user;
}
public function set passwordAuthentication(pauth:PasswordAuthentication): void
{
this ._user = pauth;
}
public function loggedIn(): void
{
trace( " 客户端登录成功 " );
dispatchEvent( new SGSEvent(SGSEvent.LOGIN_SUCCESS));
}
public function loginFailed(reason:String): void
{
trace( " 客户端登录失败 " );
dispatchEvent( new SGSEvent(SGSEvent.LOGIN_FAILED));
}
public function exceptionThrown(err:String): void
{
trace( " 连接出错了 " );
dispatchEvent( new ExecptionEvent(err));
}
public function joinedChannel(channel:ClientChannel):ClientChannelListener
{
return null ;
}
// 接收客户端的数据
public function receivedClientMessage(message:BeyondoByteArray): void
{
var str:String = message.readSgsString();
dispatchEvent( new TestMessageEvent(TestMessageEvent.MESSAGEEVENT,str));
}
// 从新连接
public function reconnecting(): void
{
}
public function reconnected(): void
{
}
public function disconnected(graceful:Boolean, reason:String): void
{
trace( " 断开连接 " );
dispatchEvent( new SGSEvent(SGSEvent.DISCONNECTED));
}
}
}
{
import com.beyondo.sgs.client.client.ClientChannel;
import com.beyondo.sgs.client.client.ClientChannelListener;
import com.beyondo.sgs.client.client.simple.SimpleClient;
import com.beyondo.sgs.client.client.simple.SimpleClientListener;
import com.beyondo.sgs.client.impl.client.comm.ClientConnector;
import com.beyondo.sgs.util.PasswordAuthentication;
import com.beyondo.util.BeyondoByteArray;
import flash.events.EventDispatcher;
import net.papaya.event.ExecptionEvent;
import net.papaya.event.SGSEvent;
import net.papaya.event.TestMessageEvent;
public class Client extends EventDispatcher implements SimpleClientListener
{
private var _client:SimpleClient;
private var _user:PasswordAuthentication;
public function Client()
{
this ._client = new SimpleClient( this );
}
public function connect(host:String,port:String): void
{
var connectProps:Object = new Object();
connectProps[ClientConnector.HOST] = host;
connectProps[ClientConnector.PORT] = port;
this ._client.login(connectProps);
}
// 发送数据
public function send(message:String): void
{
var buf:BeyondoByteArray = new BeyondoByteArray();
buf.writeUTF(message);
this ._client.send(buf);
}
public function get passwordAuthentication():PasswordAuthentication
{
return this ._user;
}
public function set passwordAuthentication(pauth:PasswordAuthentication): void
{
this ._user = pauth;
}
public function loggedIn(): void
{
trace( " 客户端登录成功 " );
dispatchEvent( new SGSEvent(SGSEvent.LOGIN_SUCCESS));
}
public function loginFailed(reason:String): void
{
trace( " 客户端登录失败 " );
dispatchEvent( new SGSEvent(SGSEvent.LOGIN_FAILED));
}
public function exceptionThrown(err:String): void
{
trace( " 连接出错了 " );
dispatchEvent( new ExecptionEvent(err));
}
public function joinedChannel(channel:ClientChannel):ClientChannelListener
{
return null ;
}
// 接收客户端的数据
public function receivedClientMessage(message:BeyondoByteArray): void
{
var str:String = message.readSgsString();
dispatchEvent( new TestMessageEvent(TestMessageEvent.MESSAGEEVENT,str));
}
// 从新连接
public function reconnecting(): void
{
}
public function reconnected(): void
{
}
public function disconnected(graceful:Boolean, reason:String): void
{
trace( " 断开连接 " );
dispatchEvent( new SGSEvent(SGSEvent.DISCONNECTED));
}
}
}
事件类:
SGSEvent
代码
package
net.papaya.event
{
import flash.events.Event;
public class SGSEvent extends Event
{
public static const CONNECT_SUCCESS:String = " CONNECT_SUCCESS " ;
public static const DISCONNECTED:String = " SGSEvent_DISCONNECTED " ;
public static const LOGIN_SUCCESS:String = " SGSEvent_LOGIN_SUCCESS " ;
public static const LOGIN_FAILED:String = " SGSEvent_LOGIN_FAILED " ;
public function SGSEvent(type:String, bubbles:Boolean = false , cancelable:Boolean = false )
{
super (type, bubbles, cancelable);
}
}
}
{
import flash.events.Event;
public class SGSEvent extends Event
{
public static const CONNECT_SUCCESS:String = " CONNECT_SUCCESS " ;
public static const DISCONNECTED:String = " SGSEvent_DISCONNECTED " ;
public static const LOGIN_SUCCESS:String = " SGSEvent_LOGIN_SUCCESS " ;
public static const LOGIN_FAILED:String = " SGSEvent_LOGIN_FAILED " ;
public function SGSEvent(type:String, bubbles:Boolean = false , cancelable:Boolean = false )
{
super (type, bubbles, cancelable);
}
}
}
ExecptionEvent:
处理派发socket的异常
代码
package
net.papaya.event
{
import flash.events.Event;
public class ExecptionEvent extends Event
{
public static const ExecptionThrow = " ExecptionEvent_ExecptionThrow " ;
private var wrongMsg:String = "" ;
public function ExecptionEvent(wrong:String)
{
super (ExecptionEvent.ExecptionThrow, false , false );
this .wrongMsg = wrong;
}
public function get wrong():String
{
return this .wrongMsg;
}
public function set wrong(str:String): void
{
this .wrongMsg = str;
}
}
}
{
import flash.events.Event;
public class ExecptionEvent extends Event
{
public static const ExecptionThrow = " ExecptionEvent_ExecptionThrow " ;
private var wrongMsg:String = "" ;
public function ExecptionEvent(wrong:String)
{
super (ExecptionEvent.ExecptionThrow, false , false );
this .wrongMsg = wrong;
}
public function get wrong():String
{
return this .wrongMsg;
}
public function set wrong(str:String): void
{
this .wrongMsg = str;
}
}
}
SocketError
package
net.papaya.event
{
public class SocketError
{
public static const Connect_Fail:String = " Error #2031 " ;
public static const Security_error:String = " Error #2048 " ;
}
}
{
public class SocketError
{
public static const Connect_Fail:String = " Error #2031 " ;
public static const Security_error:String = " Error #2048 " ;
}
}
TestMessageEvent:处理派发接受到的数据
代码
package
net.papaya.event
{
import flash.events.Event;
public class TestMessageEvent extends Event
{
public static const MESSAGEEVENT:String = " TestMessageEvent_MESSAGEeVENT " ;
private var _msg:String = "" ;
public function TestMessageEvent(type:String,Eventmessage:String)
{
super (type, false , false );
this ._msg = Eventmessage;
}
public function get message():String
{
return this ._msg;
}
public function set message(msg:String): void
{
this ._msg = msg;
}
}
}
{
import flash.events.Event;
public class TestMessageEvent extends Event
{
public static const MESSAGEEVENT:String = " TestMessageEvent_MESSAGEeVENT " ;
private var _msg:String = "" ;
public function TestMessageEvent(type:String,Eventmessage:String)
{
super (type, false , false );
this ._msg = Eventmessage;
}
public function get message():String
{
return this ._msg;
}
public function set message(msg:String): void
{
this ._msg = msg;
}
}
}
下面是View模块:
代码
<?
xml version="1.0" encoding="utf-8"
?>
< mx:Application xmlns:mx ="http://www.adobe.com/2006/mxml" layout ="absolute" fontSize ="13" height ="200" applicationComplete ="init();" >
< mx:Script >
<![CDATA[
import net.papaya.MainApp;
private function init():void
{
MainApp.getInstance(this);
}
]]>
</ mx:Script >
< mx:Panel x ="10" y ="10" width ="270" height ="174" layout ="absolute" title ="用户登录" >
< mx:Label x ="10" y ="22" text ="用户名:" />
< mx:Label x ="10" y ="52" text ="密码:" />
< mx:TextInput x ="75" y ="20" id ="user_txt" />
< mx:TextInput x ="75" y ="50" id ="psw_txt" />
< mx:Button x ="104" y ="99" label ="登录" id ="btn_logger" />
</ mx:Panel >
< mx:TextArea x ="288" y ="10" width ="308" height ="132" id ="return_msg" />
< mx:TextInput x ="288" y ="158" width ="221" id ="send_txt" />
< mx:Button x ="517" y ="158" label ="确定" id ="send_btn" />
</ mx:Application >
< mx:Application xmlns:mx ="http://www.adobe.com/2006/mxml" layout ="absolute" fontSize ="13" height ="200" applicationComplete ="init();" >
< mx:Script >
<![CDATA[
import net.papaya.MainApp;
private function init():void
{
MainApp.getInstance(this);
}
]]>
</ mx:Script >
< mx:Panel x ="10" y ="10" width ="270" height ="174" layout ="absolute" title ="用户登录" >
< mx:Label x ="10" y ="22" text ="用户名:" />
< mx:Label x ="10" y ="52" text ="密码:" />
< mx:TextInput x ="75" y ="20" id ="user_txt" />
< mx:TextInput x ="75" y ="50" id ="psw_txt" />
< mx:Button x ="104" y ="99" label ="登录" id ="btn_logger" />
</ mx:Panel >
< mx:TextArea x ="288" y ="10" width ="308" height ="132" id ="return_msg" />
< mx:TextInput x ="288" y ="158" width ="221" id ="send_txt" />
< mx:Button x ="517" y ="158" label ="确定" id ="send_btn" />
</ mx:Application >
代码
package
net.papaya
{
import com.beyondo.sgs.util.PasswordAuthentication;
import flash.events.MouseEvent;
import mx.controls.Alert;
import net.papaya.event.ExecptionEvent;
import net.papaya.event.SGSEvent;
import net.papaya.event.SocketError;
import net.papaya.event.TestMessageEvent;
public class MainApp
{
private var app:sgsClient;
public static function getInstance(_app:sgsClient): void
{
new MainApp(_app);
}
public function MainApp(_app:sgsClient)
{
this .app = _app;
trace( " MainApp ... " );
this .init();
}
private var client:Client = new Client();
private function init(): void
{
// 注册app的事件
this .app.btn_logger.addEventListener(MouseEvent.CLICK,onLogger);
this .app.send_btn.addEventListener(MouseEvent.CLICK,onSendMsg);
// 注册client的事件
this .client.addEventListener(SGSEvent.LOGIN_SUCCESS,onLOGIN_SUCCESS);
this .client.addEventListener(SGSEvent.LOGIN_FAILED,onLOGIN_FAILED);
this .client.addEventListener(SGSEvent.DISCONNECTED,onDISCONNECTED);
this .client.addEventListener(ExecptionEvent.ExecptionThrow,onExecptionThrow);
this .client.addEventListener(TestMessageEvent.MESSAGEEVENT,onMESSAGEEVENT);
}
private function onLogger(e:MouseEvent): void
{
trace( " 正在登录 " );
this .client.passwordAuthentication = new PasswordAuthentication(
this .app.user_txt.text,
this .app.psw_txt.text
);
this .client.connect( " localhost " , " 1139 " );
}
private function onSendMsg(e:MouseEvent): void
{
this .client.send(
this .app.send_txt.text
);
}
private function onLOGIN_SUCCESS(e:SGSEvent): void
{
Alert.show( " 登录成功 " );
}
private function onLOGIN_FAILED(e:SGSEvent): void
{
Alert.show( " 登录失败 " );
}
private function onDISCONNECTED(e:SGSEvent): void
{
Alert.show( " 连接失败 " );
}
private function onExecptionThrow(e:ExecptionEvent): void
{
switch (e.wrong)
{
case SocketError.Connect_Fail:
Alert.show( " 连接服务器失败 " );
break ;
case SocketError.Security_error:
Alert.show( " 你所在的域没有权限访问服务器 " );
break ;
default :
Alert.show( " 连接失败 " );
break ;
}
}
private function onMESSAGEEVENT(e:TestMessageEvent): void
{
var str:String = e.message;
app.return_msg.text += " 服务器--》 " + str + " \n " ;
}
}
}
{
import com.beyondo.sgs.util.PasswordAuthentication;
import flash.events.MouseEvent;
import mx.controls.Alert;
import net.papaya.event.ExecptionEvent;
import net.papaya.event.SGSEvent;
import net.papaya.event.SocketError;
import net.papaya.event.TestMessageEvent;
public class MainApp
{
private var app:sgsClient;
public static function getInstance(_app:sgsClient): void
{
new MainApp(_app);
}
public function MainApp(_app:sgsClient)
{
this .app = _app;
trace( " MainApp ... " );
this .init();
}
private var client:Client = new Client();
private function init(): void
{
// 注册app的事件
this .app.btn_logger.addEventListener(MouseEvent.CLICK,onLogger);
this .app.send_btn.addEventListener(MouseEvent.CLICK,onSendMsg);
// 注册client的事件
this .client.addEventListener(SGSEvent.LOGIN_SUCCESS,onLOGIN_SUCCESS);
this .client.addEventListener(SGSEvent.LOGIN_FAILED,onLOGIN_FAILED);
this .client.addEventListener(SGSEvent.DISCONNECTED,onDISCONNECTED);
this .client.addEventListener(ExecptionEvent.ExecptionThrow,onExecptionThrow);
this .client.addEventListener(TestMessageEvent.MESSAGEEVENT,onMESSAGEEVENT);
}
private function onLogger(e:MouseEvent): void
{
trace( " 正在登录 " );
this .client.passwordAuthentication = new PasswordAuthentication(
this .app.user_txt.text,
this .app.psw_txt.text
);
this .client.connect( " localhost " , " 1139 " );
}
private function onSendMsg(e:MouseEvent): void
{
this .client.send(
this .app.send_txt.text
);
}
private function onLOGIN_SUCCESS(e:SGSEvent): void
{
Alert.show( " 登录成功 " );
}
private function onLOGIN_FAILED(e:SGSEvent): void
{
Alert.show( " 登录失败 " );
}
private function onDISCONNECTED(e:SGSEvent): void
{
Alert.show( " 连接失败 " );
}
private function onExecptionThrow(e:ExecptionEvent): void
{
switch (e.wrong)
{
case SocketError.Connect_Fail:
Alert.show( " 连接服务器失败 " );
break ;
case SocketError.Security_error:
Alert.show( " 你所在的域没有权限访问服务器 " );
break ;
default :
Alert.show( " 连接失败 " );
break ;
}
}
private function onMESSAGEEVENT(e:TestMessageEvent): void
{
var str:String = e.message;
app.return_msg.text += " 服务器--》 " + str + " \n " ;
}
}
}