Created
July 1, 2024 00:12
-
-
Save gesslar/4cfba19c33b66b675cc63906f8354419 to your computer and use it in GitHub Desktop.
Basic example of using websocket to connect to echo.websocket.org (https://echo.websocket.org/)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// /adm/daemons/websocket_echo.c | |
// Test websocket with echo.websocket.org | |
// | |
// Created: 2024/06/30: Gesslar | |
// Last Change: 2024/06/30: Gesslar | |
// | |
// 2024/06/30: Gesslar - Created | |
#include <daemons.h> | |
#include <websocket.h> | |
#include <net/socket.h> | |
#include <net/socket_errors.h> | |
inherit WEBSOCKET_D ; | |
private nosave mapping handles = ([ ]) ; | |
private nosave string host = "echo.websocket.org" ; | |
private nosave string path = UNDEFINED ; | |
private nosave string server_name = "WebSocket Echo Server" ; | |
void periodic_message(int fd) ; | |
void send_outgoing_message(int fd, string message) ; | |
void close_down_session(int fd) ; | |
void setup() { | |
log_level = 1 ; | |
} | |
// Start the Connection | |
varargs void startup() { | |
ws_connect(host, path) ; | |
} | |
void handle_connected(int fd) { | |
mapping curr = ([ ]) ; | |
int closing_time = 15+random(15) ; | |
curr["host"] = ws_get_host(fd) ; | |
curr["port"] = ws_get_port(fd) ; | |
_log(2, "Scheduling periodic messaging") ; | |
curr["messaging"] = call_out_walltime((: periodic_message, fd :), 5) ; | |
_log(2, "Scheduling close down in %d seconds", closing_time) ; | |
curr["closing"] = call_out_walltime((: close_down_session, fd :), closing_time) ; | |
handles[fd] = curr ; | |
} | |
void handle_shutdown(int fd, mapping info) { | |
mapping curr ; | |
int messaging, closing ; | |
if(!handles[fd]) { | |
_log(2, "No handle for fd %d\n", fd) ; | |
return ; | |
} | |
messaging = handles[fd]["messaging"] ; | |
if(!nullp(messaging)) { | |
if(find_call_out(messaging) != -1) { | |
_log(1, "Stopping automatic messaging") ; | |
remove_call_out(messaging) ; | |
} | |
} | |
closing = handles[fd]["closing"] ; | |
if(!nullp(closing)) { | |
if(find_call_out(closing) != -1) { | |
_log(1, "Stopping automatic close down") ; | |
remove_call_out(closing) ; | |
} | |
} | |
curr = handles[fd] ; | |
map_delete(handles, fd); | |
} | |
// Function to parse text frames | |
void handle_text_frame(int fd, mapping frame_info) { | |
string payload ; | |
mixed message ; | |
if(!frame_info) { | |
_log(2, "No frame info\n") ; | |
return ; | |
} | |
payload = to_string(frame_info["payload"]); | |
message = REST_D->determine_response_payload(payload) ; | |
if(!stringp(message)) { | |
_log(2, "Received non-string payload: %O\n", message) ; | |
return ; | |
} | |
_log(1, "Received message: %O\n", message) ; | |
} | |
void periodic_message(int fd) { | |
int messaging = handles[fd]["messaging"] ; | |
if(find_call_out(messaging) != -1) { | |
_log(1, "Canceling existing messaging schedule") ; | |
remove_call_out(messaging) ; | |
} | |
_log(2, "Sending periodic message") ; | |
send_outgoing_message(fd, "Hello, world - " + base64encode(""+time())) ; | |
_log(2, "Scheduling next message") ; | |
handles[fd]["messaging"] = call_out_walltime((: periodic_message, fd :), 10+random(20)) ; | |
} | |
void send_outgoing_message(int fd, string message) { | |
_log(1, "Sending message: %O\n", message) ; | |
if(!send_message(fd, WS_TEXT_FRAME, message)) | |
_log(1, "Failed to send message") ; | |
} | |
void close_down_session(int fd) { | |
_log(1, "Automatically closing down session") ; | |
if(!send_message(fd, WS_CLOSE_FRAME, WS_CLOSE_NORMAL, "Self-initiated close down")) | |
_log(1, "Failed to send close frame") ; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2024/06/30 17:32:21 ws_connect - Setting up socket | |
2024/06/30 17:32:21 ws_on_resolve - Host Resolved Host: echo.websocket.org, Addr: 66.241.124.119 | |
2024/06/30 17:32:21 ws_on_resolve - Connecting to echo.websocket.org | |
2024/06/30 17:32:21 ws_write_data - Socket fully connected, now able to send data | |
2024/06/30 17:32:21 ws_write_data - Handshake request sent | |
2024/06/30 17:32:21 ws_receive_data - =========== STARTING WS TRANSACTION 1 =========== | |
2024/06/30 17:32:21 ws_receive_data - Incoming size: 266 | |
2024/06/30 17:32:21 ws_receive_data - Buffer size: 266 | |
2024/06/30 17:32:21 Ok listen: ({ 15, "LISTEN", "STREAM", "*.8282", "", OBJ(/adm/daemons/rest) }) | |
2024/06/30 17:32:21 ws_receive_data - Headers processed. Remaining buffer size: 0 | |
2024/06/30 17:32:21 handle_handshake - ===== VALIDATING WEBSOCKET HANDSHAKE ===== | |
2024/06/30 17:32:21 handle_handshake - HTTP Status Code: 101 | |
2024/06/30 17:32:21 handle_handshake - Header 'upgrade': websocket | |
2024/06/30 17:32:21 handle_handshake - Header 'Connection': upgrade | |
2024/06/30 17:32:21 handle_handshake - Generated Key: C9KmJmLjIeZrgmQj | |
2024/06/30 17:32:21 handle_handshake - Base64 Encoded SHA-1 Hash (Expected): AfLYkK4OpeKucLEadA4pX2f6qYg= | |
2024/06/30 17:32:21 handle_handshake - Header 'sec-websocket-accept': AfLYkK4OpeKucLEadA4pX2f6qYg= | |
2024/06/30 17:32:21 handle_handshake - ===== WEBSOCKET HANDSHAKE SUCCESS ===== | |
2024/06/30 17:32:21 handle_connected - Connected to WebSocket Echo Server | |
2024/06/30 17:32:21 handle_connected - Scheduling periodic messaging | |
2024/06/30 17:32:21 handle_connected - Sheduling close down in 24 seconds | |
2024/06/30 17:32:21 ws_receive_data - =========== STARTING WS TRANSACTION 2 =========== | |
2024/06/30 17:32:21 ws_receive_data - Incoming size: 34 | |
2024/06/30 17:32:21 ws_receive_data - Buffer size: 34 | |
2024/06/30 17:32:21 ws_receive_data - Processing WebSocket data | |
2024/06/30 17:32:21 is_message_complete - Enough data for the full payload | |
2024/06/30 17:32:21 parse_websocket_frame - Initial frame details - fin: 128, opcode: 1, masked: 0, payload_length: 32 | |
2024/06/30 17:32:21 parse_websocket_frame - Processed payload length: 32, offset: 2 | |
2024/06/30 17:32:21 parse_websocket_frame - Payload unmasked or copied | |
2024/06/30 17:32:21 parse_websocket_frame - Offset: 2, Payload Length: 32, Buffer Size: 34 | |
2024/06/30 17:32:21 parse_websocket_frame - Remaining buffer size: 0 | |
2024/06/30 17:32:21 process_websocket - Received text frame: Request served by 7811941c69e658 | |
2024/06/30 17:32:21 process_text_frame - Payload: Request served by 7811941c69e658 | |
2024/06/30 17:32:21 handle_text_frame - Received text frame: "Request served by 7811941c69e658" | |
2024/06/30 17:32:26 periodic_message - Sending periodic message | |
2024/06/30 17:32:26 send_message - Frame type: 1, Message: ({ /* sizeof() == 1 */ | |
"Hello, world - MTcxOTc4MzE0Ng==" | |
}) | |
2024/06/30 17:32:26 send_message - Binary frame: "0x81, 0x9f, 0x7f, 0x51, 0x17, 0xa5, 0x37, 0x34, 0x7b, 0xc9, 0x10, 0x7d, 0x37, 0xd2, 0x10, 0x23, 0x7b, 0xc1, 0x5f, 0x7c, 0x37, 0xe8, 0x2b, 0x32, 0x6f, 0xea, 0x2b, 0x32, 0x23, 0xe8, 0x05, 0x14, 0x27, 0xeb, 0x18, 0x6c, 0x2a" | |
2024/06/30 17:32:26 send_message - Sent message to echo.websocket.org | |
2024/06/30 17:32:26 periodic_message - Scheduling next message | |
2024/06/30 17:32:26 ws_receive_data - =========== STARTING WS TRANSACTION 3 =========== | |
2024/06/30 17:32:26 ws_receive_data - Incoming size: 33 | |
2024/06/30 17:32:26 ws_receive_data - Buffer size: 33 | |
2024/06/30 17:32:26 ws_receive_data - Processing WebSocket data | |
2024/06/30 17:32:26 is_message_complete - Enough data for the full payload | |
2024/06/30 17:32:26 parse_websocket_frame - Initial frame details - fin: 128, opcode: 1, masked: 0, payload_length: 31 | |
2024/06/30 17:32:26 parse_websocket_frame - Processed payload length: 31, offset: 2 | |
2024/06/30 17:32:26 parse_websocket_frame - Payload unmasked or copied | |
2024/06/30 17:32:26 parse_websocket_frame - Offset: 2, Payload Length: 31, Buffer Size: 33 | |
2024/06/30 17:32:26 parse_websocket_frame - Remaining buffer size: 0 | |
2024/06/30 17:32:26 process_websocket - Received text frame: Hello, world - MTcxOTc4MzE0Ng== | |
2024/06/30 17:32:26 process_text_frame - Payload: Hello, world - MTcxOTc4MzE0Ng== | |
2024/06/30 17:32:26 handle_text_frame - Received text frame: "Hello, world - MTcxOTc4MzE0Ng==" | |
2024/06/30 17:32:45 close_down_session - Closing down session | |
2024/06/30 17:32:45 send_message - Frame type: 8, Message: ({ /* sizeof() == 2 */ | |
1000, | |
"Self-initiated close down" | |
}) | |
2024/06/30 17:32:45 send_message - Binary frame: "0x88, 0x9b, 0xa9, 0x88, 0xf0, 0x8b, 0xaa, 0x60, 0xa3, 0xee, 0xc5, 0xee, 0xdd, 0xe2, 0xc7, 0xe1, 0x84, 0xe2, 0xc8, 0xfc, 0x95, 0xef, 0x89, 0xeb, 0x9c, 0xe4, 0xda, 0xed, 0xd0, 0xef, 0xc6, 0xff, 0x9e" | |
2024/06/30 17:32:45 send_message - Sent message to echo.websocket.org | |
2024/06/30 17:32:45 ws_receive_data - =========== STARTING WS TRANSACTION 4 =========== | |
2024/06/30 17:32:45 ws_receive_data - Incoming size: 4 | |
2024/06/30 17:32:45 ws_receive_data - Buffer size: 4 | |
2024/06/30 17:32:45 ws_receive_data - Processing WebSocket data | |
2024/06/30 17:32:45 is_message_complete - Enough data for the full payload | |
2024/06/30 17:32:45 parse_websocket_frame - Initial frame details - fin: 128, opcode: 8, masked: 0, payload_length: 2 | |
2024/06/30 17:32:45 parse_websocket_frame - Processed payload length: 2, offset: 2 | |
2024/06/30 17:32:45 parse_websocket_frame - Payload unmasked or copied | |
2024/06/30 17:32:45 parse_websocket_frame - Offset: 2, Payload Length: 2, Buffer Size: 4 | |
2024/06/30 17:32:45 parse_websocket_frame - Remaining buffer size: 0 | |
2024/06/30 17:32:45 process_websocket - Received close frame: "0x03, 0xe8" | |
2024/06/30 17:32:45 process_close_frame - Connection closed by server. Code: 1000, Reason: | |
2024/06/30 17:32:45 handle_shutdown - Stopping automatic messaging | |
2024/06/30 17:32:45 ws_socket_shutdown - Shutting down socket after 24.43 seconds |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment