\n <\/td>\n | # The Rack Application container<\/span><\/td>\n <\/tr>\n \n <\/td>\n | module<\/span> MyRackApplication<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # Rack applications use the \`call\` callback to handle HTTP requests.<\/span><\/td>\n <\/tr>\n \n <\/td>\n | def<\/span> self<\/span>.<\/span>call<\/span>(<\/span>env<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # if upgrading...<\/span><\/td>\n <\/tr>\n \n <\/td>\n | if<\/span> env<\/span>[<\/span>'HTTP_UPGRADE'<\/span>.<\/span>freeze<\/span>]<\/span> =~ /websocket/i<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # We can assign a class or an instance that implements callbacks.<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # We will assign an object, passing it the request information (\`env\`)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | env<\/span>[<\/span>'upgrade.websocket'<\/span>.<\/span>freeze<\/span>]<\/span> =<\/span> MyWebsocket<\/span>.<\/span>new<\/span>(<\/span>env<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # Rack responses must be a 3 item array with [status, {http: :headers}, ["response body"]]<\/span><\/td>\n <\/tr>\n \n <\/td>\n | return<\/span> [<\/span>0<\/span>,<\/span> {<\/span>}<\/span>,<\/span> [<\/span>]<\/span>]<\/span><\/td>\n <\/tr>\n \n <\/td>\n | end<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # a semi-regualr HTTP response<\/span><\/td>\n <\/tr>\n \n <\/td>\n | out<\/span> =<\/span> File<\/span>.<\/span>open<\/span> File<\/span>.<\/span>expand_path<\/span>(<\/span>'../index.html'<\/span>,<\/span> __FILE__<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | [<\/span>200<\/span>,<\/span> {<\/span> 'X-Sendfile'<\/span> =><\/span> File<\/span>.<\/span>expand_path<\/span>(<\/span>'../index.html'<\/span>,<\/span> __FILE__<\/span>)<\/span>,<\/span> 'Content-Length'<\/span> =><\/span> out<\/span>.<\/span>size<\/span> }<\/span>,<\/span> out<\/span>]<\/span><\/td>\n <\/tr>\n \n <\/td>\n | end<\/span><\/td>\n <\/tr>\n \n <\/td>\n | end<\/span><\/td>\n <\/tr>\n \n <\/td>\n | \n<\/td>\n <\/tr>\n | \n <\/td>\n | # The Websocket Callback Object<\/span><\/td>\n <\/tr>\n \n <\/td>\n | class<\/span> MyWebsocket<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # this is optional, but I wanted the object to have the nickname provided in<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # the HTTP request<\/span><\/td>\n <\/tr>\n \n <\/td>\n | def<\/span> initialize<\/span>(<\/span>env<\/span>)<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # we need to change the ASCI Rack encoding to UTF-8,<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # otherwise everything with the nickname will be a binary "blob" in the<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # Javascript layer<\/span><\/td>\n <\/tr>\n \n <\/td>\n | @nickname<\/span> =<\/span> env<\/span>[<\/span>'PATH_INFO'<\/span>]<\/span>[<\/span>1<\/span>..-1<\/span>]<\/span>.<\/span>force_encoding<\/span> 'UTF-8'<\/span><\/td>\n <\/tr>\n \n <\/td>\n | end<\/span><\/td>\n <\/tr>\n \n <\/td>\n | \n<\/td>\n <\/tr>\n | \n <\/td>\n | # A classic websocket callback, called when the connection is opened and<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # linked to this object<\/span><\/td>\n <\/tr>\n \n <\/td>\n | def<\/span> on_open<\/span><\/td>\n <\/tr>\n \n <\/td>\n | puts<\/span> 'We have a websocket connection'<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # iodine supports native pub/sub, using subscribe we listen to incoming data on the chat channel<\/span><\/td>\n <\/tr>\n \n <\/td>\n | subscribe<\/span> channel<\/span>: "chat"<\/span><\/td>\n <\/tr>\n \n <\/td>\n | end<\/span><\/td>\n <\/tr>\n \n <\/td>\n | \n<\/td>\n <\/tr>\n | \n <\/td>\n | # A classic websocket callback, called when the connection is closed<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # (after disconnection).<\/span><\/td>\n <\/tr>\n \n <\/td>\n | def<\/span> on_close<\/span><\/td>\n <\/tr>\n \n <\/td>\n | puts<\/span> "Bye Bye... #{<\/span>count<\/span>}<\/span><\/span> connections left..."<\/span><\/td>\n <\/tr>\n \n <\/td>\n | end<\/span><\/td>\n <\/tr>\n \n <\/td>\n | \n<\/td>\n <\/tr>\n | \n <\/td>\n | # A server-side niceness, called when the server if shutting down,<\/span><\/td>\n <\/tr>\n \n <\/td>\n | # to gracefully disconnect (before disconnection).<\/span><\/td>\n <\/tr>\n \n <\/td>\n | def<\/span> on_shutdown<\/span><\/td>\n <\/tr>\n \n <\/td>\n | write<\/span> 'The server is shutting down, goodbye.'<\/span><\/td>\n <\/tr>\n \n <\/td>\n | end<\/span><\/td>\n <\/tr>\n \n <\/td>\n | \n<\/td>\n <\/tr>\n | \n <\/td>\n | def<\/span> on_message<\/span> | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |