Use new on_timer solution, to check every 1 second, the presence of ".stop" file.
If this file exists, close all active websockets. Redesigned the commands implementation for this example.
This commit is contained in:
@@ -10,6 +10,9 @@ inherit
|
|||||||
WSF_WEBSOCKET_EXECUTION
|
WSF_WEBSOCKET_EXECUTION
|
||||||
|
|
||||||
WEB_SOCKET_EVENT_I
|
WEB_SOCKET_EVENT_I
|
||||||
|
redefine
|
||||||
|
on_timer
|
||||||
|
end
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -52,6 +55,9 @@ feature -- Websocket execution
|
|||||||
|
|
||||||
on_open (ws: WEB_SOCKET)
|
on_open (ws: WEB_SOCKET)
|
||||||
do
|
do
|
||||||
|
initialize_commands
|
||||||
|
set_timer_delay (1) -- Every 1 second.
|
||||||
|
|
||||||
ws.put_error ("Connecting")
|
ws.put_error ("Connecting")
|
||||||
ws.send (Text_frame, "Hello, this is a simple demo with Websocket using Eiffel. (/help for more information).%N")
|
ws.send (Text_frame, "Hello, this is a simple demo with Websocket using Eiffel. (/help for more information).%N")
|
||||||
end
|
end
|
||||||
@@ -62,12 +68,26 @@ feature -- Websocket execution
|
|||||||
end
|
end
|
||||||
|
|
||||||
on_text (ws: WEB_SOCKET; a_message: READABLE_STRING_8)
|
on_text (ws: WEB_SOCKET; a_message: READABLE_STRING_8)
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
cmd_name: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
if a_message.same_string_general ("/help") then
|
if a_message.starts_with_general ("/") then
|
||||||
-- Echo the message for testing.
|
from
|
||||||
ws.send (Text_frame, "Help: available commands%N - /time : return the server UTC time.%N")
|
i := 1
|
||||||
elseif a_message.starts_with_general ("/time") then
|
until
|
||||||
ws.send (Text_frame, "Server time is " + (create {HTTP_DATE}.make_now_utc).string)
|
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
|
else
|
||||||
-- Echo the message for testing.
|
-- Echo the message for testing.
|
||||||
ws.send (Text_frame, a_message)
|
ws.send (Text_frame, a_message)
|
||||||
@@ -80,6 +100,88 @@ feature -- Websocket execution
|
|||||||
ws.put_error ("Connection closed")
|
ws.put_error ("Connection closed")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
on_timer (ws: WEB_SOCKET)
|
||||||
|
-- <Precursor>.
|
||||||
|
-- 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 ("<li> /")
|
||||||
|
s.append (ic.item.name)
|
||||||
|
s.append (" : ")
|
||||||
|
s.append (ic.item.description)
|
||||||
|
s.append ("</li>%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
|
feature -- HTML Resource
|
||||||
|
|
||||||
websocket_app_html (a_port: INTEGER): STRING
|
websocket_app_html (a_port: INTEGER): STRING
|
||||||
@@ -188,5 +290,4 @@ body {font-family:Arial, Helvetica, sans-serif;}
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user