Darkstar入门指南
这几日在做Sun的Darkstar项目,看了三天教程,初步了解了这个平台的架构。
服务器端主要包括AppListener和ClientSessionListener。
-
在AppListener中设计Initialize和loggedIn。loggedIn的任务是给每一个连进来的session分配一个ClientSessionListener。Initialize的任务是用ChannelManager建立Channel(建立好的Channel无需保存引用,可以在后面用getChannel按名称调用)。
-
在ClientSessionListener中设计receivedMessage和disconnected。receivedMessage表示服务器收到客户端发来的消息,disconnected表示服务器收到客户端掉线或logout的信息。
-
在ClientSessionListener中需要设置成员变量ManagedReference<ClientSession> sessionRef,并在构造函数中令sessionRef = AppContext.getDataManager().createReference(session)来保存session的一个引用。这样以后可以用sessionRef.get().send()向该客户端发送消息。
-
在ClientSessionListener的构造函数中用channelManager.getChannel(channelName)得到channel,再用channel.join(session)将相应的session加入该channel。
-
服务器向一个channel群发消息只需用channelManager.getChannel(channelName)得到channel,再用channel.send()发送即可。
-
服务器端踢人只需调用AppContext.getDataManager().removeObject(sessionRef.get())即可。(如果没有在构造函数中把该session加入Data Store,那么踢人就不知道怎么实现了……)
客户端主要包括SimpleClientListener。
-
在SimpleClientListener中需要设置成员变量SimpleClient simpleClient,并在构造函数中令simpleClient = new SimpleClient(this)来生成一个simpleClient。这个simpleClient可以执行login/logout等操作。
-
SimpleClientListener的构造函数还需要:设置Properties,login。具体代码为:
simpleClient = new SimpleClient(this); Properties props = new Properties(); props.put("host", "localhost"); props.put("port", "1139"); try { simpleClient.login(props); } catch (IOException e) { e.printStackTrace(); }
-
在SimpleClientListener中还需要加入函数
public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(player,password.toCharArray()); }
来生成登入信息发送给服务器。
-
实现SimpleClientListener和ServerSessionListener接口要求的其他函数:
public void loggedIn() { System.out.println(player + " has logged in"); } public void loginFailed(String reason) { System.out.println(player + " failed to log in"); } public void disconnected(boolean graceful, String reason) { System.out.println(player + " has disconnected"); } public ClientChannelListener joinedChannel(ClientChannel channel) { return new ClientSideChannelListener(); // 其中ClientSideChannelListener是自己写的implements ClientChannelListener的类 } public void receivedMessage(ByteBuffer message) { System.out.println(message); } public void reconnected() { System.out.println(player + " has reconnected"); } public void reconnecting() { System.out.println(player + " is reconnecting"); } public static void main(String[] args) { new ClientSide(); }
-
实现类ClientSideChannelListener:
class ClientSideChannelListener implements ClientChannelListener { public void leftChannel(ClientChannel channel) { System.out.println("Removed from channel " + channel.getName()); } public void receivedMessage(ClientChannel channel, ByteBuffer message) { System.out.println("Message from channel " + channel.getName() + ":" + message); } }
最后附上C/S端的源码,S端就不说了,C端的流程是login,等待,logout,等待,结束。
// ServerSide.java
import java.io.*;
import java.util.*;
import java.nio.*;
import com.sun.sgs.app.*;
public class ServerSide implements AppListener, Serializable {
private static final long serialVersionUID = 1L;
public void initialize(Properties props) {
ChannelManager channelManager = AppContext.getChannelManager();
channelManager.createChannel("BaseChannel", new ServerSideChannelListener(), Delivery.RELIABLE);
}
public ClientSessionListener loggedIn(ClientSession session) {
System.out.println(session.getName() + " has logged in");
return new ServerSideSessionListener(session);
}
}
class ServerSideSessionListener implements ClientSessionListener,Serializable {
public static final long serialVersionUID = 2L;
private final ManagedReference<ClientSession> sessionRef;
private final String sessionName;
public ServerSideSessionListener(ClientSession session) {
sessionRef = AppContext.getDataManager().createReference(session);
sessionName = session.getName();
ChannelManager channelManager = AppContext.getChannelManager();
Channel baseChannel = channelManager.getChannel("BaseChannel");
baseChannel.join(session);
}
public void receivedMessage(ByteBuffer message) {
System.out.println(message);
}
public void disconnected(boolean graceful) {
System.out.println(sessionName + " has disconnected " + (graceful ? "gracefully" : "ungracefully"));
}
}
class ServerSideChannelListener implements ChannelListener,Serializable {
private static final long serialVersionUID = 3L;
public void receivedMessage(Channel channel, ClientSession session, ByteBuffer message) {
System.out.println("session " + session.getName() + " sent a message on channel " + channel.getName());
channel.send(session, message);
}
}
// ClientSide.java
import java.util.*;
import java.io.*;
import java.nio.*;
import java.net.*;
import com.sun.sgs.client.*;
import com.sun.sgs.client.simple.*;
public class ClientSide implements SimpleClientListener {
protected final SimpleClient simpleClient;
private String player = "Michael Jackson";
private String password = "123456";
public ClientSide() {
simpleClient = new SimpleClient(this);
Properties props = new Properties();
props.put("host", "localhost");
props.put("port", "1139");
try {
simpleClient.login(props);
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0;i < 1000000;i++)
for (int j = 0;j < 10000;j++)
;
simpleClient.logout(false);
for (int i = 0;i < 1000000;i++)
for (int j = 0;j < 10000;j++)
;
}
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(player,password.toCharArray());
}
public void loggedIn() {
System.out.println(player + " has logged in");
}
public void loginFailed(String reason) {
System.out.println(player + " failed to log in" + ";" + reason);
}
public void disconnected(boolean graceful, String reason) {
System.out.println(player + " has disconnected " + (graceful ? "gracefully" : "ungracefully") + ":" + reason);
}
public ClientChannelListener joinedChannel(ClientChannel channel) {
System.out.println(player + " has joined channel " + channel.getName());
byte[] buf = {1,2,3};
try {
channel.send(ByteBuffer.wrap(buf));
} catch (IOException e) {
e.printStackTrace();
}
return new ClientSideChannelListener();
}
public void receivedMessage(ByteBuffer message) {
System.out.println(message);
}
public void reconnected() {
System.out.println(player + " has reconnected");
}
public void reconnecting() {
System.out.println(player + " is reconnecting");
}
public static void main(String[] args) {
new ClientSide();
}
}
class ClientSideChannelListener implements ClientChannelListener {
public void leftChannel(ClientChannel channel) {
System.out.println("Removed from channel " + channel.getName());
}
public void receivedMessage(ClientChannel channel, ByteBuffer message) {
System.out.println("Message from channel " + channel.getName() + ":" + message);
}
}