Skip to content

Instantly share code, notes, and snippets.

@profan
Created October 28, 2018 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save profan/a07bcc7bbda329720dff4a870c270e61 to your computer and use it in GitHub Desktop.
Save profan/a07bcc7bbda329720dff4a870c270e61 to your computer and use it in GitHub Desktop.
terrible message handling loop
import vibe.d;
import vibe.data.json;
import vibe.http.router;
import std.concurrency : spawnLinked, Tid, thisTid;
import orb.net : NetworkClient;
import orb.server : Server;
shared static this() {
auto router = new URLRouter;
router.get("*", serveStaticFiles("public/"));
router.get("/ws", handleWebSockets(&handleConn));
auto settings = new HTTPServerSettings;
settings.port = 8080;
settings.bindAddresses = ["::1", "127.0.0.1"];
listenHTTP(settings, router);
//start game server
auto tid = spawnLinked(&startServer, thisTid);
SingletonServer.set(tid);
import vibe.core.log : LogLevel;
//setLogLevel(LogLevel.debug_);
}
void handleConn(scope WebSocket sock) {
auto tid = SingletonServer.get();
auto client = NetworkClient(sock, tid);
client.run();
}
class SingletonServer {
private static __gshared Tid server_tid;
static __gshared public Tid get() {
return server_tid;
}
static synchronized __gshared public void set(Tid tid) {
SingletonServer.server_tid = tid;
}
}
void startServer(Tid owner_tid) {
auto server = Server(owner_tid);
server.run();
}
module orb.net;
import std.concurrency : send, Tid;
import vibe.core.concurrency : receive, receiveTimeout, thisTid;
import vibe.http.websockets : WebSocket;
import vibe.core.log : logInfo;
import orb.util : Listener;
import orb.defs : AuthTimeout, EventType, vibeTid;
import orb.log : logSpecial;
import orb.chat : ChatMessageEvent;
/* generated code */
import orb.protobuf : AuthResponse, ChatMessage, ClientLogin, Protocol;
import orb.event : EventManager, Event;
alias ClientLoginEvent = Event!(EventType.ClientLogin, ClientLogin);
alias ClientConnectEvent = Event!(EventType.ClientConnect, ConnectPayload);
alias ClientDisconnectEvent = Event!(EventType.ClientDisconnect, vibeTid);
struct ConnectPayload {
vibeTid tid;
string username;
}
struct NetworkClient {
private WebSocket socket;
private Tid server_tid;
this(WebSocket socket, Tid server_tid) {
this.socket = socket;
this.server_tid = server_tid;
}
@disable this();
@disable this(this);
void init() {
//?
} //init
void run() {
logInfo("[NetworkClient] client connected.");
bool success = false;
if (socket.connected) {
auto msg = socket.receiveBinary();
logInfo("[NetworkClient] client sent msg: %d bytes", msg.length);
auto login = ClientLogin(msg);
logInfo("[NetworkClient] login msg: %s", login);
send(server_tid, thisTid, login);
receiveTimeout(AuthTimeout,
(shared(ubyte[]) response, bool connected) {
socket.send(cast(ubyte[])response);
if (connected) { //TODO look at this, this is a bit iffy (shouldn't this happen internally?)
send(server_tid, ClientConnectEvent(ConnectPayload(thisTid, login.username)));
logInfo("[NetworkClient] login successful!");
success = true;
}
});
}
scope(exit) {
if (success) {
socket.close();
send(server_tid, ClientDisconnectEvent(thisTid));
logInfo("[NetworkClient] client disconnected.");
}
}
while (socket.connected) {
import core.time : dur;
if (socket.waitForData(dur!"msecs"(5))) { //TODO define this somewhere visible (is duplicated below?)
auto msg = socket.receiveBinary();
logInfo("[NetworkClient] client sent msg: %d bytes", msg.length);
auto packet = Protocol(msg);
logInfo("[NetworkClient] got msg of type: %d", packet.type);
if (packet.type == Protocol.Type.Chat) {
auto cmsg = ChatMessage(packet.data);
send(server_tid, thisTid, ChatMessageEvent(cmsg));
} else if (packet.type == Protocol.Type.Auth) {
auto amsg = ClientLogin(packet.data);
send(server_tid, thisTid, amsg);
} else if (packet.type == Protocol.Type.Game) {
//wow, much game, such packet
} else {
logInfo("[NetworkClient] got unexpected packet type: %d", packet.type);
}
}
receiveTimeout(dur!"msecs"(5), //TODO belongs to above todo, same timeout perhaps?
(shared(ubyte[]) message) {
logInfo("[NetworkClient] recieved message, sending to client.");
socket.send(cast(ubyte[])message);
}
);
}
} //run
} //NetworkClient
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment