diff --git a/Examples/simple_chat_room.alusus b/Examples/simple_chat_room.alusus
new file mode 100644
index 0000000..359ace5
--- /dev/null
+++ b/Examples/simple_chat_room.alusus
@@ -0,0 +1,141 @@
+import "Srl/Console.alusus";
+import "Srl/String.alusus";
+import "Apm.alusus";
+Apm.importFile("Alusus/Http");
+
+module WebSocketChat {
+ use Srl;
+
+ class Client {
+ def conn: ptr[Http.Connection];
+ };
+
+ def clients: array[Client, 32];
+ def clientCount: Int = 0;
+
+
+
+ func onWebSocketConnect(conn: ptr[Http.Connection], _: ptr[Void]): Int {
+ clients(clientCount).conn = conn;
+ clientCount += 1;
+
+ Console.print("Client connected\n");
+ return 0;
+ };
+
+ func onWebSocketReady(conn: ptr[Http.Connection], _: ptr[Void]): Void {
+ Http.writeWebSocketText(
+ conn,
+ "Connected to broadcast chat",
+ 27
+ );
+ };
+
+ func onWebSocketData(
+ conn: ptr[Http.Connection],
+ bits: Int,
+ data: CharsPtr,
+ len: Int,
+ _: ptr[Void]
+ ): Int {
+ if ((bits & 1) == 0) return 1;
+
+ def i: Int = 0;
+ def full_data : String ="";
+ while i < clientCount {
+ if (clients(i).conn == conn)
+ full_data = full_data + String.format("user : %i ",i+1) ;
+ i +=1;
+ }
+ full_data.append(data);
+ i=0;
+ len = full_data.getLength();
+ while i < clientCount {
+ Http.writeWebSocketText(
+ clients(i).conn,
+ full_data.buf,
+ len
+ );
+ i += 1;
+ }
+
+ return 1;
+ };
+
+ func onWebSocketClose(conn: ptr[Http.Connection], _: ptr[Void]): Void {
+ def i: Int = 0;
+ while i < clientCount {
+ if (clients(i).conn == conn) {
+
+ def j: Int = i;
+ while j < clientCount - 1 {
+ clients(j).conn = clients(j + 1).conn;
+ j += 1;
+ }
+
+ clientCount -= 1;
+ break;
+ }
+ i += 1;
+ }
+
+ Console.print("Client disconnected\n");
+ };
+
+
+
+ func handleHttpRequest(conn: ptr[Http.Connection]): Int {
+ def req : ptr[Http.RequestInfo] = Http.getRequestInfo(conn);
+
+ if String.isEqual(req~cnt.localUri, "/websocket") return 0;
+
+ if String.isEqual(req~cnt.localUri, "/") {
+ def html: CharsPtr =
+ "
"
+ "Broadcast Chat
"
+ ""
+ ""
+ ""
+ "";
+
+ Http.print(conn, "HTTP/1.1 200 OK\r\n");
+ Http.print(conn, "Content-Length: %d\r\n\r\n",
+ String.getLength(html));
+ Http.print(conn, html);
+ return 1;
+ }
+
+ return 1;
+ };
+
+ func start() {
+ def ctx : ptr[Http.Context] = Http.startServer(handleHttpRequest~ptr, {
+ "listening_ports", "8080"
+ });
+
+ Http.setWebSocketHandler(
+ ctx,
+ "/websocket",
+ onWebSocketConnect~ptr,
+ onWebSocketReady~ptr,
+ onWebSocketData~ptr,
+ onWebSocketClose~ptr
+ );
+
+ Console.print("Server running on 8080\n");
+ Console.getChar();
+ Http.stopServer(ctx);
+ };
+};
+
+WebSocketChat.start();
diff --git a/Examples/websocket_server.alusus b/Examples/websocket_server.alusus
index 49dbf76..7224eb4 100644
--- a/Examples/websocket_server.alusus
+++ b/Examples/websocket_server.alusus
@@ -8,11 +8,12 @@ module WebSocketExample {
use Srl;
func start() {
- def context: ptr[Http.Context] = Http.startServer(handleHttpRequest~ptr, {
- "document_root", ".", // Set document root
- "listening_ports", "8080", // Listen on port 8080
- "websocket_timeout_ms", "3600000"
- });
+ def context: ptr[Http.Context] =
+ Http.startServer(handleHttpRequest~ptr, {
+ "document_root", ".",
+ "listening_ports", "8080",
+ "websocket_timeout_ms", "3600000"
+ });
Http.setWebSocketHandler(
context,
@@ -23,110 +24,136 @@ module WebSocketExample {
onWebSocketClose~ptr
);
- Console.print("Server with WebSocket support listening on port 8080\n");
- Console.print("HTTP: http://localhost:8080/\n");
- Console.print("WebSocket: ws://localhost:8080/websocket\n");
- Console.print("Press enter to close server.");
+ Console.print("Server running on port 8080\n");
+ Console.print("HTTP : http://localhost:8080/\n");
+ Console.print("WS : ws://localhost:8080/websocket\n");
+ Console.print("Press ENTER to stop server...\n");
Console.getChar();
+
Http.stopServer(context);
- Console.print("Server closed.\nPress enter to exit.");
+ Console.print("Server stopped. Press ENTER to exit.\n");
Console.getChar();
};
func handleHttpRequest(connection: ptr[Http.Connection]): Int {
- def requestInfo: ptr[Http.RequestInfo] = Http.getRequestInfo(connection);
-
- if String.isEqual(requestInfo~cnt.localUri, "/") {
- def htmlContent: CharsPtr =
- "\n"
- "\n"
- "WebSocket Test\n"
- "\n"
- " WebSocket Test Page
\n"
- " \n"
- " \n"
- " \n"
- " \n"
- "\n"
- "";
-
- Http.print(connection, "HTTP/1.1 200 OK\r\n");
- Http.print(connection, "Content-Type: text/html\r\n");
- Http.print(connection, "Content-Length: %d\r\n\r\n", String.getLength(htmlContent));
- Http.print(connection, htmlContent);
- } else {
- Http.print(connection, "HTTP/1.1 404 Not Found\r\n");
- Http.print(connection, "Content-Type: text/plain\r\n");
- Http.print(connection, "Content-Length: 9\r\n\r\n");
- Http.print(connection, "Not Found");
- }
+ def req: ptr[Http.RequestInfo] = Http.getRequestInfo(connection);
+
+
+ if String.isEqual(req~cnt.localUri, "/websocket") {
+ return 0;
+ }
+
+
+ if String.isEqual(req~cnt.localUri, "/") {
+
+ def page: CharsPtr =
+ "\n"
+ "\n"
+ "WebSocket Test\n"
+ "\n"
+ "WebSocket Test
\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ "";
+
+ Http.print(connection, "HTTP/1.1 200 OK\r\n");
+ Http.print(connection, "Content-Type: text/html\r\n");
+ Http.print(
+ connection,
+ "Content-Length: %d\r\n\r\n",
+ String.getLength(page)
+ );
+ Http.print(connection, page);
return 1;
- };
+ }
+
+
+ Http.print(connection, "HTTP/1.1 404 Not Found\r\n");
+ Http.print(connection, "Content-Length: 9\r\n\r\nNot Found");
- func onWebSocketConnect(connection: ptr[Http.Connection], userData: ptr[Void]): Int {
+ return 1;
+};
+
+ func onWebSocketConnect(
+ connection: ptr[Http.Connection],
+ userData: ptr[Void]
+ ): Int {
Console.print("WebSocket client connected\n");
return 0;
};
- func onWebSocketReady(connection: ptr[Http.Connection], userData: ptr[Void]): Void {
- Console.print("WebSocket connection ready\n");
- Http.writeWebSocketText(connection, "Welcome to the WebSocket server!", 33);
- };
+ func onWebSocketReady(
+ connection: ptr[Http.Connection],
+ userData: ptr[Void]
+ ): Void {
+ Console.print("WebSocket ready\n");
- func onWebSocketData(connection: ptr[Http.Connection], bits: Int, data: CharsPtr, dataLen: Int, userData: ptr[Void]): Int {
- Console.print("Received WebSocket message: ");
- Console.print(data, dataLen);
- Console.print("\n");
+ def msg: CharsPtr = "Welcome to the WebSocket server!";
+ Http.writeWebSocketText(
+ connection,
+ msg,
+ String.getLength(msg)
+ );
+ };
- def response: array[Char, 256];
- String.assign(response~ptr, "Echo: ");
- String.concat(response~ptr, data, dataLen);
+ func onWebSocketData(
+ connection: ptr[Http.Connection],
+ bits: Int,
+ data: CharsPtr,
+ dataLen: Int,
+ userData: ptr[Void]
+): Int {
- Http.writeWebSocketText(connection, response~ptr, String.getLength(response~ptr));
+ if ((bits & 0x1) == 0) {
return 1;
- };
+ }
+
+ Console.print("Received: ");
+ Console.print(data, dataLen);
+ Console.print("\n");
+
+ def buffer: array[Char, 512];
+ String.assign(buffer~ptr, "Echo: ");
+ String.concat(buffer~ptr, data, dataLen);
+
+ Http.writeWebSocketText(
+ connection,
+ buffer~ptr,
+ String.getLength(buffer~ptr)
+ );
+
+ return 1;
+};
- func onWebSocketClose(connection: ptr[Http.Connection], userData: ptr[Void]): Void {
+ func onWebSocketClose(
+ connection: ptr[Http.Connection],
+ userData: ptr[Void]
+ ): Void {
Console.print("WebSocket client disconnected\n");
};
};
-WebSocketExample.start();
\ No newline at end of file
+WebSocketExample.start();
diff --git a/Http.alusus b/Http.alusus
index eac9c61..8cff4c0 100644
--- a/Http.alusus
+++ b/Http.alusus
@@ -15,7 +15,7 @@ module Http {
}
class Context{
- def stopFlag: int; // Should we stop event loop
+
};
def RequestCallback: alias ptr[func (connection: ptr[Connection]): Int];