7164


初心者です。RoRでチャットを作っています。下記のコードで走らせても思ったように動きません。どこに問題がありますか？

ユーザーの新規のpostを1秒ごとに取得して、render_to_stringした後で送信しています。クライアント側では、それをpostが表示される"post-
list"にappendしています。しかし、ユーザーがpostを作成しても、作成は成功しますが、表示がされません。

**chats.coffee**

[code]

    $ ->
      chat_id = $("chat_id").text()
      eventSource = new EventSource(chat_id+"/stream")
      eventSource.addEventListener 'push', (event) ->
        post = event.data
        $('#post-list').append(post)
    
[/code]

**chats.controller.rb**

[code]

    include ActionController::Live
    def stream
      @chat = Chat.find(params[:id])
      response.headers['Content-Type'] = 'text/event-stream'
      start = Time.zone.now
      loop do
        Post.uncached do
          Post.where('created_at > ?', start).where('chat_id = ?', @chat.id).each do |post|
            html = render_to_string partial:'shared/_post.html.erb', object:post
            response.stream.write("event:push\n")
            response.stream.write("data:#{html}\n\n")
            start = post.created_at
          end
        end 
        sleep 1
      end
      rescue
      ensure
        response.stream.close
    end
    
[/code]

お願いします。


CC BY-SA 3.0
2015-02-26T12:59:26.813
7152
2015-02-26T22:17:23.190
2015-02-26T17:38:20.977
question
javascript ruby-on-rails coffeescript
ActionController::Liveとjavascriptがうまく働かない


`ActionController::Live`は使ったことがないのですが、「ActionController::Live render
render_to_string」というキーワードでネットを検索したところ、`render_to_string`がそのままでは使えないのでモンキーパッチを当てた、という記事がありました。

<http://blog.sorah.jp/2013/07/28/render_to_string-in-ac-live>

<http://diary.sorah.jp/2013/07/28/render-to-string-actioncontroller-live>

[code]

    # モンキーパッチのコード
    def render_to_string(*)
      orig_stream = response.stream
      super
    ensure
      if orig_stream
        response.instance_variable_set(:@stream, orig_stream)
      end
    end
    
[/code]

ただ、ちょっと情報が古いので最新のRailsではどうなっているのかよくわからないのと、以下のように「結局JS側はうまく動かない」という情報もあったりします。

<https://stackoverflow.com/questions/19858470/actioncontrollerlive-with-sse-
not-working-properly>

ですが、いずれにせよ「作成は成功しますが、表示がされません」だけだと回答する側も原因を予測しづらいです。  
なのでChrome
デベロッパーツールの「ネットワーク」タブやJavaScriptのデバッグ実行などを使って、正常な実行を妨げている箇所を絞り込んだ後に、その情報と一緒に質問を投げるのがベターだと思います。

デベロッパーツールに関する参考情報: <https://ja.stackoverflow.com/a/6898/85>

ちなみにコントローラーのコードで

[code]

    rescue
    ensure
      response.stream.close
    
[/code]

と書いていますが、`rescue`する場合は「発生が予想されるエラーのみ」に絞り込んでおいた方が良いです。

[code]

    # See http://tenderlovemaking.com/2012/07/30/is-it-live.html
    rescue IOError
      # When the client disconnects, we'll get an IOError on write
    ensure
      response.stream.close
    
[/code]

現状のコードだとあらゆるエラーを握りつぶしてしまうので、問題が起きていても気づけなくなります。


CC BY-SA 3.0
2015-02-26T22:06:41.810
7164
2015-02-26T22:17:23.190
2017-05-23T12:38:55.250
-1
85
7152
answer