diff --git a/Examples/simple_chat_room.alusus b/Examples/simple_chat_room.alusus
index 07c0e7f..555b44f 100644
--- a/Examples/simple_chat_room.alusus
+++ b/Examples/simple_chat_room.alusus
@@ -46,12 +46,12 @@ module WebSocketChat {
func onWebSocketData(
conn: ptr[Http.Connection],
- opcode: Int,
+ bits: Int,
data: CharsPtr,
len: ArchWord,
_: ptr[Void]
): Int {
- if (opcode & 1) == 0 return 1;
+ if (bits & 0x0F) != 1 return 1; // Ignore non-text frames
def i: Int = 0;
while i < clientCount and clients(i).conn != conn {
diff --git a/Examples/websocket_server.alusus b/Examples/websocket_server.alusus
index 4975a7a..70e298b 100644
--- a/Examples/websocket_server.alusus
+++ b/Examples/websocket_server.alusus
@@ -133,12 +133,12 @@ module WebSocketExample {
func onWebSocketData(
connection: ptr[Http.Connection],
- opcode: Int,
+ bits: Int,
data: CharsPtr,
dataLen: ArchWord,
userData: ptr[Void]
): Int {
- if ((opcode & 0x1) == 0) {
+ if ((bits & 0x0F) != 1) { // Ignore non-text frames
return 1;
}
diff --git "a/Examples/\331\205\330\253\330\247\331\204_\330\256\330\247\330\257\331\205_\331\210\331\212\330\250_\330\263\331\210\331\203\330\252.\330\243\330\263\330\263" "b/Examples/\331\205\330\253\330\247\331\204_\330\256\330\247\330\257\331\205_\331\210\331\212\330\250_\330\263\331\210\331\203\330\252.\330\243\330\263\330\263"
index 3334f4e..539fac9 100644
--- "a/Examples/\331\205\330\253\330\247\331\204_\330\256\330\247\330\257\331\205_\331\210\331\212\330\250_\330\263\331\210\331\203\330\252.\330\243\330\263\330\263"
+++ "b/Examples/\331\205\330\253\330\247\331\204_\330\256\330\247\330\257\331\205_\331\210\331\212\330\250_\330\263\331\210\331\203\330\252.\330\243\330\263\330\263"
@@ -130,12 +130,12 @@
دالة عند_بيانات_ويب_سوكت(
اتصال: مؤشر[بـننت.اتـصال]،
- رمز_العملية: صـحيح،
+ بتات: صـحيح،
بيانات: مـؤشر_محارف،
طول_البيانات: طـبيعي_متكيف،
بيانات_المستخدم: مؤشر[فـراغ]
): صـحيح {
- إذا (رمز_العملية & 1) == 0 ارجع 1؛
+ إذا (بتات & 0x0F) != 1 ارجع 1؛ // تجاهل الإطارات غير النصية
طـرفية.اطبع("تم استلام رسالة WebSocket: ")؛
طـرفية.اطبع(بيانات، طول_البيانات)؛
diff --git "a/Examples/\331\205\330\253\330\247\331\204_\330\272\330\261\331\201\330\251_\330\257\330\261\330\257\330\264\330\251.\330\243\330\263\330\263" "b/Examples/\331\205\330\253\330\247\331\204_\330\272\330\261\331\201\330\251_\330\257\330\261\330\257\330\264\330\251.\330\243\330\263\330\263"
index 49202dc..923ff70 100644
--- "a/Examples/\331\205\330\253\330\247\331\204_\330\272\330\261\331\201\330\251_\330\257\330\261\330\257\330\264\330\251.\330\243\330\263\330\263"
+++ "b/Examples/\331\205\330\253\330\247\331\204_\330\272\330\261\331\201\330\251_\330\257\330\261\330\257\330\264\330\251.\330\243\330\263\330\263"
@@ -47,12 +47,12 @@
دالة عند_بيانات_ويب_سوكت(
اتصال: مؤشر[بـننت.اتـصال]،
- رمز_العملية: صـحيح،
+ بتات: صـحيح،
بيانات: مـؤشر_محارف،
طول_البيانات: طـبيعي_متكيف،
_: مؤشر[فـراغ]
): صـحيح {
- إذا (رمز_العملية & 1) == 0 أرجع 1؛
+ إذا (بتات & 0x0F) != 1 أرجع 1؛ // تجاهل الإطارات غير النصية
عرف ت: صـحيح = 0؛
بينما ت < عدد_العملاء و العملاء(ت).اتصال != اتصال {
diff --git a/Http.alusus b/Http.alusus
index 94c20ea..ea665b1 100644
--- a/Http.alusus
+++ b/Http.alusus
@@ -102,7 +102,7 @@ module Http {
def WebSocketConnectCallback: alias ptr[func (connection: ptr[Connection], userData: ptr[Void]): Int];
def WebSocketReadyCallback: alias ptr[func (connection: ptr[Connection], userData: ptr[Void]): Void];
def WebSocketDataCallback: alias ptr[func (
- connection: ptr[Connection], opcode: Int, data: CharsPtr, dataLen: ArchWord, userData: ptr[Void]
+ connection: ptr[Connection], bits: Int, data: CharsPtr, dataLen: ArchWord, userData: ptr[Void]
): Int];
def WebSocketCloseCallback: alias ptr[func (connection: ptr[Connection], userData: ptr[Void]): Void];
diff --git a/websocket_documentation.ar.md b/websocket_documentation.ar.md
index 27755a3..49e7194 100644
--- a/websocket_documentation.ar.md
+++ b/websocket_documentation.ar.md
@@ -55,7 +55,7 @@ def WebSocketReadyCallback: alias ptr[func (connection: ptr[Connection], userDat
### مـنادى_بيانات_ويب_سوكت (WebSocketDataCallback)
```
-عرف مـنادى_بيانات_ويب_سوكت: لقب مؤشر[دالة (اتصال: مؤشر[بـننت.اتـصال], رمز_العملية: صـحيح, بيانات: مـؤشر_محارف, طول_البيانات: صـحيح, بيانات_المستخدم: مؤشر[فـراغ]): صـحيح];
+عرف مـنادى_بيانات_ويب_سوكت: لقب مؤشر[دالة (اتصال: مؤشر[بـننت.اتـصال], بتات: صـحيح, بيانات: مـؤشر_محارف, طول_البيانات: صـحيح, بيانات_المستخدم: مؤشر[فـراغ]): صـحيح];
```
@@ -66,12 +66,38 @@ def WebSocketDataCallback: alias ptr[func (connection: ptr[Connection], bits: In
-يتم استدعاؤها عند استلام البيانات من العميل. يشير المعامل `رمز_العملية` إلى نوع الإطار:
-- `1`: إطار نصي
-- `2`: إطار ثنائي
-- `8`: إطار إغلاق
-- `9`: إطار Ping
-- `10`: إطار Pong
+يتم استدعاؤها عند استلام البيانات من العميل. المعامل `بتات` هو البايت الأول من رأس إطار ويب سوكت.
+
+وفق **RFC 6455**، يحتوي هذا البايت على:
+
+- البت 7 (`0x80`): نهائي (FIN).
+- البتات 4-6 (`0x70`): بتات محجوزة، عادةً `0` ما لم تُستخدم امتدادات.
+- البتات 0-3 (`0x0F`): رمز العملية (opcode).
+
+استخرج كل جزء قبل التحقق منه:
+
+```
+عرف رمز_العملية: صـحيح = بتات & 0x0F؛
+عرف نهائي: ثـنائي = (بتات & 0x80) != 0؛
+```
+
+
+
+```alusus
+def opcode: Int = bits & 0x0F;
+def fin: Bool = (bits & 0x80) != 0;
+```
+
+
+
+* قيم `رمز_العملية`:
+ - `1`: إطار نصي
+ - `2`: إطار ثنائي
+ - `8`: إطار إغلاق
+ - `9`: إطار Ping
+ - `10`: إطار Pong
+
+* تكون `نهائي` قيمتها `true` عندما تكون هذه هي الإطار الأخير (أو الوحيد) من الرسالة.
### مـنادى_إغلاق_ويب_سوكت (WebSocketCloseCallback)
@@ -294,12 +320,12 @@ func closeWebSocket(connection: ptr[Connection]): Int;
دالة عند_بيانات_ويب_سوكت(
اتصال: مؤشر[بـننت.اتـصال]،
- رمز_العملية: صـحيح،
+ بتات: صـحيح،
بيانات: مـؤشر_محارف،
طول_البيانات: صـحيح،
بيانات_المستخدم: مؤشر[فـراغ]
): صـحيح {
- إذا رمز_العملية == 1 { // إطار نصي
+ إذا (بتات & 0x0F) == 1 { // إطار نصي
طـرفية.اطبع("تم الاستلام: ")؛
طـرفية.اطبع(بيانات، طول_البيانات)؛
طـرفية.اطبع("\ج")؛
@@ -370,7 +396,7 @@ module WebSocketExample {
};
func onData(connection: ptr[Http.Connection], bits: Int, data: CharsPtr, dataLen: Int, userData: ptr[Void]): Int {
- if bits == 1 { // إطار نصي
+ if (bits & 0x0F) == 1 { // إطار نصي
Console.print("تم الاستلام: ");
Console.print(data, dataLen);
Console.print("\n");
diff --git a/websocket_documentation.en.md b/websocket_documentation.en.md
index 86a5eed..d31402b 100644
--- a/websocket_documentation.en.md
+++ b/websocket_documentation.en.md
@@ -19,29 +19,48 @@ The Alusus HTTP module now includes comprehensive WebSocket support, built on to
## WebSocket Callback Types
### WebSocketConnectCallback
+
```alusus
def WebSocketConnectCallback: alias ptr[func (connection: ptr[Connection], userData: ptr[Void]): Int];
```
Called when a new WebSocket connection is established. Return 0 to accept the connection, non-zero to reject.
### WebSocketReadyCallback
+
```alusus
def WebSocketReadyCallback: alias ptr[func (connection: ptr[Connection], userData: ptr[Void]): Void];
```
Called when the WebSocket connection is ready for communication.
### WebSocketDataCallback
+
```alusus
def WebSocketDataCallback: alias ptr[func (connection: ptr[Connection], bits: Int, data: CharsPtr, dataLen: Int, userData: ptr[Void]): Int];
```
-Called when data is received from the client. The `bits` parameter indicates the frame type:
-- `1`: Text frame
-- `2`: Binary frame
-- `8`: Close frame
-- `9`: Ping frame
-- `10`: Pong frame
+Called when data is received from the client. The `bits` parameter is the raw first byte of the WebSocket frame header, not the frame type by itself. Per RFC 6455, that byte packs at:
+
+- bit 7 (`0x80`): The FIN flag.
+- bits 4-6 (`0x70`): Reserved bits, usually `0` unless extensions are used.
+- bits 0-3 (`0x0F`): The opcode.
+
+Extract each piece before checking it:
+
+```alusus
+def opcode: Int = bits & 0x0F;
+def fin: Bool = (bits & 0x80) != 0;
+```
+
+* `opcode` values:
+ - `1`: Text frame
+ - `2`: Binary frame
+ - `8`: Close frame
+ - `9`: Ping frame
+ - `10`: Pong frame
+
+* `fin` is `true` when this is the final (or only) fragment of the message.
### WebSocketCloseCallback
+
```alusus
def WebSocketCloseCallback: alias ptr[func (connection: ptr[Connection], userData: ptr[Void]): Void];
```
@@ -50,6 +69,7 @@ Called when a WebSocket connection is closed.
## Core Functions
### setWebSocketHandler
+
```alusus
func setWebSocketHandler(
context: ptr[Context],
@@ -73,6 +93,7 @@ Registers WebSocket handlers for a specific URI path.
- `userData`: Optional user data passed to callbacks
### setWebSocketHandlerWithSubprotocols
+
```alusus
func setWebSocketHandlerWithSubprotocols(
context: ptr[Context],
@@ -90,6 +111,7 @@ Same as `setWebSocketHandler` but with support for WebSocket subprotocols.
## Message Sending Functions
### writeToWebSocket
+
```alusus
func writeToWebSocket(connection: ptr[Connection], opcode: Int, data: CharsPtr, dataLen: Int): Int;
```
@@ -103,18 +125,21 @@ Send raw WebSocket frame with specified opcode.
- `10`: Pong frame
### writeTextToWebSocket
+
```alusus
func writeTextToWebSocket(connection: ptr[Connection], data: CharsPtr, dataLen: Int): Int;
```
Send text message to WebSocket client.
### writeBinaryToWebSocket
+
```alusus
func writeBinaryToWebSocket(connection: ptr[Connection], data: CharsPtr, dataLen: Int): Int;
```
Send binary message to WebSocket client.
### closeWebSocket
+
```alusus
func closeWebSocket(connection: ptr[Connection]): Int;
```
@@ -172,7 +197,7 @@ module WebSocketExample {
};
func onData(connection: ptr[Http.Connection], bits: Int, data: CharsPtr, dataLen: Int, userData: ptr[Void]): Int {
- if bits == 1 { // Text frame
+ if (bits & 0x0F) == 1 { // Text frame
Console.print("Received: ");
Console.print(data, dataLen);
Console.print("\n");