This commit is contained in:
2014-07-05 18:02:25 +04:00
parent ecd7c54379
commit 6cd5eaee75
11 changed files with 103 additions and 152 deletions

3
.gitignore vendored
View File

@@ -4,4 +4,5 @@ out/
*.iml *.iml
*.ipr *.ipr
*.iws *.iws
*.ids *.ids
*.stackdump

View File

@@ -4,7 +4,7 @@ import protohx.Message;
import haxe.crypto.Md5; import haxe.crypto.Md5;
import flash.Lib; import flash.Lib;
import flash.events.MouseEvent; import flash.events.MouseEvent;
import ru.m.armageddon.core.connect.FlashConnection; import ru.m.armageddon.core.connect.flash.FlashConnection;
import ru.m.armageddon.core.connect.IConnection; import ru.m.armageddon.core.connect.IConnection;
import haxework.log.TraceLogger; import haxework.log.TraceLogger;
import ru.m.armageddon.proto.LoginRequest; import ru.m.armageddon.proto.LoginRequest;

View File

@@ -1,5 +1,6 @@
package ru.m.armageddon.core.connect; package ru.m.armageddon.core.connect;
import haxe.io.Bytes;
import protohx.Message; import protohx.Message;
import ru.m.armageddon.core.connect.IConnection; import ru.m.armageddon.core.connect.IConnection;
@@ -13,5 +14,7 @@ class BaseConnection implements IConnection {
this.handler = handler; this.handler = handler;
} }
public function pushData(bytes:Bytes):Void {}
public function send(packet:Message):Void {} public function send(packet:Message):Void {}
private function receive(packet:Message):Void {}
} }

View File

