diff --git a/examples/websocket/application_execution.e b/examples/websocket/application_execution.e index 506bbedf..295411bd 100644 --- a/examples/websocket/application_execution.e +++ b/examples/websocket/application_execution.e @@ -10,6 +10,9 @@ inherit WSF_WEBSOCKET_EXECUTION WEB_SOCKET_EVENT_I + redefine + on_timer + end create make @@ -52,6 +55,9 @@ feature -- Websocket execution on_open (ws: WEB_SOCKET) do + initialize_commands + set_timer_delay (1) -- Every 1 second. + ws.put_error ("Connecting") ws.send (Text_frame, "Hello, this is a simple demo with Websocket using Eiffel. (/help for more information).%N") end @@ -62,12 +68,26 @@ feature -- Websocket execution end on_text (ws: WEB_SOCKET; a_message: READABLE_STRING_8) + local + i: INTEGER + cmd_name: READABLE_STRING_8 do - if a_message.same_string_general ("/help") then - -- Echo the message for testing. - ws.send (Text_frame, "Help: available commands%N - /time : return the server UTC time.%N") - elseif a_message.starts_with_general ("/time") then - ws.send (Text_frame, "Server time is " + (create {HTTP_DATE}.make_now_utc).string) + if a_message.starts_with_general ("/") then + from + i := 1 + until + i >= a_message.count or else a_message[i + 1].is_space + loop + i := i + 1 + end + cmd_name := a_message.substring (2, i) + if attached command (cmd_name) as cmd then + cmd (ws, a_message.substring (i + 1, a_message.count)) + elseif a_message.same_string_general ("/help") then + on_help_command (ws, Void) + else + ws.send (Text_frame, "Error: unknown command '/" + cmd_name + "'!%N") + end else -- Echo the message for testing. ws.send (Text_frame, a_message) @@ -80,6 +100,88 @@ feature -- Websocket execution ws.put_error ("Connection closed") end + on_timer (ws: WEB_SOCKET) + -- . + -- If ever the file ".stop" exists, stop gracefully the connection. + local + fut: FILE_UTILITIES + f: RAW_FILE + do + if fut.file_exists (".stop") then + ws.send_text ("End of the communication ...%N") + ws.send_connection_close ("") + create f.make_with_name (".stop") + f.delete + end + end + +feature -- Command + + initialize_commands + do + register_command (agent on_help_command, "help", "Display this help.") + register_command (agent on_time_command, "time", "Return the server UTC time.") + register_command (agent on_shutdown_command, "shutdown", "Shutdown the service (ends the websocket).") + end + + register_command (a_cmd: attached like command; a_name: READABLE_STRING_8; a_description: READABLE_STRING_8) + local + tb: like commands + do + tb := commands + if tb = Void then + create tb.make_caseless (1) + commands := tb + end + tb.force ([a_cmd, a_name, a_description], a_name) + end + + commands: detachable STRING_TABLE [TUPLE [cmd: attached like command; name, description: READABLE_STRING_8]] + + command (a_name: READABLE_STRING_GENERAL): detachable PROCEDURE [TUPLE [ws: WEB_SOCKET; args: detachable READABLE_STRING_GENERAL]] + do + if + attached commands as tb and then + attached tb.item (a_name) as d + then + Result := d.cmd + end + end + + on_help_command (ws: WEB_SOCKET; args: detachable READABLE_STRING_GENERAL) + local + s: STRING + do + create s.make_from_string ("Help: available commands:%N") + if attached commands as tb then + across + tb as ic + loop + s.append ("
  • /") + s.append (ic.item.name) + s.append (" : ") + s.append (ic.item.description) + s.append ("
  • %N") + end + end + ws.send_text (s) + end + + on_time_command (ws: WEB_SOCKET; args: detachable READABLE_STRING_GENERAL) + do + ws.send_text ("Server time is " + (create {HTTP_DATE}.make_now_utc).string) + end + + on_shutdown_command (ws: WEB_SOCKET; args: detachable READABLE_STRING_GENERAL) + local + f: RAW_FILE + do + ws.send_text ("Active websockets will end soon.%N") + create f.make_create_read_write (".stop") + f.put_string ("stop%N") + f.close + end + feature -- HTML Resource websocket_app_html (a_port: INTEGER): STRING @@ -188,5 +290,4 @@ body {font-family:Arial, Helvetica, sans-serif;} end end - end