-
Notifications
You must be signed in to change notification settings - Fork 0
Simple Socket Server Example
Jacob Jensen edited this page Sep 10, 2016
·
2 revisions
Below is a simple socket server example using cheetah.
module simple_socket_server_example;
import vibe.d : logInfo;
import cheetah;
shared static this() {
// Creates a server listening at 127.0.0.1:8899
auto server = new SocketServer!Client("127.0.0.1", 8899);
// Attaches events to the server
server.attach(SocketEventType.connect, new SocketEvent!Client(&onConnect));
server.attach(SocketEventType.receive, [
new SocketEvent!Client(&onReceiveHead),
new SocketEvent!Client(&onReceiveBody)
]);
server.attach(SocketEventType.disconnect, new SocketEvent!Client(&onDisconnect));
server.attach(SocketEventType.error, new SocketEvent!Client(&onError));
// Sets up events that has to be local per client.
// This is usually used with events using moveNext() ...
server.copyReceiveEvents = true;
// Starts the server
server.start();
}
/// Custom client wrapper that we use to handle custom packet specifications
class Client {
size_t expectedAmount;
ushort type;
}
/// Handling connections
void onConnect(SocketEventArgs!Client e) {
logInfo("A client has connected ...");
e.client.data = new Client;
}
/// Handling disconnections
void onDisconnect(SocketEventArgs!Client e) {
logInfo("A client has disconnected ...");
}
/// Handling receive for the packet head
void onReceiveHead(SocketEventArgs!Client e) {
e.client.read(4 - e.currentReceiveAmount);
if (e.currentReceiveAmount >= 4) {
auto ptr = e.buffer.ptr;
e.client.data.expectedAmount = (*cast(ushort*)(ptr));
e.client.data.type = (*cast(ushort*)(ptr + 2));
logInfo("Received head ...");
import std.conv : to;
logInfo(to!string(e.client.data.expectedAmount));
logInfo(to!string(e.client.data.type));
e.resetReceive(e.currentReceiveAmount);
e.client.moveNext(SocketEventType.receive);
}
}
/// Handling receive for the packet body
void onReceiveBody(SocketEventArgs!Client e) {
e.client.read(e.client.data.expectedAmount - e.currentReceiveAmount);
if (e.currentReceiveAmount >= e.client.data.expectedAmount) {
logInfo("Received body ...");
import std.conv : to;
logInfo(to!string(e.buffer[4 .. $]));
e.resetReceive(e.currentReceiveAmount - e.client.data.expectedAmount);
e.client.moveNext(SocketEventType.receive);
}
}
/// Handling errors
void onError(SocketEventArgs!Client e) {
logInfo("Error: " ~ e.error.toString());
if (e.client) {
e.client.close();
}
else if (e.server) {
e.server.stop();
}
}