shokai / ruby-socket.io-client-simple

A simple ruby client for node.js's socket.io. Supports only WebSocket.
https://rubygems.org/gems/socket.io-client-simple
MIT License
61 stars 36 forks source link

Cannot process web socket events while in the callback of another web socket event #12

Open tobalsgithub opened 9 years ago

tobalsgithub commented 9 years ago

We're implementing a realtime, bi-directional api using websockets, and trying to build a gem for our ruby customers.

Do to the nature of what we're sending, we have to implement an acknowledgement system in order to ensure the messages are reaching their destinations, and to allow for any errors to be returned. We also need to ensure that a message gets its response before any new messages are sent.

So we're trying to make this a synchronous call/response, despite the fact that these things happen asynchronously.

A very basic example of what we're trying is below. We have a function post that emits a post message to the server, waits for a post-response to be received, then returns.

When we call this function from outside any other event listener callbacks, everything works fine.

However, when we listen for a push message from the server, then call post, it never finishes. In other words, the post-response event is never received, despite the fact that it is sent from the server.

I've tried putting the listeners in a new thread, using EventMachine and Fibers for the listeners, using EventMachine and Fibers for the post method, but nothing has helped. Whenever we listen for a new event inside the listener for another event, the new listener is not called if the outside listener has not finished processing.

So the question is: is this expected and if so, is there a way around it?

@socket = SocketIO::Client::Simple.connect url

def post
  ready = false
  @socket.emit :post data
  @socket.on :'post-response' do |res|
    ready = true
    response = res
  end

  sleep 1 while !ready
  return response
end

# Call #1 succeeds just fine
puts post {}

@socket.on :push do |data|
  #Call #2 never finishes
  puts post {}
end

Happy to provide more details. I know this use case is a little strange.

tobalsgithub commented 9 years ago

It's certainly possible that the root of this lies in one of the included modules, but I haven't been able to pinpoint the issue yet, so starting here.