<!DOCTYPE html> <html> <head> <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"> <title>class Reactor - TeensyMUD 3.0.0 Mud Server</title> <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet"> <script type="text/javascript"> var rdoc_rel_prefix = "./"; </script> <script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script> <script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script> <script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script> <script type="text/javascript" charset="utf-8" src="./js/search.js"></script> <script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script> <script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script> <body id="top" class="class"> <nav id="metadata"> <nav id="home-section" class="section"> <h3 class="section-header"> <a href="./index.html">Home</a> <a href="./table_of_contents.html#classes">Classes</a> <a href="./table_of_contents.html#methods">Methods</a> </h3> </nav> <nav id="search-section" class="section project-section" class="initially-hidden"> <form action="#" method="get" accept-charset="utf-8"> <h3 class="section-header"> <input type="text" name="search" placeholder="Search" id="search-field" title="Type to search, Up and Down to navigate, Enter to load"> </h3> </form> <ul id="search-results" class="initially-hidden"></ul> </nav> <div id="file-metadata"> <nav id="file-list-section" class="section"> <h3 class="section-header">Defined In</h3> <ul> <li>lib/network/reactor.rb </ul> </nav> </div> <div id="class-metadata"> <nav id="parent-class-section" class="section"> <h3 class="section-header">Parent</h3> <p class="link"><a href="Object.html">Object</a> </nav> <!-- Method Quickref --> <nav id="method-list-section" class="section"> <h3 class="section-header">Methods</h3> <ul class="link-list"> <li><a href="#method-c-new">::new</a> <li><a href="#method-i-poll">#poll</a> <li><a href="#method-i-register">#register</a> <li><a href="#method-i-start">#start</a> <li><a href="#method-i-stop">#stop</a> <li><a href="#method-i-unregister">#unregister</a> </ul> </nav> </div> <div id="project-metadata"> <nav id="fileindex-section" class="section project-section"> <h3 class="section-header">Pages</h3> <ul> <li class="file"><a href="./README.html">README</a> <li class="file"><a href="./TML.html">TML</a> </ul> </nav> <nav id="classindex-section" class="section project-section"> <h3 class="section-header">Class and Module Index</h3> <ul class="link-list"> <li><a href="./Farts.html">Farts</a> <li><a href="./Farts/AttributeSyntaxNode.html">Farts::AttributeSyntaxNode</a> <li><a href="./Farts/CallSyntaxNode.html">Farts::CallSyntaxNode</a> <li><a href="./Farts/CommandSyntaxNode.html">Farts::CommandSyntaxNode</a> <li><a href="./Farts/CommentSyntaxNode.html">Farts::CommentSyntaxNode</a> <li><a href="./Farts/EndSyntaxNode.html">Farts::EndSyntaxNode</a> <li><a href="./Farts/IfSyntaxNode.html">Farts::IfSyntaxNode</a> <li><a href="./Farts/Interpreter.html">Farts::Interpreter</a> <li><a href="./Farts/Lexer.html">Farts::Lexer</a> <li><a href="./Farts/Lib.html">Farts::Lib</a> <li><a href="./Farts/LiteralSyntaxNode.html">Farts::LiteralSyntaxNode</a> <li><a href="./Farts/LocalVarSyntaxNode.html">Farts::LocalVarSyntaxNode</a> <li><a href="./Farts/Parser.html">Farts::Parser</a> <li><a href="./Farts/ProgramSyntaxNode.html">Farts::ProgramSyntaxNode</a> <li><a href="./Farts/SyntaxNode.html">Farts::SyntaxNode</a> <li><a href="./SQLite.html">SQLite</a> <li><a href="./SQLite3.html">SQLite3</a> <li><a href="./SQLite3/Database.html">SQLite3::Database</a> <li><a href="./SQLite/Database.html">SQLite::Database</a> <li><a href="./TernaryTrie.html">TernaryTrie</a> <li><a href="./TernaryTrie/TNode.html">TernaryTrie::TNode</a> <li><a href="./ASCIICodes.html">ASCIICodes</a> <li><a href="./Acceptor.html">Acceptor</a> <li><a href="./Account.html">Account</a> <li><a href="./BoolExpParser.html">BoolExpParser</a> <li><a href="./CacheEntry.html">CacheEntry</a> <li><a href="./CacheManager.html">CacheManager</a> <li><a href="./CacheStats.html">CacheStats</a> <li><a href="./Character.html">Character</a> <li><a href="./Client.html">Client</a> <li><a href="./Cmd.html">Cmd</a> <li><a href="./ColorFilter.html">ColorFilter</a> <li><a href="./Command.html">Command</a> <li><a href="./Configuration.html">Configuration</a> <li><a href="./Connection.html">Connection</a> <li><a href="./Connector.html">Connector</a> <li><a href="./ConsoleClient.html">ConsoleClient</a> <li><a href="./CursesClient.html">CursesClient</a> <li><a href="./DbmStore.html">DbmStore</a> <li><a href="./DebugFilter.html">DebugFilter</a> <li><a href="./Dumper.html">Dumper</a> <li><a href="./Engine.html">Engine</a> <li><a href="./Event.html">Event</a> <li><a href="./EventManager.html">EventManager</a> <li><a href="./Exit.html">Exit</a> <li><a href="./Filter.html">Filter</a> <li><a href="./GameObject.html">GameObject</a> <li><a href="./GdbmStore.html">GdbmStore</a> <li><a href="./LineIO.html">LineIO</a> <li><a href="./Loader.html">Loader</a> <li><a href="./Log.html">Log</a> <li><a href="./Module.html">Module</a> <li><a href="./Obj.html">Obj</a> <li><a href="./ObjCmd.html">ObjCmd</a> <li><a href="./Object.html">Object</a> <li><a href="./PacketIO.html">PacketIO</a> <li><a href="./ProtocolStack.html">ProtocolStack</a> <li><a href="./Publisher.html">Publisher</a> <li><a href="./Reactor.html">Reactor</a> <li><a href="./Room.html">Room</a> <li><a href="./Root.html">Root</a> <li><a href="./Script.html">Script</a> <li><a href="./SdbmStore.html">SdbmStore</a> <li><a href="./Session.html">Session</a> <li><a href="./SockIO.html">SockIO</a> <li><a href="./Sqlite3Store.html">Sqlite3Store</a> <li><a href="./SqliteStore.html">SqliteStore</a> <li><a href="./Store.html">Store</a> <li><a href="./String.html">String</a> <li><a href="./TelnetCodes.html">TelnetCodes</a> <li><a href="./TelnetFilter.html">TelnetFilter</a> <li><a href="./TerminalFilter.html">TerminalFilter</a> <li><a href="./Timer.html">Timer</a> <li><a href="./Utility.html">Utility</a> <li><a href="./VT100Codes.html">VT100Codes</a> <li><a href="./World.html">World</a> <li><a href="./XmlStore.html">XmlStore</a> <li><a href="./YamlStore.html">YamlStore</a> </ul> </nav> </div> </nav> <div id="documentation"> <h1 class="class">class Reactor</h1> <div id="description" class="description"> <p>The <a href="Reactor.html">Reactor</a> class defines a representation of a multiplexer based on a non-blocking select() server.</p> <p>The network design is based on the Mesh project NetworkService code which was translated almost directly from C++, warts and all, which in turn is based on Schmidt’s Acceptor/Connector/Reactor patterns which may be found at <a href="http://citeseer.ist.psu.edu/schmidt97acceptor.html">citeseer.ist.psu.edu/schmidt97acceptor.html</a> for an idea of how all these classes are supposed to interelate.</p> </div><!-- description --> <section id="5Buntitled-5D" class="documentation-section"> <!-- Attributes --> <section id="attribute-method-details" class="method-section section"> <h3 class="section-header">Attributes</h3> <div id="attribute-i-port" class="method-detail"> <div class="method-heading attribute-method-heading"> <span class="method-name">port</span><span class="attribute-access-type">[R]</span> </div> <div class="method-description"> </div> </div> <div id="attribute-i-service_filters" class="method-detail"> <div class="method-heading attribute-method-heading"> <span class="method-name">service_filters</span><span class="attribute-access-type">[R]</span> </div> <div class="method-description"> </div> </div> <div id="attribute-i-service_io" class="method-detail"> <div class="method-heading attribute-method-heading"> <span class="method-name">service_io</span><span class="attribute-access-type">[R]</span> </div> <div class="method-description"> </div> </div> <div id="attribute-i-service_negotiation" class="method-detail"> <div class="method-heading attribute-method-heading"> <span class="method-name">service_negotiation</span><span class="attribute-access-type">[R]</span> </div> <div class="method-description"> </div> </div> <div id="attribute-i-service_type" class="method-detail"> <div class="method-heading attribute-method-heading"> <span class="method-name">service_type</span><span class="attribute-access-type">[R]</span> </div> <div class="method-description"> </div> </div> </section><!-- attribute-method-details --> <!-- Methods --> <section id="public-class-5Buntitled-5D-method-details" class="method-section section"> <h3 class="section-header">Public Class Methods</h3> <div id="method-c-new" class="method-detail "> <div class="method-heading"> <span class="method-name">new</span><span class="method-args">(service_port, service_type, service_io, service_negotiation, service_filters, address=nil)</span> <span class="method-click-advice">click to toggle source</span> </div> <div class="method-description"> <p>Constructor for <a href="Reactor.html">Reactor</a></p> <dl class="rdoc-list label-list"><dt><code>service_port</code> <dd> <p>The port the server will listen on or client will connect to.</p> </dd><dt><code>service_type</code> <dd> <p>The type of service (:server or :client)</p> </dd><dt><code>service_io</code> <dd> <p>The service io handler (:sockio, :lineio, or :packetio)</p> </dd><dt><code>service_negotiation</code> <dd> <p>An array of telnet options the service will try to negotiate</p> </dd></dl> <pre>Valid options are :sga, :echo, :naws, :ttype, :zmp (negotiate default) :binary</pre> <dl class="rdoc-list label-list"><dt><code>service_filters</code> <dd> <p>An array of io filters the service will use.</p> </dd></dl> <pre>Valid options are :filter - attach dummy filter :debugfilter - attach debug filter (default) :telnetfilter - attach telnet filter (default) :colorfilter - attach color filter (default) :terminalfilter - attach terminal filter</pre> <dl class="rdoc-list label-list"><dt><code>address</code> <dd> <p>Optional address for outgoing connection.</p> </dd></dl> <div class="method-source-code" id="new-source"> <pre><span class="ruby-comment"># File lib/network/reactor.rb, line 55</span> <span class="ruby-keyword">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">service_port</span>, <span class="ruby-identifier">service_type</span>, <span class="ruby-identifier">service_io</span>, <span class="ruby-identifier">service_negotiation</span>, <span class="ruby-identifier">service_filters</span>, <span class="ruby-identifier">address</span>=<span class="ruby-keyword">nil</span>) <span class="ruby-ivar">@port</span> = <span class="ruby-identifier">service_port</span> <span class="ruby-comment"># port server will listen on</span> <span class="ruby-ivar">@shutdown</span> = <span class="ruby-keyword">false</span> <span class="ruby-comment"># Flag to indicate that server is shutting down.</span> <span class="ruby-ivar">@acceptor</span> = <span class="ruby-keyword">nil</span> <span class="ruby-comment"># Listening socket for incoming connections.</span> <span class="ruby-ivar">@connector</span> = <span class="ruby-keyword">nil</span> <span class="ruby-comment"># Connecting socket for outgoing connections.</span> <span class="ruby-ivar">@registry</span> = [] <span class="ruby-comment"># list of sessions</span> <span class="ruby-ivar">@address</span> = <span class="ruby-identifier">address</span> <span class="ruby-comment"># Address for Connector.</span> <span class="ruby-ivar">@service_type</span> = <span class="ruby-identifier">service_type</span> <span class="ruby-ivar">@service_io</span> = <span class="ruby-identifier">service_io</span> <span class="ruby-ivar">@service_negotiation</span> = <span class="ruby-identifier">service_negotiation</span> <span class="ruby-ivar">@service_filters</span> = <span class="ruby-identifier">service_filters</span> <span class="ruby-identifier">log</span>.<span class="ruby-identifier">debug</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier">inspect</span> <span class="ruby-keyword">end</span></pre> </div><!-- new-source --> </div> </div><!-- new-method --> </section><!-- public-class-method-details --> <section id="public-instance-5Buntitled-5D-method-details" class="method-section section"> <h3 class="section-header">Public Instance Methods</h3> <div id="method-i-poll" class="method-detail "> <div class="method-heading"> <span class="method-name">poll</span><span class="method-args">(tm_out)</span> <span class="method-click-advice">click to toggle source</span> </div> <div class="method-description"> <p>poll starts the <a href="Reactor.html">Reactor</a> running to process incoming connection, input and output requests. It also executes commands from input requests.</p> <dl class="rdoc-list label-list"><dt>+tm_out* <dd> <p>time to poll in seconds</p> </dd></dl> <div class="method-source-code" id="poll-source"> <pre><span class="ruby-comment"># File lib/network/reactor.rb, line 107</span> <span class="ruby-keyword">def</span> <span class="ruby-identifier">poll</span>(<span class="ruby-identifier">tm_out</span>) <span class="ruby-comment"># Reset our socket interest set</span> <span class="ruby-identifier">infds</span> = [];<span class="ruby-identifier">outfds</span> = [];<span class="ruby-identifier">oobfds</span> = [] <span class="ruby-ivar">@registry</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">is_readable?</span> <span class="ruby-identifier">infds</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">sock</span> <span class="ruby-identifier">oobfds</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">sock</span> <span class="ruby-keyword">end</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">is_writable?</span> <span class="ruby-identifier">outfds</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">sock</span> <span class="ruby-keyword">end</span> <span class="ruby-keyword">end</span> <span class="ruby-comment"># Poll our socket interest set</span> <span class="ruby-identifier">infds</span>,<span class="ruby-identifier">outfds</span>,<span class="ruby-identifier">oobfds</span> = <span class="ruby-identifier">select</span>(<span class="ruby-identifier">infds</span>, <span class="ruby-identifier">outfds</span>, <span class="ruby-identifier">oobfds</span>, <span class="ruby-identifier">tm_out</span>) <span class="ruby-comment"># Dispatch events to handlers</span> <span class="ruby-ivar">@registry</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">handle_output</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">outfds</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">outfds</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">s</span>.<span class="ruby-identifier">sock</span>) <span class="ruby-identifier">s</span>.<span class="ruby-identifier">handle_oob</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">oobfds</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">oobfds</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">s</span>.<span class="ruby-identifier">sock</span>) <span class="ruby-identifier">s</span>.<span class="ruby-identifier">handle_input</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">infds</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">infds</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">s</span>.<span class="ruby-identifier">sock</span>) <span class="ruby-identifier">s</span>.<span class="ruby-identifier">handle_close</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">closing</span> <span class="ruby-comment"># special handling for Telnet initialization</span> <span class="ruby-keyword">if</span> <span class="ruby-ivar">@service_filters</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-value">:telnetfilter</span>) <span class="ruby-operator">&&</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">respond_to?</span>(<span class="ruby-value">:initdone</span>) <span class="ruby-operator">&&</span> <span class="ruby-operator">!</span><span class="ruby-identifier">s</span>.<span class="ruby-identifier">initdone</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">pstack</span>.<span class="ruby-identifier">set</span>(<span class="ruby-value">:init_subneg</span>, <span class="ruby-keyword">true</span>) <span class="ruby-keyword">end</span> <span class="ruby-keyword">end</span> <span class="ruby-keyword">rescue</span> <span class="ruby-identifier">log</span>.<span class="ruby-identifier">error</span> <span class="ruby-node">"Reactor#poll"</span> <span class="ruby-identifier">log</span>.<span class="ruby-identifier">error</span> <span class="ruby-identifier">$!</span> <span class="ruby-identifier">raise</span> <span class="ruby-keyword">end</span></pre> </div><!-- poll-source --> </div> </div><!-- poll-method --> <div id="method-i-register" class="method-detail "> <div class="method-heading"> <span class="method-name">register</span><span class="method-args">(session)</span> <span class="method-click-advice">click to toggle source</span> </div> <div class="method-description"> <p>register adds a session to the registry</p> <dl class="rdoc-list label-list"><dt><code>session</code> <dd></dd></dl> <div class="method-source-code" id="register-source"> <pre><span class="ruby-comment"># File lib/network/reactor.rb, line 143</span> <span class="ruby-keyword">def</span> <span class="ruby-identifier">register</span>(<span class="ruby-identifier">session</span>) <span class="ruby-ivar">@registry</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">session</span> <span class="ruby-keyword">end</span></pre> </div><!-- register-source --> </div> </div><!-- register-method --> <div id="method-i-start" class="method-detail "> <div class="method-heading"> <span class="method-name">start</span><span class="method-args">(engine)</span> <span class="method-click-advice">click to toggle source</span> </div> <div class="method-description"> <p>Start initializes the reactor and gets it ready to accept incoming connections.</p> <dl class="rdoc-list label-list"><dt><code>engine</code> <dd> <p>The client engine that will be observing the acceptor.</p> </dd><dt><code>return</code>' <dd> <p>true if server boots correctly, false if an error occurs.</p> </dd></dl> <div class="method-source-code" id="start-source"> <pre><span class="ruby-comment"># File lib/network/reactor.rb, line 75</span> <span class="ruby-keyword">def</span> <span class="ruby-identifier">start</span>(<span class="ruby-identifier">engine</span>) <span class="ruby-comment"># Create an acceptor to listen for this server.</span> <span class="ruby-keyword">if</span> <span class="ruby-ivar">@service_type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:client</span> <span class="ruby-ivar">@connector</span> = <span class="ruby-constant">Connector</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword">self</span>, <span class="ruby-ivar">@address</span>) <span class="ruby-ivar">@connector</span>.<span class="ruby-identifier">subscribe</span>(<span class="ruby-identifier">engine</span>) <span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span> <span class="ruby-keyword">if</span> <span class="ruby-operator">!</span><span class="ruby-ivar">@connector</span>.<span class="ruby-identifier">init</span> <span class="ruby-keyword">else</span> <span class="ruby-ivar">@acceptor</span> = <span class="ruby-constant">Acceptor</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword">self</span>) <span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span> <span class="ruby-keyword">if</span> <span class="ruby-operator">!</span><span class="ruby-ivar">@acceptor</span>.<span class="ruby-identifier">init</span> <span class="ruby-ivar">@acceptor</span>.<span class="ruby-identifier">subscribe</span>(<span class="ruby-identifier">engine</span>) <span class="ruby-keyword">end</span> <span class="ruby-keyword">true</span> <span class="ruby-keyword">rescue</span> <span class="ruby-identifier">log</span>.<span class="ruby-identifier">error</span> <span class="ruby-node">"Reactor#start"</span> <span class="ruby-identifier">log</span>.<span class="ruby-identifier">error</span> <span class="ruby-identifier">$!</span> <span class="ruby-keyword">false</span> <span class="ruby-keyword">end</span></pre> </div><!-- start-source --> </div> </div><!-- start-method --> <div id="method-i-stop" class="method-detail "> <div class="method-heading"> <span class="method-name">stop</span><span class="method-args">()</span> <span class="method-click-advice">click to toggle source</span> </div> <div class="method-description"> <p>stop requests each of the connections to disconnect in the server’s user list, deletes the connections, and erases them from the user list. It then closes its own listening port.</p> <div class="method-source-code" id="stop-source"> <pre><span class="ruby-comment"># File lib/network/reactor.rb, line 96</span> <span class="ruby-keyword">def</span> <span class="ruby-identifier">stop</span> <span class="ruby-ivar">@registry</span>.<span class="ruby-identifier">each</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">closing</span> = <span class="ruby-keyword">true</span>} <span class="ruby-ivar">@acceptor</span>.<span class="ruby-identifier">unsubscribe_all</span> <span class="ruby-keyword">if</span> <span class="ruby-ivar">@acceptor</span> <span class="ruby-ivar">@connector</span>.<span class="ruby-identifier">unsubscribe_all</span> <span class="ruby-keyword">if</span> <span class="ruby-ivar">@connector</span> <span class="ruby-identifier">log</span>.<span class="ruby-identifier">info</span> <span class="ruby-node">"Reactor#shutdown: Reactor shutting down"</span> <span class="ruby-comment"># log.close</span> <span class="ruby-keyword">end</span></pre> </div><!-- stop-source --> </div> </div><!-- stop-method --> <div id="method-i-unregister" class="method-detail "> <div class="method-heading"> <span class="method-name">unregister</span><span class="method-args">(session)</span> <span class="method-click-advice">click to toggle source</span> </div> <div class="method-description"> <p>unregister removes a session from the registry</p> <dl class="rdoc-list label-list"><dt><code>session</code> <dd></dd></dl> <div class="method-source-code" id="unregister-source"> <pre><span class="ruby-comment"># File lib/network/reactor.rb, line 149</span> <span class="ruby-keyword">def</span> <span class="ruby-identifier">unregister</span>(<span class="ruby-identifier">session</span>) <span class="ruby-ivar">@registry</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">session</span>) <span class="ruby-keyword">end</span></pre> </div><!-- unregister-source --> </div> </div><!-- unregister-method --> </section><!-- public-instance-method-details --> </section><!-- 5Buntitled-5D --> </div><!-- documentation --> <footer id="validator-badges"> <p><a href="http://validator.w3.org/check/referer">[Validate]</a> <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 3.12.1. <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3. </footer>