Ruby和EventMachine-WebSockets - 它是如何异步的?

时间:2012-08-07 20:10:59

标签: ruby asynchronous websocket eventmachine

我正在使用WebSockets通过EventMachine在Ruby上构建服务器。

假设用户Carl要求购买汽车。

向CarManager请求id为“7”的汽车。 CarManager创建一个Car实例,Car从Mongo数据库加载自己(提供了id)。 Car“7”存储在CarManager中,就像缓存一样,只要卡尔或其他任何人继续使用或请求它。然后Car通过WebSocket发送,特别是给Carl。我把卡尔的WS存放在某处。

如果两个用户,比如Lenny和Carl,都在“确切”同时要求Car id“7”怎么办?将CarManager,因为它无法在任何一种情况下找到Car 7的缓存版本,从数据库中获取它并将其实例化,或者首先处理这两个WebSocket请求中的一个,然后第二个将使用缓存版本

WebSockets的整个异步事情让我有点困惑。感谢您对此有任何见解!

2 个答案:

答案 0 :(得分:0)

让我这样说吧:假设你已经扩展到两台服务器。你应该明白你对懒惰汽车创造的方法是不正确的。您不应该允许用户使用提供的ID创建,或者您应该使用一些外部互斥锁,例如CarManager中的“Car:7:loading”。或者,您可以将CarManager设置为透明代理,将作业提取到其上(并在那里面临相同的并发问题)。

答案 1 :(得分:0)

我会使用类似Mongoid的内容来隐藏大部分细节,以便当Carl的浏览器发送一个websocket onmessage请求时,例如{:command => 'get_car", :car_id => "7"}你的EM onmessage处理程序会看起来有点像

ws.onmessage do |msg|
  message = JSON.parse(msg)
  car = Cars.where(car_number: message[:car_id]).first
  ws.send(car.to_json)
end

显然你想要处理找不到汽车,或者消息形成不正确等情况,你可能想要自定义返回的JSON(例如添加.to_summary方法到Car模型)所以它只返回客户关心的汽车信息。

您不必担心首先出现哪个请求,或者即使它们都在mongoid同时处理,也会为您处理这些低级别的内容。