Top Level Namespace
Defined Under Namespace
Classes: MqttSN
Instance Method Summary collapse
Instance Method Details
#http_server(options) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/mqtt-sn-http.rb', line 7 def http_server prev_t={} ports=['127.0.0.1'] if Socket.method_defined? :getifaddrs ports=Socket.getifaddrs.map { |i| i.addr.ip_address if i.addr.ipv4? }.compact puts "Starting HTTP services at port #{[:http_port]}, server IPs: #{ports}" else puts "Starting HTTP services at port #{[:http_port]}." end if File.directory? './http' $http_dir="http/" else $http_dir = File.join( Gem.loaded_specs['mqtt-sn-ruby'].full_gem_path, 'http/') end Thread.new([:http_port],[:app_name]) do |http_port,http_app| server = TCPServer.new("0.0.0.0",http_port) @http_sessions={} http_session_counter=1 loop do Thread.start(server.accept) do |client| begin request = client.gets.split " " status="200 OK" type="text/html" req=request[1] req="/#{http_app}.html" if req=="/" or req=="/index.htm" or req=="/index.html" req,argss=req.split "\?" #puts "req: #{req}, agss:#{argss}" args={} if argss argss.split("&").each do |a| if a k,v=URI.decode(a).force_encoding("UTF-8").split "=" args[k]=v end end end #puts "req: #{req}, args:#{args}" if req[/\.html$/] and File.file?(fn="#{$http_dir}haml#{req.gsub('.html','.haml')}") contents = File.read(fn) response=Haml::Engine.new(contents).render elsif req[/\.js$/] and File.file?(fn="#{$http_dir}coffee#{req.gsub('.js','.coffee')}") type="application/javascript" contents = File.read(fn) begin response=CoffeeScript.compile contents rescue => e response="Coffee Compile error: #{e}" end elsif req[/^\/(.+)\.json$/] and File.file?(fn="#{$http_dir}json#{req.gsub('.json','.rb')}") req[/\/(.+).json$/] act=$1 #puts "act:#{act} args:#{args}" t=File.mtime(fn) if not prev_t[fn] or prev_t[fn]<t begin load_ok=load fn prev_t[fn]=t rescue Exception => e puts "**** RELOAD #{fn} failed: #{e}" pp e.backtrace response=[{act: :error, msg:"Error loading JSON",alert: "Load error #{e} in #{fn}"}].to_json type="text/json" status="404 Not Found" end end if type!="text/event-stream" and status=="200 OK" begin type,response=eval "json_#{act} req,args,0,0" #event handlers get called with zero session => init :) rescue => e puts "**** AJAX EXEC #{fn} failed: #{e}" pp e.backtrace response=[{act: :error, msg:"Error executing JSON",alert: "Syntax error '#{e}' in '#{fn}'"}].to_json type="text/json" end response=response.to_json end elsif req[/\.css$/] and File.file?(fnc="#{$http_dir}css#{req}") type="text/css" contents = File.read(fnc) response=contents else status="404 Not Found" response="Not Found: #{request[1]}" end client.print "HTTP/1.1 #{status}\r\n" + "Content-Type: #{type}\r\n" if type!="text/event-stream" client.print "Content-Length: #{response.bytesize}\r\n" client.print "Connection: close\r\n" client.print "\r\n" client.print response else client.print "Expires: -1\r\n" client.print "\r\n" begin my_session=client.peeraddr[1] if not @http_sessions[my_session] #puts "**************** new port #{my_session}" @http_sessions[my_session]={client_port:client.peeraddr[1],client_ip:client.peeraddr[2] , log_position:0 } end my_event=0 loop do begin type,response=eval "json_#{act} request,args,my_session,my_event" my_event+=1 rescue => e puts "**** AJAX EXEC #{fn} failed: #{e}" puts "#{e.backtrace[0..2]}" pp e.backtrace response=[{act: :error, msg:"Error executing JSON",alert: "Syntax error '#{e}' in '#{fn}'"}].to_json end if not response or response==[] or response=={} else client.print "retry: 1000\n" client.print "data: #{response.to_json}\n\n" end sleep 1 break if my_event>100 end rescue => e puts "stream #{client} died #{e}" pp e.backtrace end end client.close rescue Exception =>e puts "http thread died #{e}" pp e.backtrace client.print "Error #{e}" client.close end end end end end |