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";
}
}
}