@@ -1,11 +1,14 @@
package ru.m.armageddon.core.connect; package ru.m.armageddon.core.connect;
import haxe.io.Bytes;
import protohx.Message; import protohx.Message;
interface IConnection { interface IConnection {
private var builder:IPacketBuilder; private var builder:IPacketBuilder;
private var handler:IConnectionHandler; private var handler:IConnectionHandler;
public function send(packet:Message):Void; public function send(packet:Message):Void;
public function pushData(bytes:Bytes):Void;
private function receive(packet:Message):Void;
} }
interface IConnectionHandler { interface IConnectionHandler {

View File

@@ -1,99 +0,0 @@
package ru.m.armageddon.core.connect;
import sys.net.Socket;
import haxe.io.BytesOutput;
import protohx.Message;
import haxe.io.Bytes;
class NekoConnection implements IConnection {
private static var MAP:Map<Int, Map<Int, Class<Message>>> = [
0x01 => [
0x0001 = > LoginRequest,
0x0002 = > LoginResponse
]
];
private var socket:Socket;
public function new(host, port) {
this.onConnect = onConnect;
this.addBytes = addBytes;
this.onClose = onClose;
try {
socket.connect(new sys.net.Host(host), port);
} catch (e:Dynamic) {
trace(e);
//onClose();
return;
}
onConnect();
var buffer = Bytes.alloc(1024);
var socks = [socket];
var timer = new haxe.Timer(100);
timer.run = function() {
try {
var r:Array<sys.net.Socket>;
do {
r = sys.net.Socket.select(socks, null, null, 0.001).read;
for (s in r) {
var size = s.input.readBytes(buffer, 0, buffer.length);
onSocketData(buffer.sub(0, size));
}
} while (r.length > 0);
} catch (e:haxe.io.Eof) {
timer.stop();
//onClose();
socket.close();
} catch (e:Dynamic) {
trace(e);
//onClose();
}
};
}
public dynamic function onConnect():Void {
}
private function onSocketData(data):Void {
var family = socket.readByte();
var id = socket.readByte();
var b = new flash.utils.ByteArray();
socket.readBytes(b);
var bs = Bytes.ofData(cast b);
var packet = buildPacket(family, id);
packet.mergeFrom(bs);
receive(packet);
}
private function buildPacket(family:Int, id:Int):Message {
var packetClass = MAP[family][id];
return Type.createInstance(packetClass, []);
}
public function send(packet:Message):Void {
for (family in MAP.keys()) {
var subMap = MAP[family];
for (id in MAP.keys()) {
var packetClass = subMap[id];
if (Std.is(packet, packetClass)) {
socket.output.writeByte(family);
socket.output.writeByte(id);
var b = new BytesOutput();
packet.writeTo(b);
var bytes = b.getBytes();
socket.output.writeUInt16(bytes.length);
socket.output.writeBytes(bytes, 0, bytes.length);
socket.output.flush();
}
}
}
}
public dynamic function receive(packet:Message):Void {
L.d("Receive", packet + "");
}
}

View File

@@ -9,12 +9,12 @@ import ru.m.armageddon.proto.ErrorResponse;
class PacketBuilder implements IPacketBuilder { class PacketBuilder implements IPacketBuilder {
private static var MAP:Map<Int, Map<Int, Class<Message>>> = [ private static var MAP:Map<Int, Map<Int, Class<Message>>> = [
0x00 => [
0x0001 => ErrorResponse
],
0x01 => [ 0x01 => [
0x0001 => LoginRequest, 0x0001 => LoginRequest,
0x0002 => LoginResponse 0x0002 => LoginResponse
],
0x10 => [
0x0001 => ErrorResponse
] ]
]; ];

View File

@@ -1,4 +1,4 @@
package ru.m.armageddon.core.connect; package ru.m.armageddon.core.connect.flash;
import ru.m.armageddon.core.connect.IConnection.IConnectionHandler; import ru.m.armageddon.core.connect.IConnection.IConnectionHandler;
import protohx.MessageUtils; import protohx.MessageUtils;
@@ -68,9 +68,10 @@ class FlashConnection extends BaseConnection {
socket.flush(); socket.flush();
} }
private function receive(packet:Message):Void { override private function receive(packet:Message):Void {
L.d("Receive", MessageUtils.toJson(packet)); L.d("Receive", MessageUtils.toJson(packet));
var name = Type.getClassName(Type.getClass(packet)).split("::")[1]; var name = Type.getClassName(Type.getClass(packet)).split(".").pop();
L.d("xxx", name); L.d("xxx", name);
handler.onPacket(packet);
} }
} }

View File

@@ -0,0 +1,60 @@
package ru.m.armageddon.core.connect.neko;
import haxe.io.BytesOutput;
import protohx.MessageUtils;
import protohx.Message;
import haxe.io.Bytes;
import sys.net.Socket;
import ru.m.armageddon.core.connect.IConnection.IConnectionHandler;
class NekoConnection extends BaseConnection {
public var queue(default, null):PacketQueue;
private var socket:Socket;
public function new(socket:Socket, handler:IConnectionHandler) {
super(handler);
this.socket = socket;
socket.setFastSend(true);
socket.output.bigEndian = false;
socket.input.bigEndian = false;
queue = new PacketQueue(builder);
}
override public function pushData(bytes:Bytes):Void {
queue.addBytes(bytes);
while (queue.hasMsg()) {
var packet:Message = queue.popMsg();
try {
receive(packet);
} catch (error:Dynamic) {
handler.onError(error);
}
}
}
override public function send(packet:Message):Void {
trace("Send: " + MessageUtils.toJson(packet));
try {
var meta = builder.packetMeta(packet);
var b = new BytesOutput();
packet.writeTo(b);
var bytes = b.getBytes();
socket.output.writeByte(meta.family);
socket.output.writeByte(meta.id);
socket.output.writeUInt16(bytes.length);
socket.output.write(bytes);
socket.output.flush();
} catch (e:Dynamic) {
trace(e);
}
}
override private function receive(packet:Message):Void {
trace("Receive", MessageUtils.toJson(packet));
var name = Type.getClassName(Type.getClass(packet)).split(".").pop();
trace("xxx", name);
handler.onPacket(packet);
}
}

View File

@@ -1,4 +1,4 @@
package ru.m.armageddon.server.session; package ru.m.armageddon.core.connect.neko;
import ru.m.armageddon.core.connect.IConnection.IPacketBuilder; import ru.m.armageddon.core.connect.IConnection.IPacketBuilder;
import protohx.Message; import protohx.Message;

View File

@@ -13,13 +13,13 @@ class Server extends ThreadServer<Session, Bytes> {
} }
override function clientConnected(s:Socket):Session { override function clientConnected(s:Socket):Session {
var session = new Session(s, null); var session = new Session(s);
Lib.println("client: " + session.id + " / " + s.peer()); Lib.println("client: " + session.user + " / " + s.peer());
return session; return session;
} }
override function clientDisconnected(session:Session) { override function clientDisconnected(session:Session) {
Lib.println("client " + Std.string(session.id) + " disconnected"); Lib.println("client " + Std.string(session.user) + " disconnected");
} }
override function readClientMessage(session:Session, buf:Bytes, pos:Int, len:Int) { override function readClientMessage(session:Session, buf:Bytes, pos:Int, len:Int) {
@@ -27,7 +27,7 @@ class Server extends ThreadServer<Session, Bytes> {
} }
override function clientMessage(session:Session, bytes:Bytes) { override function clientMessage(session:Session, bytes:Bytes) {
session.pushData(bytes); session.connection.pushData(bytes);
} }
public static function main() { public static function main() {

View File

@@ -1,60 +1,41 @@
package ru.m.armageddon.server.session; package ru.m.armageddon.server.session;
import ru.m.armageddon.core.connect.BaseConnection; import ru.m.armageddon.core.connect.neko.NekoConnection;
import ru.m.armageddon.proto.ErrorResponse; import ru.m.armageddon.proto.ErrorResponse;
import ru.m.armageddon.server.db.Db; import ru.m.armageddon.server.db.Db;
import ru.m.armageddon.proto.User; import ru.m.armageddon.proto.User;
import ru.m.armageddon.proto.LoginResponse; import ru.m.armageddon.proto.LoginResponse;
import ru.m.armageddon.proto.LoginRequest; import ru.m.armageddon.proto.LoginRequest;
import protohx.MessageUtils;
import haxe.io.Bytes;
import protohx.Message; import protohx.Message;
import ru.m.armageddon.core.connect.IConnection; import ru.m.armageddon.core.connect.IConnection;
import haxe.io.BytesOutput;
import sys.net.Socket; import sys.net.Socket;
class Session extends BaseConnection { class Session implements IConnectionHandler {
public var id:Int; public var user(default, null):User;
public var socket:Socket; public var connection(default, null):IConnection;
public var queue:PacketQueue;
public function new(socket:Socket, handler:IConnectionHandler) { public function new(socket:Socket) {
super(handler); connection = new NekoConnection(socket, this);
this.socket = socket;
socket.setFastSend(true);
socket.output.bigEndian = false;
socket.input.bigEndian = false;
queue = new PacketQueue(builder);
} }
public function pushData(bytes:Bytes):Void { public function onConnected():Void {
queue.addBytes(bytes);
while (queue.hasMsg()) {
var packet:Message = queue.popMsg();
receive(packet);
}
} }
override public function send(packet:Message):Void { public function onDisconnected():Void {
trace("Send: " + MessageUtils.toJson(packet));
try {
var meta = builder.packetMeta(packet);
var b = new BytesOutput();
packet.writeTo(b);
var bytes = b.getBytes();
socket.output.writeByte(meta.family);
socket.output.writeByte(meta.id);
socket.output.writeUInt16(bytes.length);
socket.output.write(bytes);
socket.output.flush();
} catch (e:Dynamic) {
trace(e);
}
} }
private function receive(packet:Message):Void { public function onError(error:Dynamic):Void {
trace("Receive: " + MessageUtils.toJson(packet)); connection.send(
new ErrorResponse()
.setCode(0)
.setMessage(Std.string(error))
);
}
public function onPacket(packet:Message):Void {
if (Std.is(packet, LoginRequest)) { if (Std.is(packet, LoginRequest)) {
var request = cast(packet, LoginRequest); var request = cast(packet, LoginRequest);
@@ -64,14 +45,15 @@ class Session extends BaseConnection {
var user = new User(); var user = new User();
user.login = userData.login; user.login = userData.login;
user.nickname = userData.login; user.nickname = userData.login;
this.user = user;
var response = new LoginResponse(); var response = new LoginResponse();
response.user = user; response.user = user;
send(response); connection.send(response);
} else { } else {
var response = new ErrorResponse(); var response = new ErrorResponse();
response.code = 403; response.code = 403;
response.message = "User not found"; response.message = "User not found";
send(response); connection.send(response);
} }
} }
} }