日常

ケ・セラ・セラ

redis pub sub がうまくいっていないので宿題

Heroku の websocket のサンプルを動かしてみようと思ってちょっといじってみたんですが、@redis.publish(CHANNEL, sanitize(event.data)) が失敗してるのか ws.on :close してしまう。そして subscribe もできず。みたいなところで時間切れなのでとりあえず放置した。 何がいけないのかまだ分かっていない。宿題。

require 'faye/websocket'
require 'thread'
require 'redis'
require 'json'
require 'erb'

module ChatDemo
  class ChatBackend
    KEEPALIVE_TIME = 15 # in seconds
    CHANNEL        = "chat-demo"

    def initialize(app)
      @app     = app
      @clients = []

#       uri = URI.parse(ENV["REDISCLOUD_URL"])
#       @redis = Redis.new(host: uri.host, port: uri.port, password: uri.password)
      @redis = Redis.new(host: "localhost", port: 6379)

#       Thread.new do
#         # redis_sub = Redis.new(host: uri.host, port: uri.port, password: uri.password)
#         redis_sub = Redis.new(host: "localhost", port: 6379, timeout: 0)
# 
#         redis_sub.subscribe(CHANNEL) do |on|
#           on.message do |channel, msg|
# #             @clients.each {|ws| ws.send(msg) }
#           end
#         end
#       end

    end

    def call(env)
      if Faye::WebSocket.websocket?(env)
        ws = Faye::WebSocket.new(env, nil, {ping: KEEPALIVE_TIME })

        ws.on :open do |event|
          p [:open, ws.object_id]
          @clients << ws
        end

        ws.on :message do |event|
          p [:message, event.data]
#           @redis.publish(CHANNEL, sanitize(event.data))
          @clients.each { |client| client.send sanitize(event.data) }
        end

        ws.on :close do |event|
          p [:close, ws.object_id, event.code, event.reason]
          @clients.delete(ws)
          ws = nil
        end

        # Return async Rack response
        ws.rack_response

      else
        @app.call(env)
      end
    end

    private
    def sanitize(message)
      json = JSON.parse(message)
      json.each {|key, value| json[key] = ERB::Util.html_escape(value) }
      JSON.generate(json)
    end
  end
end